diff --git a/components/LabelPrintModal.vue b/components/LabelPrintModal.vue new file mode 100644 index 0000000..e660a6d --- /dev/null +++ b/components/LabelPrintModal.vue @@ -0,0 +1,130 @@ + + + diff --git a/components/LabelPrinterButton.vue b/components/LabelPrinterButton.vue new file mode 100644 index 0000000..2a29fee --- /dev/null +++ b/components/LabelPrinterButton.vue @@ -0,0 +1,53 @@ + + + + + \ No newline at end of file diff --git a/components/MainNav.vue b/components/MainNav.vue index dc00730..0307b41 100644 --- a/components/MainNav.vue +++ b/components/MainNav.vue @@ -339,8 +339,7 @@ const links = computed(() => { },{ label: "Export", to: "/export", - icon: "i-heroicons-clipboard-document-list", - disabled: true + icon: "i-heroicons-clipboard-document-list" } ] } diff --git a/components/PageLeaveGuard.vue b/components/PageLeaveGuard.vue new file mode 100644 index 0000000..af9a563 --- /dev/null +++ b/components/PageLeaveGuard.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/components/PublicDynamicForm.vue b/components/PublicDynamicForm.vue new file mode 100644 index 0000000..a3cdd07 --- /dev/null +++ b/components/PublicDynamicForm.vue @@ -0,0 +1,201 @@ + + + \ No newline at end of file diff --git a/components/displayBankaccounts.vue b/components/displayBankaccounts.vue index cb4ac08..07978a7 100644 --- a/components/displayBankaccounts.vue +++ b/components/displayBankaccounts.vue @@ -37,7 +37,7 @@ const calculateOpenSum = (statement) => { {{ account.name }}: - {{dayjs(account.synced_at).format("DD.MM.YY HH:mm")}} + {{dayjs(account.syncedAt).format("DD.MM.YY HH:mm")}} {{useCurrency(account.balance)}} diff --git a/components/nimbot.vue b/components/nimbot.vue new file mode 100644 index 0000000..7ceb36a --- /dev/null +++ b/components/nimbot.vue @@ -0,0 +1,60 @@ + + + diff --git a/layouts/default.vue b/layouts/default.vue index e994ab7..4993db6 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -6,6 +6,7 @@ import dayjs from "dayjs"; import {useCapacitor} from "../composables/useCapacitor.js"; import GlobalMessages from "~/components/GlobalMessages.vue"; import TenantDropdown from "~/components/TenantDropdown.vue"; +import LabelPrinterButton from "~/components/LabelPrinterButton.vue"; const dataStore = useDataStore() const colorMode = useColorMode() @@ -14,6 +15,7 @@ const router = useRouter() const route = useRoute() const auth = useAuthStore() +const labelPrinter = useLabelPrinterStore() const month = dayjs().format("MM") @@ -240,13 +242,16 @@ const footerLinks = [ diff --git a/pages/accounts/index.vue b/pages/accounts/index.vue index 3472214..1593e1f 100644 --- a/pages/accounts/index.vue +++ b/pages/accounts/index.vue @@ -26,13 +26,13 @@ const setupPage = async () => { incominginvoices.value = (await useEntities("incominginvoices").select("*, vendor(*)")) items.value = await Promise.all(items.value.map(async (i) => { - let renderedAllocationsTemp = await renderedAllocations(i.id) - let saldo = getSaldo(renderedAllocationsTemp) + // let renderedAllocationsTemp = await renderedAllocations(i.id) + // let saldo = getSaldo(renderedAllocationsTemp) return { ...i, - saldo: saldo, - allocations: renderedAllocationsTemp.length, + // saldo: saldo, + // allocations: renderedAllocationsTemp.length, } })) @@ -103,13 +103,13 @@ const templateColumns = [ },{ key: "label", label: "Name" - },{ + },/*{ key: "allocations", label: "Buchungen" },{ key: "saldo", label: "Saldo" - }, { + },*/ { key: "description", label: "Beschreibung" }, @@ -166,7 +166,7 @@ setupPage() - + --> - import dayjs from "dayjs"; +// Zugriff auf $api und Toast Notification +const { $api } = useNuxtApp() +const toast = useToast() + defineShortcuts({ '/': () => { - //console.log(searchinput) - //searchinput.value.focus() document.getElementById("searchinput").focus() } }) @@ -16,10 +17,43 @@ const route = useRoute() const bankstatements = ref([]) const bankaccounts = ref([]) +const filterAccount = ref([]) + +// Status für den Lade-Button +const isSyncing = ref(false) const setupPage = async () => { bankstatements.value = (await useEntities("bankstatements").select("*, statementallocations(*)", "date", false)) bankaccounts.value = await useEntities("bankaccounts").select() + if(bankaccounts.value.length > 0) filterAccount.value = bankaccounts.value +} + +// Funktion für den Bankabruf +const syncBankStatements = async () => { + isSyncing.value = true + try { + await $api('/api/functions/services/bankstatementsync', { method: 'POST' }) + + toast.add({ + title: 'Erfolg', + description: 'Bankdaten wurden erfolgreich synchronisiert.', + icon: 'i-heroicons-check-circle', + color: 'green' + }) + + // Wichtig: Daten neu laden, damit die neuen Buchungen direkt sichtbar sind + await setupPage() + } catch (error) { + console.error(error) + toast.add({ + title: 'Fehler', + description: 'Beim Abrufen der Bankdaten ist ein Fehler aufgetreten.', + icon: 'i-heroicons-exclamation-circle', + color: 'red' + }) + } finally { + isSyncing.value = false + } } const templateColumns = [ @@ -58,7 +92,6 @@ const clearSearchString = () => { searchString.value = '' } -const filterAccount = ref(bankaccounts.value || []) const displayCurrency = (value, currency = "€") => { return `${Number(value).toFixed(2).replace(".",",")} ${currency}` @@ -98,9 +131,6 @@ const filteredRows = computed(() => { } } - - - return useSearch(searchString.value, temp.filter(i => filterAccount.value.find(x => x.id === i.account))) }) @@ -110,6 +140,17 @@ setupPage() + + + + + @@ -21,20 +38,9 @@ + + +
+

+ + Laufende Ausführungen +

+
+ +
+
+

Start: {{ dayjs(exec.createdAt).format('DD.MM.YYYY HH:mm') }}

+
+ Läuft +
+ +
+ {{exec.summary}} +
+ +
+ +
+
+
+
+ + + @@ -67,23 +119,6 @@ {{row.customer ? row.customer.name : ""}} - @@ -98,27 +133,248 @@ Monatlich Quartalsweise + + + + + +
+ + + + + + +
+ + +
+ + + +
+
+ +
+ + + + + + +
+ +
+ {{ selectedExecutionRows.length }} Vorlage(n) ausgewählt. +
+
+ + +
+
+ + + + + +
+
+ +
+ +
+ Keine abgeschlossenen Ausführungen gefunden. +
+ +
+
+ {{ dayjs(exec.createdAt).format('DD.MM.YYYY HH:mm') }} + + {{ getStatusLabel(exec.status) }} + +
+
+
+ + {{exec.summary}} +
+
+
+
+
+
+ - - \ No newline at end of file + \ No newline at end of file diff --git a/pages/export/create/sepa.vue b/pages/export/create/sepa.vue new file mode 100644 index 0000000..9e17a7a --- /dev/null +++ b/pages/export/create/sepa.vue @@ -0,0 +1,47 @@ + + + + + \ No newline at end of file diff --git a/pages/incomingInvoices/[mode]/[id].vue b/pages/incomingInvoices/[mode]/[id].vue index 319fc26..ed07dbf 100644 --- a/pages/incomingInvoices/[mode]/[id].vue +++ b/pages/incomingInvoices/[mode]/[id].vue @@ -43,6 +43,10 @@ const setup = async () => { accounts.value = await useEntities("accounts").selectSpecial() itemInfo.value = await useEntities("incominginvoices").selectSingle(route.params.id, "*, files(*)") + + //TODO: Dirty Fix + itemInfo.value.vendor = itemInfo.value.vendor?.id + await loadFile(itemInfo.value.files[itemInfo.value.files.length-1].id) if(itemInfo.value.date && !itemInfo.value.dueDate) itemInfo.value.dueDate = itemInfo.value.date @@ -412,7 +416,7 @@ const findIncomingInvoiceErrors = computed(() => { value-attribute="id" searchable :disabled="mode === 'show'" - :search-attributes="['label']" + :search-attributes="['label','number']" searchable-placeholder="Suche..." v-model="item.account" :color="(item.account && accounts.find(i => i.id === item.account)) ? 'primary' : 'rose'" @@ -420,6 +424,9 @@ const findIncomingInvoiceErrors = computed(() => { +
@@ -575,6 +582,7 @@ const findIncomingInvoiceErrors = computed(() => { + diff --git a/pages/incomingInvoices/index.vue b/pages/incomingInvoices/index.vue index 8d12d6e..52e884f 100644 --- a/pages/incomingInvoices/index.vue +++ b/pages/incomingInvoices/index.vue @@ -2,6 +2,9 @@ import dayjs from "dayjs" import {useSum} from "~/composables/useSum.js"; +// Zugriff auf API und Toast +const { $api } = useNuxtApp() +const toast = useToast() defineShortcuts({ '/': () => { @@ -47,6 +50,9 @@ const sort = ref({ direction: 'desc' }) +// Status für den Button +const isPreparing = ref(false) + const type = "incominginvoices" const dataType = dataStore.dataTypes[type] @@ -54,6 +60,34 @@ const setupPage = async () => { items.value = await useEntities(type).select("*, vendor(id,name), statementallocations(id,amount)",sort.value.column,sort.value.direction === "asc") } +// Funktion zum Vorbereiten der Belege +const prepareInvoices = async () => { + isPreparing.value = true + try { + await $api('/api/functions/services/prepareincominginvoices', { method: 'POST' }) + + toast.add({ + title: 'Erfolg', + description: 'Eingangsbelege wurden vorbereitet.', + icon: 'i-heroicons-check-circle', + color: 'green' + }) + + // Liste neu laden + await setupPage() + } catch (error) { + console.error(error) + toast.add({ + title: 'Fehler', + description: 'Beim Vorbereiten der Belege ist ein Fehler aufgetreten.', + icon: 'i-heroicons-exclamation-circle', + color: 'red' + }) + } finally { + isPreparing.value = false + } +} + setupPage() const selectedColumns = ref(tempStore.columns[type] ? tempStore.columns[type] : dataType.templateColumns.filter(i => !i.disabledInTable)) @@ -128,6 +162,17 @@ const selectIncomingInvoice = (invoice) => {