Belege und Bankmuster in Liquiditätsprognose verwalten
Ermöglicht das Öffnen von Belegen aus der Liquiditätsprognose und das Abschließen erkannter regelmäßiger Bankbewegungen, die anschließend aus der Prognose herausgerechnet werden.
This commit is contained in:
@@ -97,8 +97,14 @@ export const useFunctions = () => {
|
||||
return await useNuxtApp().$api(`/api/banking/statements/${statementId}/suggestions`)
|
||||
}
|
||||
|
||||
const useLiquidityForecast = async () => {
|
||||
return await useNuxtApp().$api("/api/functions/liquidity-forecast")
|
||||
const useLiquidityForecast = async (ignoredRecurringKeys = []) => {
|
||||
const query = new URLSearchParams()
|
||||
if (ignoredRecurringKeys.length) {
|
||||
query.set("ignoredRecurringKeys", ignoredRecurringKeys.join(","))
|
||||
}
|
||||
|
||||
const suffix = query.toString() ? `?${query.toString()}` : ""
|
||||
return await useNuxtApp().$api(`/api/functions/liquidity-forecast${suffix}`)
|
||||
}
|
||||
|
||||
return {getWorkingTimesEvaluationData, useNextNumber, useBankingGenerateLink, useZipCheck, useBankingCheckInstitutions, useBankingListRequisitions, useBankingResolveIban, useBankingStatementSuggestions, useLiquidityForecast, useCreatePDF}
|
||||
|
||||
@@ -3,11 +3,23 @@ import dayjs from "dayjs"
|
||||
import { Line } from "vue-chartjs"
|
||||
|
||||
const toast = useToast()
|
||||
const tempStore = useTempStore()
|
||||
|
||||
const forecast = ref(null)
|
||||
const loading = ref(true)
|
||||
const error = ref("")
|
||||
|
||||
const dismissedRecurringKeys = computed(() => {
|
||||
return tempStore.settings?.liquidityForecast?.dismissedRecurringKeys || []
|
||||
})
|
||||
|
||||
const storeDismissedRecurringKeys = (keys) => {
|
||||
tempStore.modifySettings("liquidityForecast", {
|
||||
...(tempStore.settings?.liquidityForecast || {}),
|
||||
dismissedRecurringKeys: [...new Set(keys)].filter(Boolean)
|
||||
})
|
||||
}
|
||||
|
||||
const sourceLabels = {
|
||||
open_createddocument: "Offene Ausgangsrechnung",
|
||||
open_incominginvoice: "Offener Eingangsbeleg",
|
||||
@@ -26,7 +38,7 @@ const loadForecast = async () => {
|
||||
error.value = ""
|
||||
|
||||
try {
|
||||
forecast.value = await useFunctions().useLiquidityForecast()
|
||||
forecast.value = await useFunctions().useLiquidityForecast(dismissedRecurringKeys.value)
|
||||
} catch (err) {
|
||||
error.value = "Die Liquiditätsprognose konnte nicht geladen werden."
|
||||
toast.add({
|
||||
@@ -41,6 +53,39 @@ const loadForecast = async () => {
|
||||
|
||||
const formatDate = (value) => dayjs(value).format("DD.MM.YYYY")
|
||||
|
||||
const getEventRoute = (event) => {
|
||||
if (event.source === "open_createddocument" && event.sourceId) return `/createDocument/show/${event.sourceId}`
|
||||
if (event.source === "open_incominginvoice" && event.sourceId) return `/incomingInvoices/show/${event.sourceId}`
|
||||
return null
|
||||
}
|
||||
|
||||
const openEvent = (event) => {
|
||||
const route = getEventRoute(event)
|
||||
if (route) navigateTo(route)
|
||||
}
|
||||
|
||||
const dismissRecurringKey = async (key) => {
|
||||
if (!key) return
|
||||
|
||||
storeDismissedRecurringKeys([...dismissedRecurringKeys.value, key])
|
||||
toast.add({
|
||||
title: "Bankbewegung abgeschlossen",
|
||||
description: "Das erkannte Muster wird aus der Liquiditätsprognose entfernt.",
|
||||
color: "success"
|
||||
})
|
||||
await loadForecast()
|
||||
}
|
||||
|
||||
const restoreDismissedRecurring = async () => {
|
||||
storeDismissedRecurringKeys([])
|
||||
toast.add({
|
||||
title: "Bankbewegungen wiederhergestellt",
|
||||
description: "Ausgeblendete Muster werden wieder in der Prognose berücksichtigt.",
|
||||
color: "success"
|
||||
})
|
||||
await loadForecast()
|
||||
}
|
||||
|
||||
const chartData = computed(() => ({
|
||||
labels: (forecast.value?.points || []).map((point) => dayjs(point.date).format("DD.MM.")),
|
||||
datasets: [
|
||||
@@ -112,6 +157,14 @@ loadForecast()
|
||||
>
|
||||
Aktualisieren
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="dismissedRecurringKeys.length"
|
||||
icon="i-heroicons-eye"
|
||||
variant="ghost"
|
||||
@click="restoreDismissedRecurring"
|
||||
>
|
||||
Ausgeblendete wiederherstellen
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
@@ -203,7 +256,7 @@ loadForecast()
|
||||
<div
|
||||
v-for="event in upcomingEvents"
|
||||
:key="`${event.source}-${event.sourceId || event.label}-${event.date}-${event.amount}`"
|
||||
class="grid gap-3 py-3 sm:grid-cols-[110px_minmax(0,1fr)_auto]"
|
||||
class="grid gap-3 py-3 sm:grid-cols-[110px_minmax(0,1fr)_auto_auto]"
|
||||
>
|
||||
<span class="text-sm text-gray-500">{{ formatDate(event.date) }}</span>
|
||||
<div class="min-w-0">
|
||||
@@ -216,6 +269,27 @@ loadForecast()
|
||||
>
|
||||
{{ useCurrency(event.amount) }}
|
||||
</span>
|
||||
<div class="flex justify-end gap-1">
|
||||
<UButton
|
||||
v-if="getEventRoute(event)"
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
icon="i-heroicons-arrow-top-right-on-square"
|
||||
@click="openEvent(event)"
|
||||
>
|
||||
Öffnen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="event.source === 'recurring_bankstatement' && event.recurringKey"
|
||||
size="xs"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
icon="i-heroicons-check-circle"
|
||||
@click="dismissRecurringKey(event.recurringKey)"
|
||||
>
|
||||
Abschließen
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -250,9 +324,20 @@ loadForecast()
|
||||
{{ useCurrency(item.amount) }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-gray-500">
|
||||
Sicherheit {{ Math.round(item.confidence * 100) }}% · {{ item.evidence }}
|
||||
</p>
|
||||
<div class="mt-2 flex flex-wrap items-center justify-between gap-2">
|
||||
<p class="text-xs text-gray-500">
|
||||
Sicherheit {{ Math.round(item.confidence * 100) }}% · {{ item.evidence }}
|
||||
</p>
|
||||
<UButton
|
||||
size="xs"
|
||||
color="gray"
|
||||
variant="soft"
|
||||
icon="i-heroicons-check-circle"
|
||||
@click="dismissRecurringKey(item.key)"
|
||||
>
|
||||
Als abgeschlossen entfernen
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user