Rechnungsentwürfe optional wie Rechnungen verwenden
This commit is contained in:
@@ -17,6 +17,16 @@ const dismissedRecurringKeys = computed(() => {
|
||||
return tempStore.settings?.liquidityForecast?.dismissedRecurringKeys || []
|
||||
})
|
||||
|
||||
const includeDraftsAsInvoices = computed({
|
||||
get: () => Boolean(tempStore.settings?.liquidityForecast?.includeDraftsAsInvoices),
|
||||
set: (value) => {
|
||||
tempStore.modifySettings("liquidityForecast", {
|
||||
...(tempStore.settings?.liquidityForecast || {}),
|
||||
includeDraftsAsInvoices: Boolean(value)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const storeDismissedRecurringKeys = (keys) => {
|
||||
tempStore.modifySettings("liquidityForecast", {
|
||||
...(tempStore.settings?.liquidityForecast || {}),
|
||||
@@ -60,13 +70,16 @@ const readForecastCache = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const applyDismissedRecurring = (value) => {
|
||||
const applyForecastAdjustments = (value) => {
|
||||
if (!value) return null
|
||||
|
||||
const dismissed = new Set(dismissedRecurringKeys.value)
|
||||
const events = (value.events || []).filter((event) => {
|
||||
const baseEvents = (value.events || []).filter((event) => {
|
||||
return event.source !== "recurring_bankstatement" || !event.recurringKey || !dismissed.has(event.recurringKey)
|
||||
})
|
||||
const events = includeDraftsAsInvoices.value
|
||||
? [...baseEvents, ...(value.draftEvents || [])]
|
||||
: baseEvents
|
||||
const recurring = (value.recurring || []).filter((item) => !item.key || !dismissed.has(item.key))
|
||||
const eventsByDate = new Map()
|
||||
|
||||
@@ -109,7 +122,7 @@ const applyDismissedRecurring = (value) => {
|
||||
|
||||
const setRawForecast = (value) => {
|
||||
rawForecast.value = value
|
||||
forecast.value = applyDismissedRecurring(value)
|
||||
forecast.value = applyForecastAdjustments(value)
|
||||
}
|
||||
|
||||
const loadForecastFromCache = () => {
|
||||
@@ -170,7 +183,7 @@ const dismissRecurringKey = async (key) => {
|
||||
if (!key) return
|
||||
|
||||
storeDismissedRecurringKeys([...dismissedRecurringKeys.value, key])
|
||||
forecast.value = applyDismissedRecurring(rawForecast.value)
|
||||
forecast.value = applyForecastAdjustments(rawForecast.value)
|
||||
toast.add({
|
||||
title: "Bankbewegung abgeschlossen",
|
||||
description: "Das erkannte Muster wird aus der Liquiditätsprognose entfernt.",
|
||||
@@ -180,7 +193,7 @@ const dismissRecurringKey = async (key) => {
|
||||
|
||||
const restoreDismissedRecurring = () => {
|
||||
storeDismissedRecurringKeys([])
|
||||
forecast.value = applyDismissedRecurring(rawForecast.value)
|
||||
forecast.value = applyForecastAdjustments(rawForecast.value)
|
||||
toast.add({
|
||||
title: "Bankbewegungen wiederhergestellt",
|
||||
description: "Ausgeblendete Muster werden wieder in der Prognose berücksichtigt.",
|
||||
@@ -248,6 +261,7 @@ const groupedEventSummary = computed(() => {
|
||||
open_createddocument: { label: sourceLabels.open_createddocument, amount: 0, count: 0 },
|
||||
open_incominginvoice: { label: sourceLabels.open_incominginvoice, amount: 0, count: 0 },
|
||||
recurring_bankstatement: { label: sourceLabels.recurring_bankstatement, amount: 0, count: 0 },
|
||||
draft_createddocument: { label: "Rechnungsentwürfe als Rechnungen", amount: 0, count: 0 },
|
||||
tax_settlement: { label: sourceLabels.tax_settlement, amount: 0, count: 0 }
|
||||
}
|
||||
|
||||
@@ -275,6 +289,8 @@ const topExpenseDrivers = computed(() => {
|
||||
})
|
||||
|
||||
const draftIncomeDrivers = computed(() => {
|
||||
if (includeDraftsAsInvoices.value) return []
|
||||
|
||||
return [...(forecast.value?.draftEvents || [])]
|
||||
.sort((a, b) => Number(b.amount || 0) - Number(a.amount || 0))
|
||||
.slice(0, 12)
|
||||
@@ -323,7 +339,11 @@ const riskTone = computed(() => {
|
||||
})
|
||||
|
||||
watch(dismissedRecurringKeys, () => {
|
||||
forecast.value = applyDismissedRecurring(rawForecast.value)
|
||||
forecast.value = applyForecastAdjustments(rawForecast.value)
|
||||
})
|
||||
|
||||
watch(includeDraftsAsInvoices, () => {
|
||||
forecast.value = applyForecastAdjustments(rawForecast.value)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
@@ -342,6 +362,11 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<div class="flex items-center gap-2 rounded-lg border border-gray-200 px-3 py-2 text-sm dark:border-gray-800">
|
||||
<USwitch v-model="includeDraftsAsInvoices" />
|
||||
<span class="text-gray-600 dark:text-gray-300">Entwürfe wie Rechnungen verwenden</span>
|
||||
</div>
|
||||
|
||||
<UButton
|
||||
v-if="dismissedRecurringKeys.length"
|
||||
icon="i-heroicons-eye"
|
||||
@@ -452,7 +477,11 @@ onMounted(() => {
|
||||
<span class="text-sm text-gray-500">Geplante Einzahlungen</span>
|
||||
<span class="font-semibold text-primary-600">+ {{ useCurrency(forecast.totalIncome) }}</span>
|
||||
</div>
|
||||
<div v-if="forecast.draftIncome" class="flex items-center justify-between gap-3">
|
||||
<div v-if="includeDraftsAsInvoices" class="flex items-center justify-between gap-3">
|
||||
<span class="text-sm text-gray-500">Davon aus Entwürfen</span>
|
||||
<span class="font-semibold text-primary-600">+ {{ useCurrency(rawForecast?.draftIncome || 0) }}</span>
|
||||
</div>
|
||||
<div v-else-if="forecast.draftIncome" class="flex items-center justify-between gap-3">
|
||||
<span class="text-sm text-gray-500">Rechnungsentwürfe optional</span>
|
||||
<span class="font-semibold text-gray-500">(+ {{ useCurrency(forecast.draftIncome) }})</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user