|
|
|
|
@@ -12,6 +12,19 @@ const route = useRoute()
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const modal = useModal()
|
|
|
|
|
const auth = useAuthStore()
|
|
|
|
|
const quoteLikeDocumentTypes = ["quotes", "costEstimates"]
|
|
|
|
|
const deliveryNoteLikeDocumentTypes = ["deliveryNotes", "packingSlips"]
|
|
|
|
|
const documentStorageFallbackTypes = {
|
|
|
|
|
costEstimates: "quotes",
|
|
|
|
|
packingSlips: "deliveryNotes",
|
|
|
|
|
advanceInvoices: "invoices",
|
|
|
|
|
cancellationInvoices: "invoices"
|
|
|
|
|
}
|
|
|
|
|
const textTemplateFallbackTypes = {
|
|
|
|
|
serialInvoices: "invoices",
|
|
|
|
|
costEstimates: "quotes",
|
|
|
|
|
packingSlips: "deliveryNotes"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const guard = ref(true)
|
|
|
|
|
|
|
|
|
|
@@ -303,7 +316,7 @@ const setupPage = async () => {
|
|
|
|
|
itemInfo.value.rows.push(...linkedDocument.rows)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for await (const doc of linkedDocuments.filter(i => i.type === "quotes")) {
|
|
|
|
|
for await (const doc of linkedDocuments.filter(i => quoteLikeDocumentTypes.includes(i.type))) {
|
|
|
|
|
let linkedDocument = await useEntities("createddocuments").selectSingle(doc.id)
|
|
|
|
|
|
|
|
|
|
itemInfo.value.rows.push({
|
|
|
|
|
@@ -471,20 +484,24 @@ const setDocumentTypeConfig = (withTexts = false) => {
|
|
|
|
|
if (itemInfo.value.type === "invoices" || itemInfo.value.type === "advanceInvoices" || itemInfo.value.type === "serialInvoices" || itemInfo.value.type === "cancellationInvoices") {
|
|
|
|
|
itemInfo.value.documentNumberTitle = "Rechnungsnummer"
|
|
|
|
|
itemInfo.value.title = `Rechnung-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}`
|
|
|
|
|
} else if (itemInfo.value.type === "quotes") {
|
|
|
|
|
itemInfo.value.documentNumberTitle = "Angebotsnummer"
|
|
|
|
|
itemInfo.value.title = `Angebot-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}`
|
|
|
|
|
} else if (itemInfo.value.type === "deliveryNotes") {
|
|
|
|
|
itemInfo.value.documentNumberTitle = "Lieferscheinnummer"
|
|
|
|
|
itemInfo.value.title = `Lieferschein-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}`
|
|
|
|
|
} else if (quoteLikeDocumentTypes.includes(itemInfo.value.type)) {
|
|
|
|
|
const titlePrefix = itemInfo.value.type === "costEstimates" ? "Kostenschätzung" : "Angebot"
|
|
|
|
|
itemInfo.value.documentNumberTitle = itemInfo.value.type === "costEstimates" ? "Kostenschätzungsnummer" : "Angebotsnummer"
|
|
|
|
|
itemInfo.value.title = `${titlePrefix}-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}`
|
|
|
|
|
} else if (deliveryNoteLikeDocumentTypes.includes(itemInfo.value.type)) {
|
|
|
|
|
const titlePrefix = itemInfo.value.type === "packingSlips" ? "Packschein" : "Lieferschein"
|
|
|
|
|
itemInfo.value.documentNumberTitle = itemInfo.value.type === "packingSlips" ? "Packscheinnummer" : "Lieferscheinnummer"
|
|
|
|
|
itemInfo.value.title = `${titlePrefix}-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}`
|
|
|
|
|
} else if (itemInfo.value.type === "confirmationOrders") {
|
|
|
|
|
itemInfo.value.documentNumberTitle = "Auftragsbestätigungsnr."
|
|
|
|
|
itemInfo.value.title = `Auftragsbestätigung-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (withTexts) {
|
|
|
|
|
itemInfo.value.startText = getTextTemplateByType(itemInfo.value.type).find(i => i.default && i.pos === "startText").text
|
|
|
|
|
itemInfo.value.endText = getTextTemplateByType(itemInfo.value.type).find(i => i.default && i.pos === "endText").text
|
|
|
|
|
const startTemplate = getTextTemplateByType(itemInfo.value.type).find(i => i.default && i.pos === "startText")
|
|
|
|
|
const endTemplate = getTextTemplateByType(itemInfo.value.type).find(i => i.default && i.pos === "endText")
|
|
|
|
|
itemInfo.value.startText = startTemplate?.text || null
|
|
|
|
|
itemInfo.value.endText = endTemplate?.text || null
|
|
|
|
|
//itemInfo.value.startText = texttemplates.value.find(i => i.documentType === itemInfo.value.type && i.default && i.pos === "startText").text
|
|
|
|
|
//itemInfo.value.endText = texttemplates.value.find(i => i.documentType === itemInfo.value.type && i.default && i.pos === "endText").text
|
|
|
|
|
}
|
|
|
|
|
@@ -771,16 +788,16 @@ const findDocumentErrors = computed(() => {
|
|
|
|
|
} else {
|
|
|
|
|
itemInfo.value.rows.forEach((row,index) => {
|
|
|
|
|
|
|
|
|
|
if (itemInfo.value.type !== "quotes" && row.optional) {
|
|
|
|
|
if (!quoteLikeDocumentTypes.includes(itemInfo.value.type) && row.optional) {
|
|
|
|
|
errors.push({
|
|
|
|
|
message: `Position ${row.pos} ist als Optional markiert. Dies wird nur in Angeboten unterstützt.`,
|
|
|
|
|
message: `Position ${row.pos} ist als Optional markiert. Dies wird nur in Angeboten und Kostenschätzungen unterstützt.`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (itemInfo.value.type !== "quotes" && row.alternative) {
|
|
|
|
|
if (!quoteLikeDocumentTypes.includes(itemInfo.value.type) && row.alternative) {
|
|
|
|
|
errors.push({
|
|
|
|
|
message: `Position ${row.pos} ist als Alternativ markiert. Dies wird nur in Angeboten unterstützt.`,
|
|
|
|
|
message: `Position ${row.pos} ist als Alternativ markiert. Dies wird nur in Angeboten und Kostenschätzungen unterstützt.`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
@@ -805,11 +822,11 @@ const findDocumentErrors = computed(() => {
|
|
|
|
|
|
|
|
|
|
if (["normal", "service", "free"].includes(row.mode)) {
|
|
|
|
|
|
|
|
|
|
if (!row.taxPercent && typeof row.taxPercent !== "number" && itemInfo.value.type !== "deliveryNotes") errors.push({
|
|
|
|
|
if (!row.taxPercent && typeof row.taxPercent !== "number" && !deliveryNoteLikeDocumentTypes.includes(itemInfo.value.type)) errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist kein Steuersatz hinterlegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (!row.price && typeof row.price !== "number" && itemInfo.value.type !== "deliveryNotes") errors.push({
|
|
|
|
|
if (!row.price && typeof row.price !== "number" && !deliveryNoteLikeDocumentTypes.includes(itemInfo.value.type)) errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist kein Preis hinterlegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
@@ -1421,12 +1438,7 @@ const saveDocument = async (state, resetup = false) => {
|
|
|
|
|
if (state !== "Entwurf") {
|
|
|
|
|
console.log("???")
|
|
|
|
|
|
|
|
|
|
let type = ""
|
|
|
|
|
if (itemInfo.value.type === "advanceInvoices" || itemInfo.value.type === "cancellationInvoices") {
|
|
|
|
|
type = "invoices"
|
|
|
|
|
} else {
|
|
|
|
|
type = itemInfo.value.type
|
|
|
|
|
}
|
|
|
|
|
const type = itemInfo.value.type
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
itemInfo.value.documentNumber = await useFunctions().useNextNumber(type) //data.usedNumber
|
|
|
|
|
@@ -1466,7 +1478,7 @@ const saveDocument = async (state, resetup = false) => {
|
|
|
|
|
|
|
|
|
|
let createData = {
|
|
|
|
|
type: itemInfo.value.type,
|
|
|
|
|
taxType: ['invoices', 'cancellationInvoices', 'advanceInvoices', 'quotes', 'confirmationOrders'].includes(itemInfo.value.type) ? normalizeTaxTypeValue(itemInfo.value.taxType) : null,
|
|
|
|
|
taxType: ['invoices', 'cancellationInvoices', 'advanceInvoices', 'confirmationOrders', ...quoteLikeDocumentTypes].includes(itemInfo.value.type) ? normalizeTaxTypeValue(itemInfo.value.taxType) : null,
|
|
|
|
|
state: itemInfo.value.state || "Entwurf",
|
|
|
|
|
customer: itemInfo.value.customer,
|
|
|
|
|
contact: itemInfo.value.contact,
|
|
|
|
|
@@ -1529,11 +1541,7 @@ const closeDocument = async () => {
|
|
|
|
|
fileData.project = itemInfo.value.project
|
|
|
|
|
fileData.createddocument = itemInfo.value.id
|
|
|
|
|
|
|
|
|
|
let mappedType = itemInfo.value.type
|
|
|
|
|
|
|
|
|
|
if (mappedType === "advanceInvoices" || mappedType === "cancellationInvoices") {
|
|
|
|
|
mappedType = "invoices"
|
|
|
|
|
}
|
|
|
|
|
let mappedType = documentStorageFallbackTypes[itemInfo.value.type] || itemInfo.value.type
|
|
|
|
|
|
|
|
|
|
const folders = await useEntities("folders").select()
|
|
|
|
|
console.log(folders)
|
|
|
|
|
@@ -1571,11 +1579,7 @@ const closeDocument = async () => {
|
|
|
|
|
|
|
|
|
|
const getTextTemplateByType = (type, pos) => {
|
|
|
|
|
|
|
|
|
|
let finalType = type
|
|
|
|
|
|
|
|
|
|
if (type === "serialInvoices") {
|
|
|
|
|
finalType = "invoices"
|
|
|
|
|
}
|
|
|
|
|
const finalType = textTemplateFallbackTypes[type] || type
|
|
|
|
|
|
|
|
|
|
if (pos) {
|
|
|
|
|
return texttemplates.value.filter(i => i.documentType === finalType && i.pos === pos)
|
|
|
|
|
@@ -1806,7 +1810,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
|
|
|
|
|
<UFormField
|
|
|
|
|
label="Steuertyp:"
|
|
|
|
|
v-if="['invoices','advanceInvoices','quotes','confirmationOrders','serialInvoices'].includes(itemInfo.type)"
|
|
|
|
|
v-if="['invoices','advanceInvoices','confirmationOrders','serialInvoices', ...quoteLikeDocumentTypes].includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
<USelectMenu
|
|
|
|
|
:items="taxTypeItems"
|
|
|
|
|
@@ -2498,11 +2502,11 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<th class="pl-2">Name</th>
|
|
|
|
|
<th class="pl-2">Menge</th>
|
|
|
|
|
<th class="pl-2">Einheit</th>
|
|
|
|
|
<th class="pl-2" v-if="itemInfo.type !== 'deliveryNotes'">Preis</th>
|
|
|
|
|
<!-- <th class="pl-2" v-if="itemInfo.type !== 'deliveryNotes'">Steuer</th>
|
|
|
|
|
<th class="pl-2" v-if="itemInfo.type !== 'deliveryNotes'">Rabatt</th>-->
|
|
|
|
|
<th class="pl-2" v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)">Preis</th>
|
|
|
|
|
<!-- <th class="pl-2" v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)">Steuer</th>
|
|
|
|
|
<th class="pl-2" v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)">Rabatt</th>-->
|
|
|
|
|
<th class="pl-2"></th>
|
|
|
|
|
<th class="pl-2" v-if="itemInfo.type !== 'deliveryNotes'">Gesamt</th>
|
|
|
|
|
<th class="pl-2" v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)">Gesamt</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<draggable
|
|
|
|
|
@@ -2730,7 +2734,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</td>
|
|
|
|
|
<td
|
|
|
|
|
class="w-full"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode) && itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode) && !deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
<UInput
|
|
|
|
|
v-model="row.inputPrice"
|
|
|
|
|
@@ -2762,7 +2766,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</td>
|
|
|
|
|
<!-- <td
|
|
|
|
|
class="w-40"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode)&& itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode)&& !deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
<USelectMenu
|
|
|
|
|
@@ -2781,7 +2785,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</td>-->
|
|
|
|
|
<!-- <td
|
|
|
|
|
class="w-40"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode)&& itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode)&& !deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
<UInput
|
|
|
|
|
v-model="row.discountPercent"
|
|
|
|
|
@@ -2859,7 +2863,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
|
|
|
|
|
<UFormField
|
|
|
|
|
label="Einzelpreis:"
|
|
|
|
|
v-if="itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
<UInput
|
|
|
|
|
v-model="row.inputPrice"
|
|
|
|
|
@@ -2891,7 +2895,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<UFormField
|
|
|
|
|
label="Umsatzsteuer:"
|
|
|
|
|
class="mt-3"
|
|
|
|
|
v-if="itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
<USelectMenu
|
|
|
|
|
:items="taxPercentItems"
|
|
|
|
|
@@ -2911,7 +2915,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<UFormField
|
|
|
|
|
label="Rabatt:"
|
|
|
|
|
class="mt-3"
|
|
|
|
|
v-if="itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
<UInput
|
|
|
|
|
v-model="row.discountPercent"
|
|
|
|
|
@@ -3066,7 +3070,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</UModal>
|
|
|
|
|
</td>
|
|
|
|
|
<td
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode) && itemInfo.type !== 'deliveryNotes'"
|
|
|
|
|
v-if="!['pagebreak','title','text'].includes(row.mode) && !deliveryNoteLikeDocumentTypes.includes(itemInfo.type)"
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
<p class="text-right font-bold whitespace-nowrap">
|
|
|
|
|
@@ -3200,7 +3204,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<USeparator class="my-3" v-if="itemInfo.rows.length > 0" label="Auswertung & Gesamt"/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="w-full flex justify-between" v-if="itemInfo.type !== 'deliveryNotes'">
|
|
|
|
|
<div class="w-full flex justify-between" v-if="!deliveryNoteLikeDocumentTypes.includes(itemInfo.type)">
|
|
|
|
|
<table class="w-1/2" v-if="itemInfo.rows.length > 0">
|
|
|
|
|
<tr v-if="documentReport.totalProductsPurchasePrice !== 0">
|
|
|
|
|
<td>Einkaufspreis Artikel Gesamt:</td>
|
|
|
|
|
|