|
|
|
|
@@ -11,6 +11,7 @@ const route = useRoute()
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const supabase = useSupabaseClient()
|
|
|
|
|
const modal = useModal()
|
|
|
|
|
const auth = useAuthStore()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -35,16 +36,14 @@ const itemInfo = ref({
|
|
|
|
|
deliveryDateEnd: null,
|
|
|
|
|
deliveryDateType: "Lieferdatum",
|
|
|
|
|
dateOfPerformance: null,
|
|
|
|
|
paymentDays: profileStore.ownTenant.standardPaymentDays,
|
|
|
|
|
paymentDays: auth.activeTenantData.standardPaymentDays,
|
|
|
|
|
customSurchargePercentage: 0,
|
|
|
|
|
createdBy: profileStore.activeProfile.id,
|
|
|
|
|
title: null,
|
|
|
|
|
description: null,
|
|
|
|
|
startText: null,
|
|
|
|
|
endText: null,
|
|
|
|
|
rows: [
|
|
|
|
|
|
|
|
|
|
],
|
|
|
|
|
rows: [],
|
|
|
|
|
contactPerson: profileStore.activeProfile.id,
|
|
|
|
|
contactPersonName: null,
|
|
|
|
|
contactTel: null,
|
|
|
|
|
@@ -61,7 +60,7 @@ const itemInfo = ref({
|
|
|
|
|
usedAdvanceInvoices: []
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
console.log(profileStore.ownTenant)
|
|
|
|
|
console.log(auth.activeTenantData)
|
|
|
|
|
|
|
|
|
|
const letterheads = ref([])
|
|
|
|
|
const createddocuments = ref([])
|
|
|
|
|
@@ -76,6 +75,8 @@ const selectedServicecategorie = ref(null)
|
|
|
|
|
const customers = ref([])
|
|
|
|
|
const contacts = ref([])
|
|
|
|
|
const texttemplates = ref([])
|
|
|
|
|
const units = ref([])
|
|
|
|
|
const tenantUsers = ref([])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const loaded = ref(false)
|
|
|
|
|
@@ -92,17 +93,21 @@ const setupPage = async () => {
|
|
|
|
|
productcategories.value = await useEntities("productcategories").select("*")
|
|
|
|
|
customers.value = await useEntities("customers").select("*", "customerNumber")
|
|
|
|
|
contacts.value = await useEntities("contacts").select("*")
|
|
|
|
|
texttemplates.value = await useEntities("texttemplactes").select("*")
|
|
|
|
|
texttemplates.value = await useEntities("texttemplates").select("*")
|
|
|
|
|
units.value = await useEntities("units").selectSpecial("*")
|
|
|
|
|
tenantUsers.value = (await useNuxtApp().$api(`/api/tenant/users`, {
|
|
|
|
|
method: "GET"
|
|
|
|
|
})).users
|
|
|
|
|
if (productcategories.value.length > 0) selectedProductcategorie.value = productcategories.value[0].id
|
|
|
|
|
if (servicecategories.value.length > 0) selectedServicecategorie.value = servicecategories.value[0].id
|
|
|
|
|
|
|
|
|
|
if (route.params) {
|
|
|
|
|
if (route.params.id) {
|
|
|
|
|
console.log(route.params)
|
|
|
|
|
itemInfo.value = await useEntities("createddocuments").selectSingle(route.params.id)
|
|
|
|
|
checkCompatibilityWithInputPrice()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(itemInfo.value.project) await checkForOpenAdvanceInvoices()
|
|
|
|
|
|
|
|
|
|
if (!itemInfo.value.deliveryDateType) itemInfo.value.deliveryDateType = "Lieferdatum"
|
|
|
|
|
|
|
|
|
|
@@ -122,7 +127,6 @@ const setupPage = async () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setContactPersonData()
|
|
|
|
|
|
|
|
|
|
if (route.query.linkedDocuments) {
|
|
|
|
|
@@ -264,13 +268,9 @@ const setupPage = async () => {
|
|
|
|
|
setPosNumbers()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (route.query.linkedDocument) {
|
|
|
|
|
@@ -330,7 +330,6 @@ const setupPage = async () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
checkCompatibilityWithInputPrice()
|
|
|
|
|
|
|
|
|
|
if (route.query.loadMode === "storno") {
|
|
|
|
|
@@ -342,7 +341,6 @@ const setupPage = async () => {
|
|
|
|
|
|
|
|
|
|
itemInfo.value.usedAdvanceInvoices = linkedDocument.usedAdvanceInvoices
|
|
|
|
|
|
|
|
|
|
checkForOpenAdvanceInvoices()
|
|
|
|
|
|
|
|
|
|
itemInfo.value.description = `Stornorechnung zu Rechnung ${linkedDocument.documentNumber} vom ${dayjs(linkedDocument.documentDate).format('DD.MM.YYYY')}`
|
|
|
|
|
|
|
|
|
|
@@ -364,7 +362,6 @@ const setupPage = async () => {
|
|
|
|
|
itemInfo.value.description = project.customerRef
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
checkForOpenAdvanceInvoices()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -379,7 +376,6 @@ const setupPage = async () => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if(itemInfo.value.project) checkForOpenAdvanceInvoices()
|
|
|
|
|
|
|
|
|
|
loaded.value = true
|
|
|
|
|
|
|
|
|
|
@@ -478,10 +474,12 @@ const setCustomerData = async (customerId, loadOnlyAdress = false) => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const setContactPersonData = async () => {
|
|
|
|
|
//console.log(itemInfo.value.contactPerson) //TODO Set Profile
|
|
|
|
|
let profile = await useSupabaseSelectSingle("profiles",itemInfo.value.contactPerson, '*')
|
|
|
|
|
//console.log(itemInfo.value.contactPerson) //TODO: BACKEND CHANGE Set Profile
|
|
|
|
|
let profile = (await useNuxtApp().$api(`/api/user/${itemInfo.value.created_by}`, {
|
|
|
|
|
method: "GET"
|
|
|
|
|
})).profile
|
|
|
|
|
|
|
|
|
|
itemInfo.value.contactPersonName = profile.fullName
|
|
|
|
|
itemInfo.value.contactPersonName = auth.profile.full_name
|
|
|
|
|
itemInfo.value.contactTel = profile.mobileTel || profile.fixedTel || ""
|
|
|
|
|
itemInfo.value.contactEMail = profile.email
|
|
|
|
|
|
|
|
|
|
@@ -556,7 +554,7 @@ const addPosition = (mode) => {
|
|
|
|
|
linkedEntitys: []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
itemInfo.value.rows.push({...rowData, ...profileStore.ownTenant.extraModules.includes("agriculture") ? {agriculture: {}}: {}})
|
|
|
|
|
itemInfo.value.rows.push({...rowData, ...auth.activeTenantData.extraModules.includes("agriculture") ? {agriculture: {}} : {}})
|
|
|
|
|
|
|
|
|
|
} else if (mode === 'normal') {
|
|
|
|
|
itemInfo.value.rows.push({
|
|
|
|
|
@@ -584,7 +582,7 @@ const addPosition = (mode) => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Push Agriculture Holder only if Module is activated
|
|
|
|
|
itemInfo.value.rows.push({...rowData, ...profileStore.ownTenant.extraModules.includes("agriculture") ? {agriculture: {}}: {}})
|
|
|
|
|
itemInfo.value.rows.push({...rowData, ...auth.activeTenantData.extraModules.includes("agriculture") ? {agriculture: {}} : {}})
|
|
|
|
|
} else if (mode === "pagebreak") {
|
|
|
|
|
itemInfo.value.rows.push({
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
@@ -623,14 +621,26 @@ const findDocumentErrors = computed(() => {
|
|
|
|
|
if (itemInfo.value.customer === null) errors.push({message: "Es ist kein Kunde ausgewählt", type: "breaking"})
|
|
|
|
|
if (itemInfo.value.contact === null) errors.push({message: "Es ist kein Kontakt ausgewählt", type: "info"})
|
|
|
|
|
if (itemInfo.value.letterhead === null) errors.push({message: "Es ist kein Briefpapier ausgewählt", type: "breaking"})
|
|
|
|
|
if(itemInfo.value.address.street === null) errors.push({message: "Es ist keine Straße im Adressat angegeben", type: "breaking"})
|
|
|
|
|
if(itemInfo.value.address.zip === null) errors.push({message: "Es ist keine Postleitzahl im Adressat angegeben", type: "breaking"})
|
|
|
|
|
if(itemInfo.value.address.city === null) errors.push({message: "Es ist keine Stadt im Adressat angegeben", type: "breaking"})
|
|
|
|
|
if (itemInfo.value.address.street === null) errors.push({
|
|
|
|
|
message: "Es ist keine Straße im Adressat angegeben",
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (itemInfo.value.address.zip === null) errors.push({
|
|
|
|
|
message: "Es ist keine Postleitzahl im Adressat angegeben",
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (itemInfo.value.address.city === null) errors.push({
|
|
|
|
|
message: "Es ist keine Stadt im Adressat angegeben",
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (itemInfo.value.project === null) errors.push({message: "Es ist kein Projekt ausgewählt", type: "info"})
|
|
|
|
|
|
|
|
|
|
if (['Lieferzeitraum', 'Leistungszeitraum'].includes(itemInfo.value.deliveryDateType) && itemInfo.value.type !== "serialInvoices") {
|
|
|
|
|
if(itemInfo.value.deliveryDateEnd === null) errors.push({message: `Es ist kein Enddatum für den ${itemInfo.value.deliveryDateType} angegeben`, type: "breaking"})
|
|
|
|
|
if (itemInfo.value.deliveryDateEnd === null) errors.push({
|
|
|
|
|
message: `Es ist kein Enddatum für den ${itemInfo.value.deliveryDateType} angegeben`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -640,23 +650,47 @@ const findDocumentErrors = computed(() => {
|
|
|
|
|
itemInfo.value.rows.forEach(row => {
|
|
|
|
|
|
|
|
|
|
if (itemInfo.value.type !== "quotes" && row.optional) {
|
|
|
|
|
errors.push({message: `Position ${row.pos} ist als Optional markiert. Dies wird nur in Angeboten unterstützt.`, type: "breaking"})
|
|
|
|
|
errors.push({
|
|
|
|
|
message: `Position ${row.pos} ist als Optional markiert. Dies wird nur in Angeboten unterstützt.`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (itemInfo.value.type !== "quotes" && row.alternative) {
|
|
|
|
|
errors.push({message: `Position ${row.pos} ist als Alternativ markiert. Dies wird nur in Angeboten unterstützt.`, type: "breaking"})
|
|
|
|
|
errors.push({
|
|
|
|
|
message: `Position ${row.pos} ist als Alternativ markiert. Dies wird nur in Angeboten unterstützt.`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(row.mode === "normal" && !row.product) errors.push({message: `In Position ${row.pos} ist kein Artikel ausgewählt`, type: "breaking"})
|
|
|
|
|
if(row.mode === "service" && !row.service) errors.push({message: `In Position ${row.pos} ist keine Leistung ausgewählt`, type: "breaking"})
|
|
|
|
|
if(row.mode === "title" && !row.text) errors.push({message: `In Position ${row.pos} ist kein Titel hinterlegt`, type: "breaking"})
|
|
|
|
|
if (row.mode === "normal" && !row.product) errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist kein Artikel ausgewählt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (row.mode === "service" && !row.service) errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist keine Leistung ausgewählt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (row.mode === "title" && !row.text) errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist kein Titel hinterlegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
//if(row.mode === "text" && !row.text) errors.push({message: `In einer Freitext Position ist kein Titel hinterlegt`, type: "breaking"})
|
|
|
|
|
if(row.mode === "free" && !row.text) errors.push({message: `In einer freien Position ist kein Titel hinterlegt`, type: "breaking"})
|
|
|
|
|
if (row.mode === "free" && !row.text) errors.push({
|
|
|
|
|
message: `In einer freien Position ist kein Titel hinterlegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (["normal", "service", "free"].includes(row.mode)) {
|
|
|
|
|
|
|
|
|
|
if(!row.taxPercent && typeof row.taxPercent !== "number") errors.push({message: `In Position ${row.pos} ist kein Steuersatz hinterlegt`, type: "breaking"})
|
|
|
|
|
if(!row.price && typeof row.price !== "number") errors.push({message: `In Position ${row.pos} ist kein Preis hinterlegt`, type: "breaking"})
|
|
|
|
|
if (!row.taxPercent && typeof row.taxPercent !== "number") errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist kein Steuersatz hinterlegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (!row.price && typeof row.price !== "number") errors.push({
|
|
|
|
|
message: `In Position ${row.pos} ist kein Preis hinterlegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (!row.unit) errors.push({message: `In Position ${row.pos} ist keine Einheit hinterlegt`, type: "breaking"})
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
@@ -673,13 +707,23 @@ const findDocumentErrors = computed(() => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (itemInfo.value.type === "serialInvoices") {
|
|
|
|
|
if(!itemInfo.value.serialConfig.intervall) errors.push({message: `Kein Intervall für die Ausführung festgelegt`, type: "breaking"})
|
|
|
|
|
if(!itemInfo.value.serialConfig.dateDirection) errors.push({message: `Kein Richtung für die Datierung festgelegt`, type: "breaking"})
|
|
|
|
|
if(!itemInfo.value.serialConfig.firstExecution) errors.push({message: `Kein Datum für die erste Ausführung festgelegt`, type: "breaking"})
|
|
|
|
|
if(!itemInfo.value.serialConfig.executionUntil) errors.push({message: `Kein Datum für die letzte Ausführung festgelegt`, type: "info"})
|
|
|
|
|
if (!itemInfo.value.serialConfig.intervall) errors.push({
|
|
|
|
|
message: `Kein Intervall für die Ausführung festgelegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (!itemInfo.value.serialConfig.dateDirection) errors.push({
|
|
|
|
|
message: `Kein Richtung für die Datierung festgelegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (!itemInfo.value.serialConfig.firstExecution) errors.push({
|
|
|
|
|
message: `Kein Datum für die erste Ausführung festgelegt`,
|
|
|
|
|
type: "breaking"
|
|
|
|
|
})
|
|
|
|
|
if (!itemInfo.value.serialConfig.executionUntil) errors.push({
|
|
|
|
|
message: `Kein Datum für die letzte Ausführung festgelegt`,
|
|
|
|
|
type: "info"
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -756,8 +800,6 @@ const documentTotal = computed(() => {
|
|
|
|
|
console.log(titleSumsTransfer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let totalGross = Number(totalNet.toFixed(2)) + Number(total19.toFixed(2)) + Number(total7.toFixed(2))
|
|
|
|
|
|
|
|
|
|
let totalGrossAlreadyPaid = 0
|
|
|
|
|
@@ -784,13 +826,6 @@ const documentTotal = computed(() => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
titleSums: titleSums,
|
|
|
|
|
titleSumsTransfer: titleSumsTransfer,
|
|
|
|
|
@@ -850,7 +885,6 @@ const documentReport = computed(() => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
//totalHoursSellingPrice += service.sellingPriceComposed.totalWorker * row.quantity
|
|
|
|
|
@@ -943,13 +977,13 @@ const processDieselPosition = () => {
|
|
|
|
|
itemInfo.value.agriculture = {...itemInfo.value.agriculture, ...agricultureData}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getDocumentData = () => {
|
|
|
|
|
const getDocumentData = async () => {
|
|
|
|
|
|
|
|
|
|
let customerData = customers.value.find(i => i.id === itemInfo.value.customer)
|
|
|
|
|
let contactData = dataStore.getContactById(itemInfo.value.contact)
|
|
|
|
|
let businessInfo = profileStore.ownTenant.businessInfo
|
|
|
|
|
let contactData = contacts.value.find(i => i.id === itemInfo.value.contact)
|
|
|
|
|
let businessInfo = auth.activeTenantData.businessInfo
|
|
|
|
|
|
|
|
|
|
if(profileStore.ownTenant.extraModules.includes("agriculture")) {
|
|
|
|
|
if (auth.activeTenantData.extraModules.includes("agriculture")) {
|
|
|
|
|
itemInfo.value.rows.forEach(row => {
|
|
|
|
|
if (row.agriculture && row.agriculture.dieselUsage) {
|
|
|
|
|
row.agriculture.description = `${row.agriculture.dieselUsage} L Diesel zu ${renderCurrency(row.agriculture.dieselPrice)}/L verbraucht ${row.description ? "\n" + row.description : ""}`
|
|
|
|
|
@@ -971,7 +1005,7 @@ const getDocumentData = () => {
|
|
|
|
|
|
|
|
|
|
rows = itemInfo.value.rows.map(row => {
|
|
|
|
|
|
|
|
|
|
let unit = dataStore.units.find(i => i.id === row.unit)
|
|
|
|
|
let unit = units.value.find(i => i.id === row.unit)
|
|
|
|
|
|
|
|
|
|
if (!['pagebreak', 'title'].includes(row.mode)) {
|
|
|
|
|
if (row.agriculture && row.agriculture.description) {
|
|
|
|
|
@@ -1021,7 +1055,9 @@ const getDocumentData = () => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let contactPerson = profileStore.getProfileById(itemInfo.value.contactPerson)
|
|
|
|
|
let contactPerson = (await useNuxtApp().$api(`/api/user/${itemInfo.value.created_by}`, {
|
|
|
|
|
method: "GET"
|
|
|
|
|
})).profile
|
|
|
|
|
|
|
|
|
|
let returnTitleSums = {}
|
|
|
|
|
if (Object.keys(documentTotal.value.titleSums).length > 0) {
|
|
|
|
|
@@ -1097,7 +1133,7 @@ const getDocumentData = () => {
|
|
|
|
|
},*/
|
|
|
|
|
{
|
|
|
|
|
label: "Ansprechpartner",
|
|
|
|
|
content: contactPerson.fullName,
|
|
|
|
|
content: contactPerson.full_name,
|
|
|
|
|
},
|
|
|
|
|
...contactPerson.fixedTel || contactPerson.mobileTel ? [{
|
|
|
|
|
label: "Telefon",
|
|
|
|
|
@@ -1126,15 +1162,15 @@ const getDocumentData = () => {
|
|
|
|
|
label: "Nettobetrag",
|
|
|
|
|
content: renderCurrency(documentTotal.value.totalNet),
|
|
|
|
|
},
|
|
|
|
|
... rows.find(i => i.taxPercent === 19) ? [{
|
|
|
|
|
...rows.find(i => i.taxPercent === 19) && !["13b UStG"].includes(itemInfo.value.taxType) ? [{
|
|
|
|
|
label: `zzgl. 19% USt auf ${renderCurrency(documentTotal.value.totalNet19)}`,
|
|
|
|
|
content: renderCurrency(documentTotal.value.total19),
|
|
|
|
|
}] : [],
|
|
|
|
|
... rows.find(i => i.taxPercent === 7) ? [{
|
|
|
|
|
...rows.find(i => i.taxPercent === 7) && !["13b UStG"].includes(itemInfo.value.taxType) ? [{
|
|
|
|
|
label: `zzgl. 7% USt auf ${renderCurrency(documentTotal.value.totalNet7)}`,
|
|
|
|
|
content: renderCurrency(documentTotal.value.total7),
|
|
|
|
|
}] : [],
|
|
|
|
|
...rows.find(i => i.taxPercent === 0) ? [{
|
|
|
|
|
...rows.find(i => i.taxPercent === 0) && !["13b UStG"].includes(itemInfo.value.taxType) ? [{
|
|
|
|
|
label: `zzgl. 0% USt auf ${renderCurrency(documentTotal.value.totalNet0)}`,
|
|
|
|
|
content: renderCurrency(documentTotal.value.total0),
|
|
|
|
|
}] : [],
|
|
|
|
|
@@ -1169,7 +1205,14 @@ const uri = ref("")
|
|
|
|
|
const generateDocument = async () => {
|
|
|
|
|
const path = letterheads.value.find(i => i.id === itemInfo.value.letterhead).path
|
|
|
|
|
|
|
|
|
|
uri.value = await useFunctions().useCreatePDF(getDocumentData(), path)
|
|
|
|
|
uri.value = await useFunctions().useCreatePDF(await getDocumentData(), path)
|
|
|
|
|
/*uri.value = await useNuxtApp().$api("/api/functions/createinvoicepdf",{
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: {
|
|
|
|
|
invoiceData: await getDocumentData(),
|
|
|
|
|
backgroundPath: path
|
|
|
|
|
}
|
|
|
|
|
})*/
|
|
|
|
|
|
|
|
|
|
showDocument.value = true
|
|
|
|
|
}
|
|
|
|
|
@@ -1256,11 +1299,9 @@ const saveDocument = async (state,resetup = false) => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(profileStore.ownTenant.extraModules.includes("agriculture")) {
|
|
|
|
|
if (auth.activeTenantData.extraModules.includes("agriculture")) {
|
|
|
|
|
itemInfo.value.rows.forEach(row => {
|
|
|
|
|
if (row.agriculture && row.agriculture.dieselUsage) {
|
|
|
|
|
row.agriculture.description = `${row.agriculture.dieselUsage} L Diesel zu ${renderCurrency(row.agriculture.dieselPrice)}/L verbraucht ${row.description ? "\n" + row.description : ""}`
|
|
|
|
|
@@ -1302,6 +1343,7 @@ const saveDocument = async (state,resetup = false) => {
|
|
|
|
|
deliveryDateType: itemInfo.value.deliveryDateType,
|
|
|
|
|
info: {},
|
|
|
|
|
createdBy: itemInfo.value.createdBy,
|
|
|
|
|
created_by: itemInfo.value.created_by,
|
|
|
|
|
title: itemInfo.value.title,
|
|
|
|
|
description: itemInfo.value.description,
|
|
|
|
|
startText: itemInfo.value.startText,
|
|
|
|
|
@@ -1317,9 +1359,10 @@ const saveDocument = async (state,resetup = false) => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (route.params.id) {
|
|
|
|
|
await dataStore.updateItem("createddocuments", {...createData, id: itemInfo.value.id})
|
|
|
|
|
//await dataStore.updateItem("createddocuments", {...createData, id: itemInfo.value.id})
|
|
|
|
|
await useEntities("createddocuments").update(itemInfo.value.id, {...createData, id: itemInfo.value.id})
|
|
|
|
|
} else {
|
|
|
|
|
const data = await dataStore.createNewItem("createddocuments", createData)
|
|
|
|
|
const data = await useEntities("createddocuments").create(createData)
|
|
|
|
|
console.log(data)
|
|
|
|
|
await router.push(`/createDocument/edit/${data.id}`)
|
|
|
|
|
}
|
|
|
|
|
@@ -1346,9 +1389,12 @@ const closeDocument = async () => {
|
|
|
|
|
mappedType = "invoices"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileData.folder = (await supabase.from("folders").select("id").eq("tenant", profileStore.currentTenant).eq("function", mappedType).eq("year",dayjs().format("YYYY")).single()).data.id
|
|
|
|
|
const folders = await useEntities("folders").select()
|
|
|
|
|
console.log(folders)
|
|
|
|
|
fileData.folder = folders.find(i => i.function === mappedType && i.year === Number(dayjs().format("YYYY"))).id
|
|
|
|
|
|
|
|
|
|
let tag = (await supabase.from("filetags").select("id").eq("tenant", profileStore.currentTenant).eq("createddocumenttype", mappedType).single()).data
|
|
|
|
|
const tags = await useEntities("filetags").select()
|
|
|
|
|
fileData.type = tags.find(i => i.createddocumenttype === mappedType).id
|
|
|
|
|
|
|
|
|
|
function dataURLtoFile(dataurl, filename) {
|
|
|
|
|
var arr = dataurl.split(","),
|
|
|
|
|
@@ -1364,7 +1410,7 @@ const closeDocument = async () => {
|
|
|
|
|
|
|
|
|
|
let file = dataURLtoFile(uri.value, `${itemInfo.value.documentNumber}.pdf`)
|
|
|
|
|
|
|
|
|
|
await dataStore.uploadFiles(fileData, [file],[tag.id], true)
|
|
|
|
|
await useFiles().uploadFiles(fileData, [file])
|
|
|
|
|
|
|
|
|
|
await router.push(`/createDocument/show/${itemInfo.value.id}`)
|
|
|
|
|
|
|
|
|
|
@@ -1517,7 +1563,8 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
>
|
|
|
|
|
<template #description>
|
|
|
|
|
<ul class="list-disc ml-5">
|
|
|
|
|
<li v-for="error in findDocumentErrors" :class="[...error.type === 'breaking' ? ['text-rose-600'] : ['dark:text-white','text-black']]">
|
|
|
|
|
<li v-for="error in findDocumentErrors"
|
|
|
|
|
:class="[...error.type === 'breaking' ? ['text-rose-600'] : ['dark:text-white','text-black']]">
|
|
|
|
|
{{ error.message }}
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
@@ -1593,7 +1640,6 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</UFormGroup>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</UCard>
|
|
|
|
|
|
|
|
|
|
</USlideover>
|
|
|
|
|
@@ -1659,7 +1705,9 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
>
|
|
|
|
|
{{ customers.find(i => i.id === itemInfo.customer) ? customers.find(i => i.id === itemInfo.customer).name : "Kein Kunde ausgewählt" }}
|
|
|
|
|
|
|
|
|
|
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform text-gray-400 dark:text-gray-500" :class="['transform rotate-90']" />
|
|
|
|
|
<UIcon name="i-heroicons-chevron-right-20-solid"
|
|
|
|
|
class="w-5 h-5 transition-transform text-gray-400 dark:text-gray-500"
|
|
|
|
|
:class="['transform rotate-90']"/>
|
|
|
|
|
</UButton>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
<EntityModalButtons
|
|
|
|
|
@@ -1708,7 +1756,6 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<UAlert
|
|
|
|
|
v-if="customers.find(i => i.id === itemInfo.customer)"
|
|
|
|
|
class="mt-2"
|
|
|
|
|
@@ -1746,10 +1793,13 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
class="w-full"
|
|
|
|
|
:disabled="!itemInfo.customer"
|
|
|
|
|
>
|
|
|
|
|
<span class="truncate">{{itemInfo.contact ? contacts.find(i => i.id === itemInfo.contact).fullName : "Kein Kontakt ausgewählt"}}</span>
|
|
|
|
|
<span
|
|
|
|
|
class="truncate">{{ itemInfo.contact ? contacts.find(i => i.id === itemInfo.contact).fullName : "Kein Kontakt ausgewählt" }}</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform text-gray-400 dark:text-gray-500" :class="['transform rotate-90']" />
|
|
|
|
|
<UIcon name="i-heroicons-chevron-right-20-solid"
|
|
|
|
|
class="w-5 h-5 transition-transform text-gray-400 dark:text-gray-500"
|
|
|
|
|
:class="['transform rotate-90']"/>
|
|
|
|
|
</UButton>
|
|
|
|
|
<template #label>
|
|
|
|
|
{{ itemInfo.contact ? contacts.find(i => i.id === itemInfo.contact).fullName : "Kein Kontakt ausgewählt" }}
|
|
|
|
|
@@ -1912,9 +1962,9 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
label="Ansprechpartner:"
|
|
|
|
|
>
|
|
|
|
|
<USelectMenu
|
|
|
|
|
:options="profileStore.profiles"
|
|
|
|
|
v-model="itemInfo.contactPerson"
|
|
|
|
|
option-attribute="fullName"
|
|
|
|
|
:options="tenantUsers"
|
|
|
|
|
v-model="itemInfo.created_by"
|
|
|
|
|
option-attribute="full_name"
|
|
|
|
|
value-attribute="id"
|
|
|
|
|
@change="setContactPersonData"
|
|
|
|
|
/>
|
|
|
|
|
@@ -1947,7 +1997,6 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
:search-attributes="['name']"
|
|
|
|
|
class="w-full"
|
|
|
|
|
:disabled="!itemInfo.customer"
|
|
|
|
|
@change="checkForOpenAdvanceInvoices"
|
|
|
|
|
>
|
|
|
|
|
<template #label>
|
|
|
|
|
{{ plants.find(i => i.id === itemInfo.plant) ? plants.find(i => i.id === itemInfo.plant).name : "Kein Objekt ausgewählt" }}
|
|
|
|
|
@@ -1986,13 +2035,13 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
:search-attributes="['name']"
|
|
|
|
|
class="w-full"
|
|
|
|
|
:disabled="!itemInfo.customer"
|
|
|
|
|
@change="checkForOpenAdvanceInvoices"
|
|
|
|
|
>
|
|
|
|
|
<template #label>
|
|
|
|
|
{{ itemInfo.project ? projects.find(i => i.id === itemInfo.project).name : "Kein Projekt ausgewählt" }}
|
|
|
|
|
</template>
|
|
|
|
|
<template #option="{option: project}">
|
|
|
|
|
{{dataStore.getCustomerById(project.customer).name}} - {{project.name}}
|
|
|
|
|
{{ customers.find(i => i.id === project.customer) ? customers.find(i => i.id === project.customer).name : "" }}
|
|
|
|
|
- {{ project.name }}
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
<UButton
|
|
|
|
|
@@ -2121,7 +2170,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
{{ option.name }} - {{ option.text }}
|
|
|
|
|
</template>
|
|
|
|
|
<template #label>
|
|
|
|
|
{{dataStore.texttemplates.find(i => i.text === itemInfo.startText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)) ? dataStore.texttemplates.find(i => i.text === itemInfo.startText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)).name : "Keine Vorlage ausgewählt oder Vorlage verändert"}}
|
|
|
|
|
{{ texttemplates.find(i => i.text === itemInfo.startText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)) ? texttemplates.find(i => i.text === itemInfo.startText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)).name : "Keine Vorlage ausgewählt oder Vorlage verändert" }}
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
</UFormGroup>
|
|
|
|
|
@@ -2194,7 +2243,8 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
</td>
|
|
|
|
|
<td
|
|
|
|
|
v-if="!['pagebreak','text'].includes(row.mode)"
|
|
|
|
|
>{{row.pos}}</td>
|
|
|
|
|
>{{ row.pos }}
|
|
|
|
|
</td>
|
|
|
|
|
<td
|
|
|
|
|
class="w-120"
|
|
|
|
|
v-if="row.mode === 'free'"
|
|
|
|
|
@@ -2225,7 +2275,9 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
@change="setRowData(row)"
|
|
|
|
|
>
|
|
|
|
|
<template #label>
|
|
|
|
|
<span class="truncate">{{products.find(i => i.id === row.product) ? products.find(i => i.id === row.product).name : "Kein Produkt ausgewählt" }}</span>
|
|
|
|
|
<span class="truncate">{{
|
|
|
|
|
products.find(i => i.id === row.product) ? products.find(i => i.id === row.product).name : "Kein Produkt ausgewählt"
|
|
|
|
|
}}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
<EntityModalButtons
|
|
|
|
|
@@ -2295,7 +2347,9 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
@change="setRowData(row)"
|
|
|
|
|
>
|
|
|
|
|
<template #label>
|
|
|
|
|
<span class="truncate">{{services.find(i => i.id === row.service) ? services.find(i => i.id === row.service).name : "Keine Leistung ausgewählt" }}</span>
|
|
|
|
|
<span class="truncate">{{
|
|
|
|
|
services.find(i => i.id === row.service) ? services.find(i => i.id === row.service).name : "Keine Leistung ausgewählt"
|
|
|
|
|
}}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
<EntityModalButtons
|
|
|
|
|
@@ -2351,7 +2405,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
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' "
|
|
|
|
|
:step="units.find(i => i.id === row.unit) ? units.find(i => i.id === row.unit).step : '1' "
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
</td>
|
|
|
|
|
@@ -2362,12 +2416,12 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<USelectMenu
|
|
|
|
|
v-model="row.unit"
|
|
|
|
|
:disabled="itemInfo.type === 'cancellationInvoices'"
|
|
|
|
|
:options="dataStore.units"
|
|
|
|
|
:options="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"}}
|
|
|
|
|
{{ units.find(i => i.id === row.unit) ? units.find(i => i.id === row.unit).name : "Keine Einheit gewählt" }}
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
</td>
|
|
|
|
|
@@ -2462,7 +2516,8 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">
|
|
|
|
|
Zeile bearbeiten
|
|
|
|
|
</h3>
|
|
|
|
|
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="row.showEdit = false" />
|
|
|
|
|
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1"
|
|
|
|
|
@click="row.showEdit = false"/>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<InputGroup>
|
|
|
|
|
@@ -2473,7 +2528,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
<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' "
|
|
|
|
|
:step="units.find(i => i.id === row.unit) ? units.find(i => i.id === row.unit).step : '1' "
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
</UFormGroup>
|
|
|
|
|
@@ -2483,13 +2538,13 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
>
|
|
|
|
|
<USelectMenu
|
|
|
|
|
v-model="row.unit"
|
|
|
|
|
:options="dataStore.units"
|
|
|
|
|
:options="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"}}
|
|
|
|
|
{{ units.find(i => i.id === row.unit) ? units.find(i => i.id === row.unit).name : "Keine Einheit gewählt" }}
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
</UFormGroup>
|
|
|
|
|
@@ -2949,7 +3004,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|
|
|
|
{{option.name}} - {{option.text}}
|
|
|
|
|
</template>
|
|
|
|
|
<template #label>
|
|
|
|
|
{{dataStore.texttemplates.find(i => i.text === itemInfo.endText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)) ? dataStore.texttemplates.find(i => i.text === itemInfo.endText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)).name : "Keine Vorlage ausgewählt oder Vorlage verändert"}}
|
|
|
|
|
{{texttemplates.find(i => i.text === itemInfo.endText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)) ? texttemplates.find(i => i.text === itemInfo.endText && (itemInfo.type === "serialInvoices" ? i.documentType === "invoices" : i.documentType === itemInfo.type)).name : "Keine Vorlage ausgewählt oder Vorlage verändert"}}
|
|
|
|
|
</template>
|
|
|
|
|
</USelectMenu>
|
|
|
|
|
</UFormGroup>
|
|
|
|
|
|