Ausgangsbeleg-Tabs schneller rendern
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-frontend (push) Successful in 1m26s
Build and Push Docker Images / build-central-services-admin (push) Successful in 31s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 43s
Build and Push Docker Images / build-frontend (push) Successful in 1m26s
Build and Push Docker Images / build-central-services-admin (push) Successful in 31s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 22s
Build and Push Docker Images / build-docs (push) Successful in 22s
This commit is contained in:
@@ -57,12 +57,14 @@
|
||||
</UBadge>
|
||||
</template>
|
||||
<template #content="{item}">
|
||||
<div style="height: 80vh; overflow-y: scroll">
|
||||
<div class="flex h-[80vh] flex-col">
|
||||
<div class="min-h-0 flex-1 overflow-y-auto">
|
||||
<UTable
|
||||
:columns="normalizeTableColumns(getColumnsForTab(item.key))"
|
||||
:data="getRowsForTab(item.key)"
|
||||
:data="getVisibleRowsForTab(item.key)"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
class="w-full"
|
||||
:watch-options="{ deep: false }"
|
||||
:on-select="selectItem"
|
||||
>
|
||||
<template #type-cell="{row}">
|
||||
@@ -118,19 +120,19 @@
|
||||
<template #paid-cell="{row}">
|
||||
<div
|
||||
v-if="(row.original.type === 'invoices' ||row.original.type === 'advanceInvoices') && row.original.state === 'Gebucht' && !hasCancellationInvoice(row.original)">
|
||||
<span v-if="useSum().getIsPaid(row.original,items)" class="text-primary-500">Bezahlt</span>
|
||||
<span v-if="isPaid(row.original)" class="text-primary-500">Bezahlt</span>
|
||||
<span v-else class="text-rose-600">Offen</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #amount-cell="{row}">
|
||||
<span v-if="!deliveryNoteLikeDocumentTypes.includes(row.original.type)">{{ displayCurrency(useSum().getCreatedDocumentSum(row.original, items)) }}</span>
|
||||
<span v-if="!deliveryNoteLikeDocumentTypes.includes(row.original.type)">{{ displayCurrency(getDocumentAmount(row.original)) }}</span>
|
||||
</template>
|
||||
|
||||
<template #amountOpen-cell="{row}">
|
||||
<span
|
||||
v-if="!['cancellationInvoices','confirmationOrders', ...quoteLikeDocumentTypes, ...deliveryNoteLikeDocumentTypes].includes(row.original.type) && row.original.state !== 'Entwurf' && !hasCancellationInvoice(row.original) && !useSum().getIsPaid(row.original,items) ">
|
||||
{{ displayCurrency(useSum().getCreatedDocumentOpenAmount(row.original, items)) }}
|
||||
v-if="!['cancellationInvoices','confirmationOrders', ...quoteLikeDocumentTypes, ...deliveryNoteLikeDocumentTypes].includes(row.original.type) && row.original.state !== 'Entwurf' && !hasCancellationInvoice(row.original) && !isPaid(row.original) ">
|
||||
{{ displayCurrency(getDocumentOpenAmount(row.original)) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #empty>
|
||||
@@ -138,13 +140,25 @@
|
||||
</template>
|
||||
</UTable>
|
||||
</div>
|
||||
<div
|
||||
v-if="getRowsForTab(item.key).length > rowsPerPage"
|
||||
class="flex items-center justify-center border-t border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900"
|
||||
>
|
||||
<UPagination
|
||||
v-model:page="tabPages[item.key]"
|
||||
:items-per-page="rowsPerPage"
|
||||
:total="getRowsForTab(item.key).length"
|
||||
:show-edges="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { ref, computed, reactive, watch } from 'vue';
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const tempStore = useTempStore()
|
||||
@@ -158,6 +172,17 @@ const dataType = dataStore.dataTypes[type]
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
const activeTabIndex = ref(0)
|
||||
const rowsPerPage = 100
|
||||
const tabPages = reactive({
|
||||
drafts: 1,
|
||||
invoices: 1,
|
||||
quotes: 1,
|
||||
costEstimates: 1,
|
||||
deliveryNotes: 1,
|
||||
packingSlips: 1,
|
||||
confirmationOrders: 1
|
||||
})
|
||||
const sum = useSum()
|
||||
|
||||
// Debounce-Logik für die Suche
|
||||
const searchString = ref(tempStore.searchStrings['createddocuments'] || '')
|
||||
@@ -281,22 +306,53 @@ const clearSearchString = () => {
|
||||
debouncedSearchString.value = ''
|
||||
}
|
||||
|
||||
const getCancellationInvoice = (row) => {
|
||||
return items.value.find((item) => {
|
||||
const linkedDocumentId = item.createddocument?.id || item.createddocument
|
||||
return item.type === 'cancellationInvoices'
|
||||
&& item.state !== 'Entwurf'
|
||||
&& !item.archived
|
||||
&& linkedDocumentId === row.id
|
||||
})
|
||||
}
|
||||
const cancellationInvoicesByDocument = computed(() => {
|
||||
const result = new Map()
|
||||
|
||||
items.value.forEach((item) => {
|
||||
const linkedDocumentId = item.createddocument?.id || item.createddocument
|
||||
if (item.type === 'cancellationInvoices' && item.state !== 'Entwurf' && !item.archived && linkedDocumentId) {
|
||||
result.set(linkedDocumentId, item)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
const documentAmounts = computed(() => {
|
||||
const result = new Map()
|
||||
|
||||
items.value.forEach((item) => {
|
||||
const amount = sum.getCreatedDocumentSum(item, items.value)
|
||||
const amountPaid = (item.statementallocations || []).reduce(
|
||||
(total, allocation) => total + Number(allocation.amount || 0),
|
||||
0
|
||||
)
|
||||
|
||||
result.set(item.id, {
|
||||
amount,
|
||||
openAmount: Number((amount - amountPaid).toFixed(2))
|
||||
})
|
||||
})
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
const getCancellationInvoice = (row) => cancellationInvoicesByDocument.value.get(row.id)
|
||||
const hasCancellationInvoice = (row) => Boolean(getCancellationInvoice(row))
|
||||
const getDocumentAmount = (row) => documentAmounts.value.get(row.id)?.amount || 0
|
||||
const getDocumentOpenAmount = (row) => documentAmounts.value.get(row.id)?.openAmount || 0
|
||||
const isPaid = (row) => getDocumentOpenAmount(row) === 0
|
||||
|
||||
const openUnpaidInvoicesFilter = {
|
||||
name: 'Nur offene Belege',
|
||||
filterFunction: (row) => {
|
||||
return row.state === 'Entwurf' || useSum().isOpenCreatedDocument(row, items.value)
|
||||
return row.state === 'Entwurf' || (
|
||||
['invoices', 'advanceInvoices'].includes(row.type)
|
||||
&& row.state === 'Gebucht'
|
||||
&& !hasCancellationInvoice(row)
|
||||
&& !isPaid(row)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,16 +395,33 @@ const filteredRows = computed(() => {
|
||||
return results
|
||||
})
|
||||
|
||||
const getRowsForTab = (tabKey) => {
|
||||
return filteredRows.value.filter(row => {
|
||||
if (tabKey === 'drafts') return row.state === 'Entwurf'
|
||||
if (row.state === 'Entwurf') return false
|
||||
if (tabKey === 'invoices') return ['invoices', 'advanceInvoices', 'cancellationInvoices'].includes(row.type)
|
||||
return row.type === tabKey
|
||||
const rowsByTab = computed(() => {
|
||||
const result = Object.fromEntries(templateTypes.map(type => [type.key, []]))
|
||||
|
||||
filteredRows.value.forEach(row => {
|
||||
if (row.state === 'Entwurf') {
|
||||
result.drafts.push(row)
|
||||
} else if (['invoices', 'advanceInvoices', 'cancellationInvoices'].includes(row.type)) {
|
||||
result.invoices.push(row)
|
||||
} else if (result[row.type]) {
|
||||
result[row.type].push(row)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
const getRowsForTab = (tabKey) => rowsByTab.value[tabKey] || []
|
||||
|
||||
const getVisibleRowsForTab = (tabKey) => {
|
||||
const rows = getRowsForTab(tabKey)
|
||||
const start = (tabPages[tabKey] - 1) * rowsPerPage
|
||||
return rows.slice(start, start + rowsPerPage)
|
||||
}
|
||||
|
||||
const isPaid = (item) => {
|
||||
return useSum().getIsPaid(item, items.value)
|
||||
}
|
||||
watch([debouncedSearchString, selectedFilters, selectedTypes], () => {
|
||||
Object.keys(tabPages).forEach((key) => {
|
||||
tabPages[key] = 1
|
||||
})
|
||||
}, { deep: true })
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user