Added Abschreibungen

This commit is contained in:
2026-03-25 17:13:59 +01:00
parent f6c9875320
commit 42e0d7b35e
16 changed files with 13054 additions and 55 deletions

View File

@@ -1,5 +1,11 @@
<script setup>
import dayjs from "dayjs";
import {
DEPRECIATION_METHOD_ITEMS,
EXPENSE_BOOKING_MODE_ITEMS,
isDepreciationBookingMode,
normalizeExpenseBookingMode
} from "~/composables/useDepreciation"
// import {filter} from "vuedraggable/dist/vuedraggable.common.js"; // Scheint nicht genutzt zu werden, auskommentiert
defineShortcuts({
@@ -43,6 +49,7 @@ const setup = async () => {
if (itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
manualAllocationSum.value = calculateOpenSum.value
allocationDepreciationStartDate.value = dayjs(itemInfo.value?.date || new Date()).format("YYYY-MM-DD")
createddocuments.value = (await useEntities("createddocuments").select("*, statementallocations(*), customer(id,name)"))
const documents = createddocuments.value.filter(i => i.type === "invoices" || i.type === "advanceInvoices")
@@ -129,13 +136,56 @@ const selectAccount = (id) => {
const manualAllocationSum = ref(itemInfo.value.amount || 0)
const allocationDescription = ref("")
const allocationBookingMode = ref("expense")
const allocationDepreciationMonths = ref(36)
const allocationDepreciationStartDate = ref(dayjs().format("YYYY-MM-DD"))
const allocationDepreciationMethod = ref("linear")
const allocationDepreciationLabel = ref("")
const allocationDepreciationGroup = ref("")
const allocationResidualValue = ref(0)
const showMoreWithoutRecipe = ref(false)
const showMoreText = ref(false)
const isDepreciationAllocation = computed(() => isDepreciationBookingMode(allocationBookingMode.value))
const buildAllocationPayload = (payload) => {
const base = {
...payload,
bookingMode: normalizeExpenseBookingMode(allocationBookingMode.value)
}
if (!isDepreciationAllocation.value) {
return {
...base,
depreciationMonths: null,
depreciationStartDate: null,
depreciationLabel: null,
depreciationGroup: null
}
}
return {
...base,
depreciationMonths: Number(allocationDepreciationMonths.value || 0),
depreciationStartDate: allocationDepreciationStartDate.value || itemInfo.value?.date || null,
depreciationMethod: allocationDepreciationMethod.value,
depreciationLabel: allocationDepreciationLabel.value || allocationDescription.value || "Direkte Abschreibung",
depreciationGroup: allocationBookingMode.value === "depreciation_bundle" ? allocationDepreciationGroup.value || null : null,
residualValue: Number(allocationResidualValue.value || 0)
}
}
watch(allocationBookingMode, (value) => {
if (!isDepreciationBookingMode(value)) return
if (!allocationDepreciationStartDate.value) {
allocationDepreciationStartDate.value = dayjs(itemInfo.value?.date || new Date()).format("YYYY-MM-DD")
}
})
const saveAllocation = async (allocation) => {
const res = await useNuxtApp().$api("/api/banking/statements", {
method: "POST",
body: {data: allocation}
body: {data: buildAllocationPayload(allocation)}
})
if (res) {
@@ -144,6 +194,13 @@ const saveAllocation = async (allocation) => {
vendorAccountToSave.value = null
customerAccountToSave.value = null
ownAccountToSave.value = null
allocationBookingMode.value = "expense"
allocationDepreciationMonths.value = 36
allocationDepreciationStartDate.value = dayjs(itemInfo.value?.date || new Date()).format("YYYY-MM-DD")
allocationDepreciationMethod.value = "linear"
allocationDepreciationLabel.value = ""
allocationDepreciationGroup.value = ""
allocationResidualValue.value = 0
// allocationDescription.value = null // Optional: Beschreibung behalten für nächste Buchung?
}
}
@@ -420,6 +477,13 @@ const getAllocationIcon = (item) => {
return 'i-heroicons-question-mark-circle'
}
const getAllocationBookingModeLabel = (item) => {
const mode = normalizeExpenseBookingMode(item?.bookingMode)
if (mode === "depreciation_bundle") return "Sammelabschreibung"
if (mode === "depreciation_single") return "Einzelabschreibung"
return "Sofortaufwand"
}
setup()
</script>
@@ -526,6 +590,12 @@ setup()
{{ getAllocationLabel(item) }}
</div>
<div class="text-xs text-gray-500 mt-0.5" v-if="item.description">{{ item.description }}</div>
<div class="mt-1 flex flex-wrap gap-1" v-if="item.bookingMode && item.bookingMode !== 'expense'">
<UBadge size="xs" color="warning" variant="soft">{{ getAllocationBookingModeLabel(item) }}</UBadge>
<UBadge size="xs" color="neutral" variant="soft" v-if="item.depreciationGroup">{{ item.depreciationGroup }}</UBadge>
<UBadge size="xs" color="neutral" variant="soft" v-if="item.depreciationMonths">{{ item.depreciationMonths }} Monate</UBadge>
<UBadge size="xs" color="neutral" variant="soft" v-if="item.depreciationMethod">{{ item.depreciationMethod === 'degressive' ? 'Degressiv' : 'Linear' }}</UBadge>
</div>
<div class="flex gap-2 mt-1" v-if="item.createddocument || item.incominginvoice">
<UButton
v-if="item.createddocument"
@@ -618,6 +688,56 @@ setup()
</div>
</div>
<div class="mt-4 grid grid-cols-1 md:grid-cols-3 gap-3">
<UFormField label="Aufwandsart" size="sm">
<USelectMenu
v-model="allocationBookingMode"
:items="EXPENSE_BOOKING_MODE_ITEMS"
value-key="value"
label-key="label"
/>
</UFormField>
<UFormField label="Abschreibungsdauer (Monate)" size="sm" v-if="isDepreciationAllocation">
<UInput v-model="allocationDepreciationMonths" type="number" min="1" step="1" />
</UFormField>
<UFormField label="Methode" size="sm" v-if="isDepreciationAllocation">
<USelectMenu
v-model="allocationDepreciationMethod"
:items="DEPRECIATION_METHOD_ITEMS"
value-key="value"
label-key="label"
/>
</UFormField>
</div>
<div class="mt-3 grid grid-cols-1 md:grid-cols-3 gap-3" v-if="isDepreciationAllocation">
<UFormField label="Start Abschreibung" size="sm">
<UInput v-model="allocationDepreciationStartDate" type="date" />
</UFormField>
<UFormField label="Restwert" size="sm">
<UInput v-model="allocationResidualValue" type="number" min="0" step="0.01" />
</UFormField>
</div>
<div class="mt-3 grid grid-cols-1 md:grid-cols-2 gap-3" v-if="isDepreciationAllocation">
<UFormField v-if="allocationBookingMode === 'depreciation_bundle'" label="Sammelposten" size="sm">
<UInput v-model="allocationDepreciationGroup" placeholder="z. B. Betriebsausstattung 2026" />
</UFormField>
<UFormField v-else label="Bezeichnung Abschreibung" size="sm">
<UInput v-model="allocationDepreciationLabel" placeholder="z. B. Werkzeugkoffer" />
</UFormField>
<UAlert
color="warning"
variant="soft"
icon="i-heroicons-calendar-days"
title="BWA bucht nur die Abschreibungsrate"
description="Die Auszahlung erscheint dann nicht sofort als Aufwand, sondern periodisiert über die gewählte Laufzeit."
/>
</div>
<div v-if="showMoreWithoutRecipe"
class="mt-4 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 grid grid-cols-1 md:grid-cols-3 gap-3">
<USelectMenu :items="ownaccounts" value-key="id" label-key="name" v-model="ownAccountToSave"