Kassenbücher werden nun zuerst tabellarisch angezeigt. Das Erstellen einer Barkasse erfolgt über ein Modal und einzelne Kassenbücher öffnen sich über eine Detailseite.
166 lines
4.8 KiB
Vue
166 lines
4.8 KiB
Vue
<script setup>
|
|
const toast = useToast()
|
|
const router = useRouter()
|
|
const tempStore = useTempStore()
|
|
|
|
const loading = ref(true)
|
|
const savingCashbook = ref(false)
|
|
const createCashbookModalOpen = ref(false)
|
|
const cashbooks = ref([])
|
|
const searchString = ref(tempStore.searchStrings["cashbooks"] || "")
|
|
|
|
const newCashbook = reactive({
|
|
name: "",
|
|
datevNumber: "1000",
|
|
openingBalance: 0
|
|
})
|
|
|
|
const displayCurrency = (value) => `${Number(value || 0).toFixed(2).replace(".", ",")} €`
|
|
|
|
const templateColumns = [
|
|
{
|
|
key: "name",
|
|
label: "Bezeichnung"
|
|
},
|
|
{
|
|
key: "datevNumber",
|
|
label: "Kontennummer"
|
|
},
|
|
{
|
|
key: "balance",
|
|
label: "Anfangsbestand"
|
|
},
|
|
{
|
|
key: "syncedAt",
|
|
label: "Erstellt"
|
|
}
|
|
]
|
|
|
|
const filteredRows = computed(() => useSearch(searchString.value, cashbooks.value))
|
|
|
|
const clearSearchString = () => {
|
|
tempStore.clearSearchString("cashbooks")
|
|
searchString.value = ""
|
|
}
|
|
|
|
const loadCashbooks = async () => {
|
|
loading.value = true
|
|
cashbooks.value = await useNuxtApp().$api("/api/banking/cashbooks")
|
|
loading.value = false
|
|
}
|
|
|
|
const resetCreateForm = () => {
|
|
newCashbook.name = ""
|
|
newCashbook.datevNumber = "1000"
|
|
newCashbook.openingBalance = 0
|
|
}
|
|
|
|
const createCashbook = async () => {
|
|
if (!newCashbook.name || !newCashbook.datevNumber) {
|
|
toast.add({ title: "Bitte Bezeichnung und Kontennummer ausfüllen.", color: "warning" })
|
|
return
|
|
}
|
|
|
|
savingCashbook.value = true
|
|
try {
|
|
const created = await useNuxtApp().$api("/api/banking/cashbooks", {
|
|
method: "POST",
|
|
body: {
|
|
name: newCashbook.name,
|
|
datevNumber: newCashbook.datevNumber,
|
|
openingBalance: Number(newCashbook.openingBalance || 0)
|
|
}
|
|
})
|
|
toast.add({ title: "Barkasse erstellt." })
|
|
createCashbookModalOpen.value = false
|
|
resetCreateForm()
|
|
await loadCashbooks()
|
|
router.push(`/accounting/cashbooks/${created.id}`)
|
|
} finally {
|
|
savingCashbook.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(loadCashbooks)
|
|
</script>
|
|
|
|
<template>
|
|
<UDashboardPanelContent>
|
|
<UDashboardNavbar title="Kassenbücher" :badge="filteredRows.length">
|
|
<template #right>
|
|
<UInput
|
|
id="searchinput"
|
|
v-model="searchString"
|
|
icon="i-heroicons-magnifying-glass"
|
|
autocomplete="off"
|
|
placeholder="Suche..."
|
|
class="hidden lg:block"
|
|
@keydown.esc="$event.target.blur()"
|
|
@change="tempStore.modifySearchString('cashbooks', searchString)"
|
|
/>
|
|
<UButton
|
|
v-if="searchString.length > 0"
|
|
icon="i-heroicons-x-mark"
|
|
variant="outline"
|
|
color="error"
|
|
@click="clearSearchString"
|
|
/>
|
|
<UButton icon="i-heroicons-plus" @click="createCashbookModalOpen = true">
|
|
Barkasse
|
|
</UButton>
|
|
</template>
|
|
</UDashboardNavbar>
|
|
|
|
<UTable
|
|
:data="filteredRows"
|
|
:columns="normalizeTableColumns(templateColumns)"
|
|
:loading="loading"
|
|
class="w-full"
|
|
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
|
:on-select="(row) => router.push(`/accounting/cashbooks/${row.original?.id || row.id}`)"
|
|
:empty="{ icon: 'i-heroicons-banknotes', label: 'Keine Kassenbücher angelegt' }"
|
|
>
|
|
<template #datevNumber-cell="{ row }">
|
|
<span class="font-mono">{{ row.original.datevNumber }}</span>
|
|
</template>
|
|
<template #balance-cell="{ row }">
|
|
{{ displayCurrency(row.original.balance) }}
|
|
</template>
|
|
<template #syncedAt-cell="{ row }">
|
|
{{ row.original.createdAt ? new Date(row.original.createdAt).toLocaleDateString("de-DE") : "-" }}
|
|
</template>
|
|
</UTable>
|
|
|
|
<UModal v-model:open="createCashbookModalOpen">
|
|
<template #content>
|
|
<UCard>
|
|
<template #header>
|
|
<div class="text-lg font-semibold">Barkasse anlegen</div>
|
|
</template>
|
|
|
|
<UForm :state="newCashbook" class="space-y-4" @submit.prevent="createCashbook">
|
|
<UFormField label="Bezeichnung">
|
|
<UInput v-model="newCashbook.name" placeholder="z. B. Hauptkasse" />
|
|
</UFormField>
|
|
<UFormField label="Kontennummer">
|
|
<UInput v-model="newCashbook.datevNumber" placeholder="1000" />
|
|
</UFormField>
|
|
<UFormField label="Anfangsbestand">
|
|
<UInput v-model="newCashbook.openingBalance" type="number" step="0.01" />
|
|
</UFormField>
|
|
|
|
<div class="flex justify-end gap-3 pt-2">
|
|
<UButton color="gray" variant="soft" @click="createCashbookModalOpen = false">
|
|
Abbrechen
|
|
</UButton>
|
|
<UButton type="submit" color="primary" :loading="savingCashbook">
|
|
Barkasse anlegen
|
|
</UButton>
|
|
</div>
|
|
</UForm>
|
|
</UCard>
|
|
</template>
|
|
</UModal>
|
|
</UDashboardPanelContent>
|
|
</template>
|