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,14 +57,16 @@
|
|||||||
</UBadge>
|
</UBadge>
|
||||||
</template>
|
</template>
|
||||||
<template #content="{item}">
|
<template #content="{item}">
|
||||||
<div style="height: 80vh; overflow-y: scroll">
|
<div class="flex h-[80vh] flex-col">
|
||||||
<UTable
|
<div class="min-h-0 flex-1 overflow-y-auto">
|
||||||
:columns="normalizeTableColumns(getColumnsForTab(item.key))"
|
<UTable
|
||||||
:data="getRowsForTab(item.key)"
|
:columns="normalizeTableColumns(getColumnsForTab(item.key))"
|
||||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
:data="getVisibleRowsForTab(item.key)"
|
||||||
class="w-full"
|
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||||
:on-select="selectItem"
|
class="w-full"
|
||||||
>
|
:watch-options="{ deep: false }"
|
||||||
|
:on-select="selectItem"
|
||||||
|
>
|
||||||
<template #type-cell="{row}">
|
<template #type-cell="{row}">
|
||||||
<span v-if="row.original.type === 'cancellationInvoices'" class="text-cyan-500">{{
|
<span v-if="row.original.type === 'cancellationInvoices'" class="text-cyan-500">{{
|
||||||
dataStore.documentTypesForCreation[row.original.type].labelSingle
|
dataStore.documentTypesForCreation[row.original.type].labelSingle
|
||||||
@@ -118,25 +120,37 @@
|
|||||||
<template #paid-cell="{row}">
|
<template #paid-cell="{row}">
|
||||||
<div
|
<div
|
||||||
v-if="(row.original.type === 'invoices' ||row.original.type === 'advanceInvoices') && row.original.state === 'Gebucht' && !hasCancellationInvoice(row.original)">
|
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>
|
<span v-else class="text-rose-600">Offen</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #amount-cell="{row}">
|
<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>
|
||||||
|
|
||||||
<template #amountOpen-cell="{row}">
|
<template #amountOpen-cell="{row}">
|
||||||
<span
|
<span
|
||||||
v-if="!['cancellationInvoices','confirmationOrders', ...quoteLikeDocumentTypes, ...deliveryNoteLikeDocumentTypes].includes(row.original.type) && row.original.state !== 'Entwurf' && !hasCancellationInvoice(row.original) && !useSum().getIsPaid(row.original,items) ">
|
v-if="!['cancellationInvoices','confirmationOrders', ...quoteLikeDocumentTypes, ...deliveryNoteLikeDocumentTypes].includes(row.original.type) && row.original.state !== 'Entwurf' && !hasCancellationInvoice(row.original) && !isPaid(row.original) ">
|
||||||
{{ displayCurrency(useSum().getCreatedDocumentOpenAmount(row.original, items)) }}
|
{{ displayCurrency(getDocumentOpenAmount(row.original)) }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<TableEmptyState label="Keine Belege anzuzeigen" />
|
<TableEmptyState label="Keine Belege anzuzeigen" />
|
||||||
</template>
|
</template>
|
||||||
</UTable>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UTabs>
|
</UTabs>
|
||||||
@@ -144,7 +158,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { ref, computed, watch } from 'vue';
|
import { ref, computed, reactive, watch } from 'vue';
|
||||||
|
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
const tempStore = useTempStore()
|
const tempStore = useTempStore()
|
||||||
@@ -158,6 +172,17 @@ const dataType = dataStore.dataTypes[type]
|
|||||||
const items = ref([])
|
const items = ref([])
|
||||||
const selectedItem = ref(0)
|
const selectedItem = ref(0)
|
||||||
const activeTabIndex = 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
|
// Debounce-Logik für die Suche
|
||||||
const searchString = ref(tempStore.searchStrings['createddocuments'] || '')
|
const searchString = ref(tempStore.searchStrings['createddocuments'] || '')
|
||||||
@@ -281,22 +306,53 @@ const clearSearchString = () => {
|
|||||||
debouncedSearchString.value = ''
|
debouncedSearchString.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCancellationInvoice = (row) => {
|
const cancellationInvoicesByDocument = computed(() => {
|
||||||
return items.value.find((item) => {
|
const result = new Map()
|
||||||
const linkedDocumentId = item.createddocument?.id || item.createddocument
|
|
||||||
return item.type === 'cancellationInvoices'
|
|
||||||
&& item.state !== 'Entwurf'
|
|
||||||
&& !item.archived
|
|
||||||
&& linkedDocumentId === row.id
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 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 = {
|
const openUnpaidInvoicesFilter = {
|
||||||
name: 'Nur offene Belege',
|
name: 'Nur offene Belege',
|
||||||
filterFunction: (row) => {
|
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
|
return results
|
||||||
})
|
})
|
||||||
|
|
||||||
const getRowsForTab = (tabKey) => {
|
const rowsByTab = computed(() => {
|
||||||
return filteredRows.value.filter(row => {
|
const result = Object.fromEntries(templateTypes.map(type => [type.key, []]))
|
||||||
if (tabKey === 'drafts') return row.state === 'Entwurf'
|
|
||||||
if (row.state === 'Entwurf') return false
|
filteredRows.value.forEach(row => {
|
||||||
if (tabKey === 'invoices') return ['invoices', 'advanceInvoices', 'cancellationInvoices'].includes(row.type)
|
if (row.state === 'Entwurf') {
|
||||||
return row.type === tabKey
|
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) => {
|
watch([debouncedSearchString, selectedFilters, selectedTypes], () => {
|
||||||
return useSum().getIsPaid(item, items.value)
|
Object.keys(tabPages).forEach((key) => {
|
||||||
}
|
tabPages[key] = 1
|
||||||
|
})
|
||||||
|
}, { deep: true })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user