Rebuild Inovice LoadModes

This commit is contained in:
2025-07-31 20:37:51 +02:00
parent 80d68e0aa9
commit c70cd797ac

View File

@@ -129,74 +129,133 @@ const setupPage = async () => {
if(route.query.linkedDocuments) {
let linkedDocuments = (await supabase.from("createddocuments").select().in("id",JSON.parse(route.query.linkedDocuments))).data
console.log(route.query.loadMode)
//TODO: Implement Checking for Same Customer, Contact and Project
if(route.query.loadMode === "deliveryNotes") {
let linkedDocuments = (await supabase.from("createddocuments").select().in("id",JSON.parse(route.query.linkedDocuments))).data
itemInfo.value.customer = linkedDocuments[0].customer
itemInfo.value.project = linkedDocuments[0].project
itemInfo.value.contact = linkedDocuments[0].contact
//TODO: Implement Checking for Same Customer, Contact and Project
setCustomerData()
itemInfo.value.customer = linkedDocuments[0].customer
itemInfo.value.project = linkedDocuments[0].project
itemInfo.value.contact = linkedDocuments[0].contact
let firstDate = null
let lastDate = null
setCustomerData()
let firstDate = null
let lastDate = null
linkedDocuments.forEach(doc => {
let lastId = 0
itemInfo.value.rows.forEach(row => {
if(row.id > lastId) lastId = row.id
})
if(dayjs(doc.documentDate).isBefore(firstDate) || !firstDate) firstDate = doc.documentDate
if(dayjs(doc.documentDate).isAfter(lastDate) || !lastDate) lastDate = doc.documentDate
itemInfo.value.rows.push(...[
{
id:uuidv4(),
mode: "title",
text: `${doc.title} vom ${dayjs(doc.documentDate).format("DD.MM.YYYY")}`
},
...doc.rows
])
linkedDocuments.forEach(doc => {
let lastId = 0
itemInfo.value.rows.forEach(row => {
if(row.id > lastId) lastId = row.id
})
if(dayjs(doc.documentDate).isBefore(firstDate) || !firstDate) firstDate = doc.documentDate
if(dayjs(doc.documentDate).isAfter(lastDate) || !lastDate) lastDate = doc.documentDate
itemInfo.value.deliveryDateType = "Leistungszeitraum"
itemInfo.value.deliveryDate = firstDate
itemInfo.value.deliveryDateEnd = lastDate
itemInfo.value.rows.push(...[
{
itemInfo.value.rows.forEach(row => {
row.discountPercent = 0
setRowData(row)
})
setPosNumbers()
console.log(linkedDocuments)
if(linkedDocuments.find(i => i.rows.find( x => x.agriculture.dieselUsage))){
console.log("has diesel")
//Remove Existing Total Diesel Pos
itemInfo.value.rows = itemInfo.value.rows.filter(i => i.key !== "dieselPos")
//Remove Existing Total Ad Blue Pos
itemInfo.value.rows = itemInfo.value.rows.filter(i => i.key !== "adbluePos")
//Add Total Title
itemInfo.value.rows.push({
id:uuidv4(),
mode: "title",
text: `${doc.title} vom ${dayjs(doc.documentDate).format("DD.MM.YYYY")}`
},
...doc.rows
])
text: "Allgemein"
})
})
processDieselPosition()
}
itemInfo.value.deliveryDateType = "Leistungszeitraum"
itemInfo.value.deliveryDate = firstDate
itemInfo.value.deliveryDateEnd = lastDate
} else if(route.query.loadMode === "finalInvoice") {
let linkedDocuments = (await supabase.from("createddocuments").select().in("id",JSON.parse(route.query.linkedDocuments))).data
itemInfo.value.rows.forEach(row => {
//TODO: Implement Checking for Same Customer, Contact and Project
row.discountPercent = 0
console.log(linkedDocuments)
setRowData(row)
itemInfo.value.customer = linkedDocuments[0].customer
itemInfo.value.project = linkedDocuments[0].project
itemInfo.value.contact = linkedDocuments[0].contact
})
setCustomerData()
setPosNumbers()
for await (const doc of linkedDocuments.filter(i => i.type === "confirmationOrders")) {
let linkedDocument = await useSupabaseSelectSingle("createddocuments",doc.id)
itemInfo.value.rows.push(...linkedDocument.rows)
}
console.log(linkedDocuments)
for await (const doc of linkedDocuments.filter(i => i.type === "quotes")) {
let linkedDocument = await useSupabaseSelectSingle("createddocuments",doc.id)
itemInfo.value.rows.push(...linkedDocument.rows)
}
for await (const doc of linkedDocuments.filter(i => i.type === "advanceInvoices")) {
itemInfo.value.rows.push({
mode: "free",
text: `Abschlagsrechnung ${doc.documentNumber}`,
quantity: 1,
taxPercent: 19, // TODO TAX PERCENTAGE
discountPercent: 0,
unit: 10,
inputPrice: useSum().getCreatedDocumentSumDetailed(doc).totalNet *-1,
linkedEntitys: [
{
type: "createddocuments",
subtype: "advanceInvoices",
id: doc.id
}
],
editDisabled: true
})
updateCustomSurcharge()
}
setPosNumbers()
if(linkedDocuments.find(i => i.rows.find( x => x.agriculture.dieselUsage))){
console.log("has diesel")
//Remove Existing Total Diesel Pos
itemInfo.value.rows = itemInfo.value.rows.filter(i => i.key !== "dieselPos")
//Remove Existing Total Ad Blue Pos
itemInfo.value.rows = itemInfo.value.rows.filter(i => i.key !== "adbluePos")
//Add Total Title
itemInfo.value.rows.push({
id:uuidv4(),
mode: "title",
text: "Allgemein"
})
processDieselPosition()
}
}
if(route.query.linkedDocument) {
@@ -265,6 +324,12 @@ const setupPage = async () => {
row.price = row.price * -1
})
itemInfo.value.documentDate = dayjs()
itemInfo.value.usedAdvanceInvoices = linkedDocument.usedAdvanceInvoices
checkForOpenAdvanceInvoices()
itemInfo.value.description = `Stornorechnung zu Rechnung ${linkedDocument.documentNumber} vom ${dayjs(linkedDocument.documentDate).format('DD.MM.YYYY')}`
itemInfo.value.type = "cancellationInvoices"
@@ -310,11 +375,12 @@ setupPage()
const openAdvanceInvoices = ref([])
const checkForOpenAdvanceInvoices = async () => {
console.log("Check for Open Advance Invoices")
const {data,error} = await supabase.from("createddocuments").select().eq("project", itemInfo.value.project).eq("advanceInvoiceResolved", false).eq("type","advanceInvoices")
const {data} = await supabase.from("createddocuments").select().eq("project", itemInfo.value.project).eq("advanceInvoiceResolved", false).eq("type","advanceInvoices")
const {data: usedAdvanceInvoices} = await supabase.from("createddocuments").select().in("id", itemInfo.value.usedAdvanceInvoices)
console.log(data)
openAdvanceInvoices.value = data
openAdvanceInvoices.value = [...data, ...usedAdvanceInvoices.filter(i => !data.find(x => x.id === i.id))]
}
@@ -487,7 +553,8 @@ const addPosition = (mode) => {
inputPrice: 0,
price: 0,
taxPercent: taxPercentage,
discountPercent: 0
discountPercent: 0,
linkedEntitys: []
}
itemInfo.value.rows.push({...rowData, ...profileStore.ownTenant.extraModules.includes("agriculture") ? {agriculture: {}}: {}})
@@ -501,7 +568,8 @@ const addPosition = (mode) => {
price: 0,
taxPercent: taxPercentage,
discountPercent: 0,
unit: 1
unit: 1,
linkedEntitys: []
})
} else if(mode === 'service'){
let rowData = {
@@ -512,7 +580,8 @@ const addPosition = (mode) => {
price: 0,
taxPercent: taxPercentage,
discountPercent: 0,
unit: 1
unit: 1,
linkedEntitys: []
}
//Push Agriculture Holder only if Module is activated
@@ -521,16 +590,19 @@ const addPosition = (mode) => {
itemInfo.value.rows.push({
id: uuidv4(),
mode: "pagebreak",
linkedEntitys: []
})
} else if(mode === "title") {
itemInfo.value.rows.push({
id: uuidv4(),
mode: "title",
linkedEntitys: []
})
} else if(mode === "text") {
itemInfo.value.rows.push({
id: uuidv4(),
mode: "text",
linkedEntitys: []
})
}
@@ -692,7 +764,22 @@ const documentTotal = computed(() => {
console.log(totalGrossAlreadyPaid)
let sumToPay = totalGross - totalGrossAlreadyPaid
let sumToPay = 0
if(itemInfo.value.type === "invoices") {
sumToPay = totalGross - totalGrossAlreadyPaid
} else if(itemInfo.value.type === "cancellationInvoices") {
sumToPay = totalGross + totalGrossAlreadyPaid
}
return {
titleSums: titleSums,
@@ -2083,6 +2170,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
<UIcon
class="handle"
name="i-mdi-menu"
v-if="itemInfo.type !== 'cancellationInvoices'"
/>
</td>
<td
@@ -2113,6 +2201,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
v-if="row.mode === 'free'"
>
<UInput
:disabled="itemInfo.type === 'cancellationInvoices' || row.editDisabled"
v-model="row.text"
placeholder="Name"
class="min-w-40"
@@ -2124,6 +2213,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
>
<InputGroup class="w-full">
<USelectMenu
:disabled="itemInfo.type === 'cancellationInvoices'"
class="w-60"
:options="products"
:color="row.product ? 'primary' : 'rose'"
@@ -2193,6 +2283,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
>
<InputGroup class="w-full">
<USelectMenu
:disabled="itemInfo.type === 'cancellationInvoices'"
class="w-60"
:options="services"
:color="row.service ? 'primary' : 'rose'"
@@ -2259,6 +2350,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
>
<UInput
v-model="row.quantity"
:disabled="itemInfo.type === 'cancellationInvoices'"
type="number"
:step="dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).step : '1' "
@@ -2270,6 +2362,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
>
<USelectMenu
v-model="row.unit"
:disabled="itemInfo.type === 'cancellationInvoices'"
:options="dataStore.units"
option-attribute="name"
value-attribute="id"
@@ -2285,6 +2378,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
>
<UInput
v-model="row.inputPrice"
:disabled="itemInfo.type === 'cancellationInvoices'"
type="number"
step="0.001"
@change="updateCustomSurcharge"
@@ -2348,10 +2442,12 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
v-if="!['pagebreak','title','text'].includes(row.mode)"
>
<UButton
:disabled="itemInfo.type === 'cancellationInvoices'"
icon="i-heroicons-pencil-square-16-solid"
@click="row.showEdit = true"
/>
<UButton
:disabled="itemInfo.type === 'cancellationInvoices'"
icon="i-mdi-water-drop-outline"
class="ml-3"
v-if="row.agriculture"
@@ -2370,6 +2466,36 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="row.showEdit = false" />
</div>
</template>
<InputGroup>
<UFormGroup
label="Anzahl:"
class="flex-auto"
>
<UInput
v-model="row.quantity"
type="number"
:step="dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).step : '1' "
/>
</UFormGroup>
<UFormGroup
label="Einheit:"
class="flex-auto"
>
<USelectMenu
v-model="row.unit"
:options="dataStore.units"
option-attribute="name"
value-attribute="id"
>
<template #label>
{{dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).name : "Keine Einheit gewählt"}}
</template>
</USelectMenu>
</UFormGroup>
</InputGroup>
<UFormGroup
label="Einzelpreis:"
v-if="itemInfo.type !== 'deliveryNotes'"
@@ -2455,6 +2581,26 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
</UFormGroup>
</InputGroup>
<UAlert
v-if="row.linkedEntitys && row.linkedEntitys.find(i => i.type === 'createddocuments' && i.subtype === 'advanceInvoices')"
title="Berechnung des Individuellen Aufschlags für die Zeile gesperrt"
color="orange"
variant="subtle"
class="my-3"
/>
Verknüpfungen:
<ul>
<li
v-for="linkedEntity in row.linkedEntitys"
>
- <a
v-if="linkedEntity.subtype === 'advanceInvoices'"
:to="`/createddocuments/show/${linkedEntity.id}`"
>Abschlagsrechnung</a>
</li>
</ul>
<UFormGroup
label="Beschreibung:"
class="mt-3"
@@ -2569,12 +2715,14 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
colspan="6"
>
<UInput
:disabled="itemInfo.type === 'cancellationInvoices'"
v-model="row.text"
placeholder="Titel"
/>
</td>
<td>
<UButton
:disabled="itemInfo.type === 'cancellationInvoices'"
variant="ghost"
color="rose"
icon="i-heroicons-x-mark-16-solid"
@@ -2597,39 +2745,42 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
<UButton
@click="addPosition('service')"
class="mt-3"
:disabled="itemInfo.type === 'advanceInvoices'"
:disabled="['advanceInvoices','cancellationInvoices'].includes(itemInfo.type)"
>
+ Leistung
</UButton>
<UButton
@click="addPosition('normal')"
class="mt-3"
:disabled="itemInfo.type === 'advanceInvoices'"
:disabled="['advanceInvoices','cancellationInvoices'].includes(itemInfo.type)"
>
+ Artikel
</UButton>
<UButton
@click="addPosition('free')"
class="mt-3"
:disabled="itemInfo.type === 'advanceInvoices'"
:disabled="['advanceInvoices','cancellationInvoices'].includes(itemInfo.type)"
>
+ Freie Position
</UButton>
<UButton
@click="addPosition('pagebreak')"
class="mt-3"
:disabled="['advanceInvoices','cancellationInvoices'].includes(itemInfo.type)"
>
+ Seitenumbruch
</UButton>
<UButton
@click="addPosition('title')"
class="mt-3"
:disabled="['advanceInvoices','cancellationInvoices'].includes(itemInfo.type)"
>
+ Titel
</UButton>
<UButton
@click="addPosition('text')"
class="mt-3"
:disabled="['advanceInvoices','cancellationInvoices'].includes(itemInfo.type)"
>
+ Text
</UButton>
@@ -2637,7 +2788,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
<UDivider
class="mt-5 mb-3"
v-if="openAdvanceInvoices.length > 0"
v-if="openAdvanceInvoices.length > 0 || itemInfo.usedAdvanceInvoices.length > 0"
>
Noch nicht abgerechnete Abschlagsrechnungen
</UDivider>