diff --git a/app.vue b/app.vue index b987c6b..f2f0d80 100644 --- a/app.vue +++ b/app.vue @@ -1,12 +1,7 @@ @@ -139,7 +133,7 @@ const filteredRows = computed(() => { /> + {{dataType.labelSingle}} @@ -190,9 +184,11 @@ const filteredRows = computed(() => { /> diff --git a/components/EntityShow.vue b/components/EntityShow.vue index 6f5291f..dc3dec8 100644 --- a/components/EntityShow.vue +++ b/components/EntityShow.vue @@ -158,22 +158,6 @@ const onTabChange = (index) => { v-else-if="!props.inModal && platform === 'mobile'" :ui="{center: 'flex items-stretch gap-1.5 min-w-0'}" > - @@ -226,6 +210,7 @@ const onTabChange = (index) => { @updateNeeded="emit('updateNeeded')" :platform="platform" /> + { @updateNeeded="emit('updateNeeded')" :platform="platform" /> - - { v-else-if="tab.label === 'Zeiten'" :platform="platform" /> - - diff --git a/components/EntityShowSub.vue b/components/EntityShowSub.vue index 75ecb8f..174fbe8 100644 --- a/components/EntityShowSub.vue +++ b/components/EntityShowSub.vue @@ -27,8 +27,6 @@ const props = defineProps({ let type = ref("") - - const dataStore = useDataStore() const tempStore = useTempStore() @@ -42,6 +40,7 @@ const columns = computed(() => dataType.templateColumns.filter((column) => !colu const loaded = ref(false) const setup = () => { + if(!props.type && props.tabLabel ) { if(props.tabLabel === "Aufgaben") { type.value = "tasks" diff --git a/components/EntityShowSubCreatedDocuments.vue b/components/EntityShowSubCreatedDocuments.vue index 3956695..751b406 100644 --- a/components/EntityShowSubCreatedDocuments.vue +++ b/components/EntityShowSubCreatedDocuments.vue @@ -61,7 +61,8 @@ const router = useRouter() const createddocuments = ref([]) const setup = async () => { - createddocuments.value = (await useSupabaseSelect("createddocuments")).filter(i => !i.archived) + //createddocuments.value = (await useSupabaseSelect("createddocuments")).filter(i => !i.archived) + createddocuments.value = (await useEntities("createddocuments").select()).filter(i => !i.archived) } setup() @@ -150,6 +151,7 @@ const selectItem = (item) => { Ausgangsbelege + { if(props.item.files) { - availableFiles.value = await files.selectSomeDocuments(props.item.files.map(i => i.id)) || [] + availableFiles.value = (await files.selectSomeDocuments(props.item.files.map(i => i.id))) || [] } } @@ -51,12 +51,12 @@ setup() @uploadFinished="emit('updateNeeded')" /> - + diff --git a/components/EntityTable.vue b/components/EntityTable.vue index 808de55..c243fc8 100644 --- a/components/EntityTable.vue +++ b/components/EntityTable.vue @@ -26,7 +26,6 @@ } } }) - const props = defineProps({ rows: { type: Array, @@ -40,9 +39,16 @@ type: { type: String, required: true, + }, + loading: { + type: Boolean, + required: true, + default: false } }) + const emit = defineEmits(["sort"]); + const dataStore = useDataStore() const router = useRouter() @@ -50,12 +56,20 @@ const dataType = dataStore.dataTypes[props.type] const selectedItem = ref(0) - + const sort = ref({ + column: dataType.supabaseSortColumn || "date", + direction: 'desc' + }) --> diff --git a/components/HistoryDisplay.vue b/components/HistoryDisplay.vue index cf60788..a9461fc 100644 --- a/components/HistoryDisplay.vue +++ b/components/HistoryDisplay.vue @@ -14,8 +14,9 @@ const props = defineProps({ default: false } }) -const profileStore = useProfileStore() -const supabase = useSupabaseClient() + +const auth = useAuthStore() + const toast = useToast() const showAddHistoryItemModal = ref(false) const colorMode = useColorMode() @@ -28,11 +29,12 @@ const setup = async () => { if(await useCapacitor().getIsPhone()) platform.value = "mobile" if(props.type && props.elementId){ - items.value = (await supabase.from("historyitems").select().eq(props.type,props.elementId).order("created_at",{ascending: true})).data || [] - } else { + //items.value = (await supabase.from("historyitems").select().eq(props.type,props.elementId).order("created_at",{ascending: true})).data || [] + items.value = await useNuxtApp().$api(`/api/resource/${props.type}/${props.elementId}/history`) + } /*else { items.value = (await supabase.from("historyitems").select().order("created_at",{ascending: true})).data || [] - } + }*/ } setup() @@ -40,55 +42,24 @@ setup() const addHistoryItemData = ref({ - text: "", - config: { - type: props.type, - id: props.elementId - } + text: "" }) const addHistoryItem = async () => { - console.log(addHistoryItemData.value) - addHistoryItemData.value.createdBy = profileStore.activeProfile.id - addHistoryItemData.value[props.type] = props.elementId + const res = await useNuxtApp().$api(`/api/resource/${props.type}/${props.elementId}/history`, { + method: "POST", + body: addHistoryItemData.value + }) - const {data,error} = await supabase - .from("historyitems") - .insert([{...addHistoryItemData.value, tenant: profileStore.currentTenant}]) - .select() - if(error) { - console.log(error) - } else { - if(addHistoryItemData.value.text.includes("@")){ - let usernames = [...addHistoryItemData.value.text.matchAll(/@(\S*)/gm)] - const {data:profiles} = await supabase.from("profiles").select("id,username") - let notifications = usernames.map(i => { - let rawUsername = i[1] + addHistoryItemData.value = {} + toast.add({title: "Eintrag erfolgreich erstellt"}) + showAddHistoryItemModal.value = false + await setup() - return { - tenant: profileStore.currentTenant, - profile: profiles.find(x => x.username === rawUsername).id, - initiatingProfile: profileStore.activeProfile.id, - title: "Sie wurden im Logbuch erwähnt", - link: `/${props.type}s/show/${props.elementId}`, - message: addHistoryItemData.value.text - } - }) - - console.log(notifications) - - const {error} = await supabase.from("notifications").insert(notifications) - } - - addHistoryItemData.value = {} - toast.add({title: "Eintrag erfolgreich erstellt"}) - showAddHistoryItemModal.value = false - await setup() - } } @@ -170,15 +141,15 @@ const renderText = (text) => { />
-

{{profileStore.getProfileById(item.createdBy) ? profileStore.getProfileById(item.createdBy).fullName : ""}}

+

{{item.created_by_profile?.full_name}}

FEDEO Bot


{{dayjs(item.created_at).format("DD.MM.YY HH:mm")}} diff --git a/components/MainNav.vue b/components/MainNav.vue index a2307b8..4d16dd6 100644 --- a/components/MainNav.vue +++ b/components/MainNav.vue @@ -1,19 +1,25 @@ \ No newline at end of file diff --git a/components/ProfileDropdown.vue b/components/ProfileDropdown.vue deleted file mode 100644 index a5c7281..0000000 --- a/components/ProfileDropdown.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - \ No newline at end of file diff --git a/components/TenantDropdown.vue b/components/TenantDropdown.vue new file mode 100644 index 0000000..039860a --- /dev/null +++ b/components/TenantDropdown.vue @@ -0,0 +1,27 @@ + + + \ No newline at end of file diff --git a/components/UserDropdown.vue b/components/UserDropdown.vue index b0b57f0..7d15569 100644 --- a/components/UserDropdown.vue +++ b/components/UserDropdown.vue @@ -1,4 +1,5 @@ \ No newline at end of file diff --git a/middleware/auth.global.ts b/middleware/auth.global.ts new file mode 100644 index 0000000..8d0d033 --- /dev/null +++ b/middleware/auth.global.ts @@ -0,0 +1,17 @@ +export default defineNuxtRouteMiddleware(async (to, from) => { + const auth = useAuthStore() + + + + // Wenn nicht eingeloggt → auf /login (außer er will schon dahin) + if (!auth.user && !["/login", "/password-reset"].includes(to.path)) { + return navigateTo("/login") + } + + // Wenn eingeloggt → von /login auf /dashboard umleiten + if (auth.user && !auth.user?.must_change_password && to.path === "/login") { + return navigateTo("/") + } else if(auth.user && auth.user.must_change_password && to.path !== "/password-change") { + return navigateTo("/password-change") + } +}) \ No newline at end of file diff --git a/middleware/auth.ts b/middleware/auth.ts deleted file mode 100644 index 0bdf3b3..0000000 --- a/middleware/auth.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default defineNuxtRouteMiddleware((to, _from) => { - const user = useSupabaseUser() - const router = useRouter() - if (!user.value) { - //useCookie('redirect', { path: '/' }).value = to.fullPath - return router.push("/login") - } -}) \ No newline at end of file diff --git a/middleware/redirectToMobileIndex.ts b/middleware/redirectToMobileIndex.ts deleted file mode 100644 index 6c4b111..0000000 --- a/middleware/redirectToMobileIndex.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default defineNuxtRouteMiddleware(async (to, _from) => { - const router = useRouter() - - console.log(await useCapacitor().getIsPhone()) - - if(await useCapacitor().getIsPhone()) { - return router.push('/mobile') - } -}) \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts index 9f690eb..873a7cf 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -34,7 +34,8 @@ export default defineNuxtConfig({ supabase: { key: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo", - url: "https://uwppvcxflrcsibuzsbil.supabase.co" + url: "https://uwppvcxflrcsibuzsbil.supabase.co", + redirect:false }, vite: { diff --git a/pages/accounts/index.vue b/pages/accounts/index.vue index 30038a6..e955732 100644 --- a/pages/accounts/index.vue +++ b/pages/accounts/index.vue @@ -1,11 +1,6 @@ - - - - \ No newline at end of file diff --git a/pages/contacts/[mode]/[[id]].vue b/pages/contacts/[mode]/[[id]].vue deleted file mode 100644 index 65f491f..0000000 --- a/pages/contacts/[mode]/[[id]].vue +++ /dev/null @@ -1,340 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/contacts/index.vue b/pages/contacts/index.vue deleted file mode 100644 index a1cf1aa..0000000 --- a/pages/contacts/index.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/createDocument/edit/[[id]].vue b/pages/createDocument/edit/[[id]].vue index 2f8b5b4..1e0cf78 100644 --- a/pages/createDocument/edit/[[id]].vue +++ b/pages/createDocument/edit/[[id]].vue @@ -11,11 +11,10 @@ const route = useRoute() const router = useRouter() const supabase = useSupabaseClient() const modal = useModal() +const auth = useAuthStore() + -definePageMeta({ - middleware: "auth" -}) const itemInfo = ref({ @@ -37,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, @@ -63,7 +60,7 @@ const itemInfo = ref({ usedAdvanceInvoices: [] }) -console.log(profileStore.ownTenant) +console.log(auth.activeTenantData) const letterheads = ref([]) const createddocuments = ref([]) @@ -78,61 +75,66 @@ const selectedServicecategorie = ref(null) const customers = ref([]) const contacts = ref([]) const texttemplates = ref([]) +const units = ref([]) +const tenantUsers = ref([]) const loaded = ref(false) const setupPage = async () => { - letterheads.value = (await useSupabaseSelect("letterheads","*")).filter(i => i.documentTypes.length === 0 || i.documentTypes.includes(itemInfo.value.type)) - createddocuments.value = (await useSupabaseSelect("createddocuments","*")) - projects.value = (await useSupabaseSelect("projects","*")) - plants.value = (await useSupabaseSelect("plants","*")) - services.value = (await useSupabaseSelect("services","*")) - servicecategories.value = (await useSupabaseSelect("servicecategories","*")) - products.value = (await useSupabaseSelect("products","*")) - productcategories.value = (await useSupabaseSelect("productcategories","*")) - customers.value = (await useSupabaseSelect("customers","*","customerNumber")) - contacts.value = (await useSupabaseSelect("contacts","*")) - texttemplates.value = (await useSupabaseSelect("texttemplates","*")) - if(productcategories.value.length > 0) selectedProductcategorie.value = productcategories.value[0].id - if(servicecategories.value.length > 0) selectedServicecategorie.value = servicecategories.value[0].id + letterheads.value = (await useEntities("letterheads").select("*")).filter(i => i.documentTypes.length === 0 || i.documentTypes.includes(itemInfo.value.type)) + createddocuments.value = await useEntities("createddocuments").select("*") + projects.value = await useEntities("projects").select("*") + plants.value = await useEntities("plants").select("*") + services.value = await useEntities("services").select("*") + servicecategories.value = await useEntities("servicecategories").select("*") + products.value = await useEntities("products").select("*") + productcategories.value = await useEntities("productcategories").select("*") + customers.value = await useEntities("customers").select("*", "customerNumber") + contacts.value = await useEntities("contacts").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) { - itemInfo.value = await useSupabaseSelectSingle("createddocuments", route.params.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" + if (!itemInfo.value.deliveryDateType) itemInfo.value.deliveryDateType = "Lieferdatum" - if(itemInfo.value.rows.find(i => i.agriculture)) { + if (itemInfo.value.rows.find(i => i.agriculture)) { processDieselPosition() } } - if(route.query) { - if(route.query.type) itemInfo.value.type = route.query.type + if (route.query) { + if (route.query.type) itemInfo.value.type = route.query.type - if(!itemInfo.value.startText && !itemInfo.value.endText) { + if (!itemInfo.value.startText && !itemInfo.value.endText) { setDocumentTypeConfig(true) } else { setDocumentTypeConfig(false) } - setContactPersonData() - if(route.query.linkedDocuments) { + if (route.query.linkedDocuments) { console.log(route.query.loadMode) - if(route.query.loadMode === "deliveryNotes") { - let linkedDocuments = (await supabase.from("createddocuments").select().in("id",JSON.parse(route.query.linkedDocuments))).data + if (route.query.loadMode === "deliveryNotes") { + let linkedDocuments = (await supabase.from("createddocuments").select().in("id", JSON.parse(route.query.linkedDocuments))).data //TODO: Implement Checking for Same Customer, Contact and Project @@ -148,15 +150,15 @@ const setupPage = async () => { linkedDocuments.forEach(doc => { let lastId = 0 itemInfo.value.rows.forEach(row => { - if(row.id > lastId) lastId = row.id + 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 + 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(), + id: uuidv4(), mode: "title", text: `${doc.title} vom ${dayjs(doc.documentDate).format("DD.MM.YYYY")}` }, @@ -181,7 +183,7 @@ const setupPage = async () => { console.log(linkedDocuments) - if(linkedDocuments.find(i => i.rows.find( x => x.agriculture.dieselUsage))){ + if (linkedDocuments.find(i => i.rows.find(x => x.agriculture.dieselUsage))) { console.log("has diesel") //Remove Existing Total Diesel Pos @@ -191,7 +193,7 @@ const setupPage = async () => { //Add Total Title itemInfo.value.rows.push({ - id:uuidv4(), + id: uuidv4(), mode: "title", text: "Allgemein" }) @@ -199,8 +201,8 @@ const setupPage = async () => { processDieselPosition() } - } else if(route.query.loadMode === "finalInvoice") { - let linkedDocuments = (await supabase.from("createddocuments").select().in("id",JSON.parse(route.query.linkedDocuments))).data + } else if (route.query.loadMode === "finalInvoice") { + let linkedDocuments = (await supabase.from("createddocuments").select().in("id", JSON.parse(route.query.linkedDocuments))).data //TODO: Implement Checking for Same Customer, Contact and Project @@ -213,7 +215,7 @@ const setupPage = async () => { setCustomerData() for await (const doc of linkedDocuments.filter(i => i.type === "confirmationOrders")) { - let linkedDocument = await useSupabaseSelectSingle("createddocuments",doc.id) + let linkedDocument = await useEntities("createddocuments").selectSingle(doc.id) itemInfo.value.rows.push({ mode: "title", @@ -224,7 +226,7 @@ const setupPage = async () => { } for await (const doc of linkedDocuments.filter(i => i.type === "quotes")) { - let linkedDocument = await useSupabaseSelectSingle("createddocuments",doc.id) + let linkedDocument = await useEntities("createddocuments").selectSingle(doc.id) itemInfo.value.rows.push({ mode: "title", @@ -247,7 +249,7 @@ const setupPage = async () => { taxPercent: 19, // TODO TAX PERCENTAGE discountPercent: 0, unit: 10, - inputPrice: useSum().getCreatedDocumentSumDetailed(doc).totalNet *-1, + inputPrice: useSum().getCreatedDocumentSumDetailed(doc).totalNet * -1, linkedEntitys: [ { type: "createddocuments", @@ -266,54 +268,49 @@ const setupPage = async () => { setPosNumbers() - - } - - } - if(route.query.linkedDocument) { + if (route.query.linkedDocument) { itemInfo.value.linkedDocument = route.query.linkedDocument - let linkedDocument = await useSupabaseSelectSingle("createddocuments",itemInfo.value.linkedDocument) + let linkedDocument = await useEntities("createddocuments").selectSingle(itemInfo.value.linkedDocument) - - if(route.query.optionsToImport) { + if (route.query.optionsToImport) { //Import only true let optionsToImport = JSON.parse(route.query.optionsToImport) console.log(optionsToImport) console.log(linkedDocument) - if(optionsToImport.taxType) itemInfo.value.taxType = linkedDocument.taxType - if(optionsToImport.customer) itemInfo.value.customer = linkedDocument.customer - if(optionsToImport.letterhead) itemInfo.value.letterhead = linkedDocument.letterhead - if(optionsToImport.contact) itemInfo.value.contact = linkedDocument.contact - if(optionsToImport.deliveryDateType) itemInfo.value.deliveryDateType = linkedDocument.deliveryDateType - if(optionsToImport.deliveryDate) itemInfo.value.deliveryDate = linkedDocument.deliveryDate - if(optionsToImport.deliveryDateEnd) itemInfo.value.deliveryDateEnd = linkedDocument.deliveryDateEnd - if(optionsToImport.documentDate) itemInfo.value.documentDate = linkedDocument.documentDate - if(optionsToImport.paymentDays) itemInfo.value.paymentDays = linkedDocument.paymentDays - if(optionsToImport.customSurchargePercentage) itemInfo.value.customSurchargePercentage = linkedDocument.customSurchargePercentage - if(optionsToImport.contactPerson) itemInfo.value.contactPerson = linkedDocument.contactPerson - if(optionsToImport.plant) itemInfo.value.plant = linkedDocument.plant - if(optionsToImport.project) itemInfo.value.project = linkedDocument.project - if(optionsToImport.title) itemInfo.value.title = linkedDocument.title - if(optionsToImport.description) itemInfo.value.description = linkedDocument.description - if(optionsToImport.startText) itemInfo.value.startText = linkedDocument.startText - if(optionsToImport.rows) itemInfo.value.rows = linkedDocument.rows - if(optionsToImport.endText) itemInfo.value.endText = linkedDocument.endText + if (optionsToImport.taxType) itemInfo.value.taxType = linkedDocument.taxType + if (optionsToImport.customer) itemInfo.value.customer = linkedDocument.customer + if (optionsToImport.letterhead) itemInfo.value.letterhead = linkedDocument.letterhead + if (optionsToImport.contact) itemInfo.value.contact = linkedDocument.contact + if (optionsToImport.deliveryDateType) itemInfo.value.deliveryDateType = linkedDocument.deliveryDateType + if (optionsToImport.deliveryDate) itemInfo.value.deliveryDate = linkedDocument.deliveryDate + if (optionsToImport.deliveryDateEnd) itemInfo.value.deliveryDateEnd = linkedDocument.deliveryDateEnd + if (optionsToImport.documentDate) itemInfo.value.documentDate = linkedDocument.documentDate + if (optionsToImport.paymentDays) itemInfo.value.paymentDays = linkedDocument.paymentDays + if (optionsToImport.customSurchargePercentage) itemInfo.value.customSurchargePercentage = linkedDocument.customSurchargePercentage + if (optionsToImport.contactPerson) itemInfo.value.contactPerson = linkedDocument.contactPerson + if (optionsToImport.plant) itemInfo.value.plant = linkedDocument.plant + if (optionsToImport.project) itemInfo.value.project = linkedDocument.project + if (optionsToImport.title) itemInfo.value.title = linkedDocument.title + if (optionsToImport.description) itemInfo.value.description = linkedDocument.description + if (optionsToImport.startText) itemInfo.value.startText = linkedDocument.startText + if (optionsToImport.rows) itemInfo.value.rows = linkedDocument.rows + if (optionsToImport.endText) itemInfo.value.endText = linkedDocument.endText } else { // Import all - if(process.dev) console.log(linkedDocument) + if (process.dev) console.log(linkedDocument) itemInfo.value.taxType = linkedDocument.taxType itemInfo.value.customer = linkedDocument.customer - await setCustomerData(null,true) + await setCustomerData(null, true) itemInfo.value.letterhead = linkedDocument.letterhead itemInfo.value.contact = linkedDocument.contact itemInfo.value.deliveryDateType = linkedDocument.deliveryDateType @@ -333,10 +330,9 @@ const setupPage = async () => { } - checkCompatibilityWithInputPrice() - if(route.query.loadMode === "storno") { + if (route.query.loadMode === "storno") { itemInfo.value.rows.forEach(row => { row.price = row.price * -1 }) @@ -345,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')}` @@ -358,69 +353,52 @@ const setupPage = async () => { } - if(route.query.project) { + if (route.query.project) { itemInfo.value.project = Number(route.query.project) - let project = await useSupabaseSelectSingle("projects",itemInfo.value.project) + let project = await useEntities("projects").selectSingle(itemInfo.value.project) - if(!itemInfo.value.description){ + if (!itemInfo.value.description) { itemInfo.value.description = project.customerRef } - checkForOpenAdvanceInvoices() } - if(route.query.plant) { + if (route.query.plant) { itemInfo.value.plant = Number(route.query.plant) } - if(route.query.contact) itemInfo.value.contact = Number(route.query.contact) - if(route.query.customer) { + if (route.query.contact) itemInfo.value.contact = Number(route.query.contact) + if (route.query.customer) { itemInfo.value.customer = Number(route.query.customer) setCustomerData() } } - //if(itemInfo.value.project) checkForOpenAdvanceInvoices() loaded.value = true } setupPage() -const openAdvanceInvoices = ref([]) -const checkForOpenAdvanceInvoices = async () => { - console.log("Check for Open Advance Invoices") - 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, ...usedAdvanceInvoices.filter(i => !data.find(x => x.id === i.id))] - -} - -const addAdvanceInvoiceToInvoice = (advanceInvoice) => { - itemInfo.value.usedAdvanceInvoices.push(advanceInvoice) -} const setDocumentTypeConfig = (withTexts = false) => { - if(itemInfo.value.type === "invoices" ||itemInfo.value.type === "advanceInvoices" || itemInfo.value.type === "serialInvoices"|| itemInfo.value.type === "cancellationInvoices") { + 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") { + } 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") { + } else if (itemInfo.value.type === "deliveryNotes") { itemInfo.value.documentNumberTitle = "Lieferscheinnummer" itemInfo.value.title = `Lieferschein-Nr. ${itemInfo.value.documentNumber ? itemInfo.value.documentNumber : "XXXX"}` - } else if(itemInfo.value.type === "confirmationOrders") { + } 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) { + 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 //itemInfo.value.startText = texttemplates.value.find(i => i.documentType === itemInfo.value.type && i.default && i.pos === "startText").text @@ -429,7 +407,7 @@ const setDocumentTypeConfig = (withTexts = false) => { itemInfo.value.letterhead = letterheads.value[0].id - if(itemInfo.value.type === "advanceInvoices" && !itemInfo.value.rows.find(i => i.text === "Abschlagszahlung")) { + if (itemInfo.value.type === "advanceInvoices" && !itemInfo.value.rows.find(i => i.text === "Abschlagszahlung")) { itemInfo.value.rows.push({ @@ -450,11 +428,11 @@ const setDocumentTypeConfig = (withTexts = false) => { } const setTaxType = () => { - if(itemInfo.value.taxType === "19 UStG") { + if (itemInfo.value.taxType === "19 UStG") { itemInfo.value.rows.forEach(row => { row.taxPercent = 0 }) - } else if(itemInfo.value.taxType === "12.3 UStG") { + } else if (itemInfo.value.taxType === "12.3 UStG") { itemInfo.value.rows.forEach(row => { row.taxPercent = 0 }) @@ -463,30 +441,30 @@ const setTaxType = () => { const setCustomerData = async (customerId, loadOnlyAdress = false) => { - if(customerId){ + if (customerId) { itemInfo.value.customer = customerId } - customers.value = await useSupabaseSelect("customers") + customers.value = await useEntities("customers").select() let customer = customers.value.find(i => i.id === itemInfo.value.customer) console.log(customer) itemInfo.value.contact = null - if(customer) { + if (customer) { itemInfo.value.address.street = customer.infoData.street itemInfo.value.address.zip = customer.infoData.zip itemInfo.value.address.city = customer.infoData.city itemInfo.value.address.special = customer.infoData.special - if(!loadOnlyAdress && customer.customPaymentDays) itemInfo.value.paymentDays = customer.customPaymentDays + if (!loadOnlyAdress && customer.customPaymentDays) itemInfo.value.paymentDays = customer.customPaymentDays - if(!loadOnlyAdress && customer.customSurchargePercentage) { + if (!loadOnlyAdress && customer.customSurchargePercentage) { itemInfo.value.customSurchargePercentage = customer.customSurchargePercentage updateCustomSurcharge() } - if(!loadOnlyAdress && contacts.value.filter(i => i.customer === itemInfo.value.customer).length === 1) { + if (!loadOnlyAdress && contacts.value.filter(i => i.customer === itemInfo.value.customer).length === 1) { itemInfo.value.contact = contacts.value.filter(i => i.customer === itemInfo.value.customer)[0].id } @@ -496,10 +474,12 @@ const setCustomerData = async (customerId, loadOnlyAdress = false) => { } const setContactPersonData = async () => { - //console.log(itemInfo.value.contactPerson) - 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 @@ -512,17 +492,17 @@ const advanceInvoiceData = ref({ part: 0 }) const importPositions = () => { - if(itemInfo.value.type === 'advanceInvoices') { - if(advanceInvoiceData.value.totalSumNet !== 0 && advanceInvoiceData.value.partPerPecentage !== 0 && advanceInvoiceData.value.part !== 0) { + if (itemInfo.value.type === 'advanceInvoices') { + if (advanceInvoiceData.value.totalSumNet !== 0 && advanceInvoiceData.value.partPerPecentage !== 0 && advanceInvoiceData.value.part !== 0) { showAdvanceInvoiceCalcModal.value = false let lastId = 0 itemInfo.value.rows.forEach(row => { - if(row.id > lastId) lastId = row.id + if (row.id > lastId) lastId = row.id }) itemInfo.value.rows.push({ - id: lastId +1, + id: lastId + 1, mode: "free", text: "Abschlagszahlung", quantity: 1, @@ -540,27 +520,27 @@ const importPositions = () => { } const getRowAmount = (row) => { - return String(Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(2)).replace('.',',') + return String(Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) / 100)).toFixed(2)).replace('.', ',') } const getRowAmountUndiscounted = (row) => { - return String(Number(Number(row.quantity) * Number(row.price)).toFixed(2)).replace('.',',') + return String(Number(Number(row.quantity) * Number(row.price)).toFixed(2)).replace('.', ',') } const addPosition = (mode) => { let lastId = 0 itemInfo.value.rows.forEach(row => { - if(row.id > lastId) lastId = row.id + if (row.id > lastId) lastId = row.id }) let taxPercentage = 19 - if(['13b UStG','19 UStG','12.3 UStG'].includes(itemInfo.value.taxType)) { + if (['13b UStG', '19 UStG', '12.3 UStG'].includes(itemInfo.value.taxType)) { taxPercentage = 0 } - if(mode === 'free'){ + if (mode === 'free') { let rowData = { id: uuidv4(), mode: "free", @@ -574,9 +554,9 @@ 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'){ + } else if (mode === 'normal') { itemInfo.value.rows.push({ id: uuidv4(), mode: "normal", @@ -588,7 +568,7 @@ const addPosition = (mode) => { unit: 1, linkedEntitys: [] }) - } else if(mode === 'service'){ + } else if (mode === 'service') { let rowData = { id: uuidv4(), mode: "service", @@ -602,20 +582,20 @@ const addPosition = (mode) => { } //Push Agriculture Holder only if Module is activated - itemInfo.value.rows.push({...rowData, ...profileStore.ownTenant.extraModules.includes("agriculture") ? {agriculture: {}}: {}}) - } else if(mode === "pagebreak") { + itemInfo.value.rows.push({...rowData, ...auth.activeTenantData.extraModules.includes("agriculture") ? {agriculture: {}} : {}}) + } else if (mode === "pagebreak") { itemInfo.value.rows.push({ id: uuidv4(), mode: "pagebreak", linkedEntitys: [] }) - } else if(mode === "title") { + } else if (mode === "title") { itemInfo.value.rows.push({ id: uuidv4(), mode: "title", linkedEntitys: [] }) - } else if(mode === "text") { + } else if (mode === "text") { itemInfo.value.rows.push({ id: uuidv4(), mode: "text", @@ -636,69 +616,115 @@ const removePosition = (id) => { } const findDocumentErrors = computed(() => { - let errors = [] + let errors = [] - 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.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.project === null) errors.push({message: "Es ist kein Projekt ausgewählt", type: "info"}) + 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 (['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.rows.length === 0) { - errors.push({message: "Es sind keine Positionen angegeben", type: "breaking"}) - } else { - itemInfo.value.rows.forEach(row => { + if (itemInfo.value.rows.length === 0) { + errors.push({message: "Es sind keine Positionen angegeben", type: "breaking"}) + } else { + 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"}) - } + 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" + }) + } - 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"}) - } - - 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(["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.unit) errors.push({message: `In Position ${row.pos} ist keine Einheit hinterlegt`, type: "breaking"}) - - } - - if(row.agriculture){ - if(row.agriculture.dieselUsage && (!row.agriculture.dieselPrice && typeof row.agriculture.dieselPrice !== "number")) { - errors.push({message: `In Position ${row.pos} ist kein Dieselpreis hinterlegt`, type: "breaking"}) - } else if(row.agriculture.dieselUsage && row.agriculture.dieselPrice === 0) { - errors.push({message: `In Position ${row.pos} ist 0,00 € als Dieselpreis hinterlegt`, type: "info"}) - } - } + 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" + }) + } + 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 (["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.unit) errors.push({message: `In Position ${row.pos} ist keine Einheit hinterlegt`, type: "breaking"}) + + } + + if (row.agriculture) { + if (row.agriculture.dieselUsage && (!row.agriculture.dieselPrice && typeof row.agriculture.dieselPrice !== "number")) { + errors.push({message: `In Position ${row.pos} ist kein Dieselpreis hinterlegt`, type: "breaking"}) + } else if (row.agriculture.dieselUsage && row.agriculture.dieselPrice === 0) { + errors.push({message: `In Position ${row.pos} ist 0,00 € als Dieselpreis hinterlegt`, type: "info"}) + } + } + + }) + } - - - 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.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" + }) + } return errors.sort((a) => (a.type === "breaking") ? -1 : 1) @@ -731,17 +757,17 @@ const documentTotal = computed(() => { let totalNet0 = 0 itemInfo.value.rows.filter(i => !i.optional && !i.alternative).forEach(row => { - if(!['pagebreak','title','text'].includes(row.mode)){ - let rowPrice = Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(3) + if (!['pagebreak', 'title', 'text'].includes(row.mode)) { + let rowPrice = Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) / 100)).toFixed(3) totalNet = totalNet + Number(rowPrice) - if(row.taxPercent === 19) { + if (row.taxPercent === 19) { total19 = total19 + Number(rowPrice * 0.19) totalNet19 += Number(rowPrice) - } else if(row.taxPercent === 7) { + } else if (row.taxPercent === 7) { total7 = total7 + Number(rowPrice * 0.07) totalNet7 += Number(rowPrice) - } else if(row.taxPercent === 0) { + } else if (row.taxPercent === 0) { totalNet0 += Number(rowPrice) } } @@ -755,18 +781,18 @@ const documentTotal = computed(() => { let transferCounter = 0 itemInfo.value.rows.forEach(row => { - if(row.mode === 'title'){ + if (row.mode === 'title') { let title = `${row.pos} - ${row.text}` titleSums[title] = 0 lastTitle = title //Übertrag berechnen - titleSumsTransfer[Object.keys(titleSums)[row.pos-2]] = transferCounter + titleSumsTransfer[Object.keys(titleSums)[row.pos - 2]] = transferCounter - } else if(!['pagebreak','text'].includes(row.mode) && lastTitle !== "" && !row.optional && !row.alternative){ - titleSums[lastTitle] = Number(titleSums[lastTitle]) + Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ) - transferCounter += Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ) + } else if (!['pagebreak', 'text'].includes(row.mode) && lastTitle !== "" && !row.optional && !row.alternative) { + titleSums[lastTitle] = Number(titleSums[lastTitle]) + Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) / 100)) + transferCounter += Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) / 100)) console.log(transferCounter) } }) @@ -774,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 @@ -794,21 +818,14 @@ const documentTotal = computed(() => { let sumToPay = 0 - if(itemInfo.value.type === "invoices") { + if (itemInfo.value.type === "invoices") { sumToPay = totalGross - totalGrossAlreadyPaid - } else if(itemInfo.value.type === "cancellationInvoices") { + } else if (itemInfo.value.type === "cancellationInvoices") { sumToPay = totalGross + totalGrossAlreadyPaid } - - - - - - - return { titleSums: titleSums, titleSumsTransfer: titleSumsTransfer, @@ -838,15 +855,15 @@ const documentReport = computed(() => { itemInfo.value.rows.filter(i => !i.optional && !i.alternative).forEach(row => { - if(row.product) { + if (row.product) { let product = products.value.find(i => i.id === row.product) totalProductsPurchasePrice += product.purchasePrice * row.quantity - } else if(row.service) { + } else if (row.service) { let service = services.value.find(i => i.id === row.service) - if(service.materialComposition) { + if (service.materialComposition) { service.materialComposition.forEach(entry => { let productData = products.value.find(i => i.id === entry.product) @@ -854,21 +871,20 @@ const documentReport = computed(() => { }) } - if(service.personalComposition) { + if (service.personalComposition) { service.personalComposition.forEach(entry => { totalHoursFromServices.total += entry.quantity * row.quantity totalHoursFromServices.totalPurchasePrice += entry.quantity * entry.purchasePrice * row.quantity totalHoursSellingPrice += entry.quantity * entry.price * row.quantity - if(totalHoursFromServices.byName[entry.name]) { + if (totalHoursFromServices.byName[entry.name]) { totalHoursFromServices.byName[entry.name] += entry.quantity * row.quantity } else { totalHoursFromServices.byName[entry.name] = entry.quantity * row.quantity } - }) } else { //totalHoursSellingPrice += service.sellingPriceComposed.totalWorker * row.quantity @@ -901,7 +917,7 @@ const processDieselPosition = () => { } itemInfo.value.rows.forEach(row => { - if(row.agriculture && row.agriculture.dieselUsage) { + if (row.agriculture && row.agriculture.dieselUsage) { console.log(row.agriculture) agricultureData.dieselUsageTotal += Number(row.agriculture.dieselUsage) agricultureData.dieselPriceTotal += Number(row.agriculture.dieselPrice || 0) * Number(row.agriculture.dieselUsage) @@ -912,9 +928,9 @@ const processDieselPosition = () => { }) console.log(agricultureData) - if(agricultureData.dieselUsageTotal !== 0) { + if (agricultureData.dieselUsageTotal !== 0) { - if(itemInfo.value.rows.find(i => i.key === "dieselPos")){ + if (itemInfo.value.rows.find(i => i.key === "dieselPos")) { let existingIndex = itemInfo.value.rows.findIndex(i => i.key === "dieselPos") itemInfo.value.rows[existingIndex] = { @@ -934,7 +950,7 @@ const processDieselPosition = () => { } else { itemInfo.value.rows.push({ mode: "free", - text: `${(agricultureData.dieselUsageTotal).toFixed(2).replace(".",",")} L Diesel`, + text: `${(agricultureData.dieselUsageTotal).toFixed(2).replace(".", ",")} L Diesel`, quantity: 1, unit: 10, price: agricultureData.dieselPriceTotal, @@ -945,7 +961,7 @@ const processDieselPosition = () => { itemInfo.value.rows.push({ mode: "free", - text: `${(agricultureData.adblueUsageTotal).toFixed(2).replace(".",",")} L AdBlue`, + text: `${(agricultureData.adblueUsageTotal).toFixed(2).replace(".", ",")} L AdBlue`, quantity: 1, unit: 10, price: agricultureData.adbluePriceTotal, @@ -961,15 +977,15 @@ 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) { + 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 : ""}` } }) @@ -977,25 +993,25 @@ const getDocumentData = () => { let rows = itemInfo.value.rows - if(itemInfo.value.taxType === "13b UStG" || itemInfo.value.taxType === "19 UStG") { - rows = rows.map(row => { - return { - ...row, - taxPercent: 0 - } - }) + if (itemInfo.value.taxType === "13b UStG" || itemInfo.value.taxType === "19 UStG") { + rows = rows.map(row => { + return { + ...row, + taxPercent: 0 + } + }) } 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) { + if (!['pagebreak', 'title'].includes(row.mode)) { + if (row.agriculture && row.agriculture.description) { console.log("Row has Agri") row.descriptionText = row.agriculture.description - } else if(row.description) { + } else if (row.description) { console.log("Row has no Agri") row.descriptionText = row.description } else { @@ -1003,18 +1019,18 @@ const getDocumentData = () => { } } - if(!['pagebreak','title','text'].includes(row.mode)) { - if(row.mode === 'normal') row.text = products.value.find(i => i.id === row.product).name - if(row.mode === 'service') row.text = services.value.find(i => i.id === row.service).name + if (!['pagebreak', 'title', 'text'].includes(row.mode)) { + if (row.mode === 'normal') row.text = products.value.find(i => i.id === row.product).name + if (row.mode === 'service') row.text = services.value.find(i => i.id === row.service).name return { ...row, rowAmount: `${getRowAmount(row)} €`, - quantity: String(row.quantity).replace(".",","), + quantity: String(row.quantity).replace(".", ","), unit: unit.short, pos: String(row.pos), - price: `${String(row.price.toFixed(2)).replace(".",",")} €`, + price: `${String(row.price.toFixed(2)).replace(".", ",")} €`, discountText: `(Rabatt: ${row.discountPercent} %)` } } else { @@ -1029,27 +1045,29 @@ const getDocumentData = () => { const generateContext = (itemInfo, contactData) => { return { lohnkosten: documentReport.value.totalHoursSellingPrice ? useCurrency(documentReport.value.totalHoursSellingPrice) : null, - anrede:(contactData && contactData.salutation) || (customerData && customerData.salutation), - titel:(contactData && contactData.title) || (customerData && customerData.title), - vorname:(contactData && contactData.firstName) || (customerData && customerData.firstname), + anrede: (contactData && contactData.salutation) || (customerData && customerData.salutation), + titel: (contactData && contactData.title) || (customerData && customerData.title), + vorname: (contactData && contactData.firstName) || (customerData && customerData.firstname), nachname: (contactData && contactData.lastName) || (customerData && customerData.lastname), kundenname: customerData && customerData.name, - zahlungsziel_in_tagen:itemInfo.paymentDays, + zahlungsziel_in_tagen: itemInfo.paymentDays, diesel_gesamtverbrauch: (itemInfo.agriculture && itemInfo.agriculture.dieselUsageTotal) && itemInfo.agriculture.dieselUsageTotal } } - 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) { + if (Object.keys(documentTotal.value.titleSums).length > 0) { Object.keys(documentTotal.value.titleSums).forEach(key => { returnTitleSums[key] = renderCurrency(documentTotal.value.titleSums[key]) }) } let returnTitleSumsTransfer = {} - if(Object.keys(documentTotal.value.titleSumsTransfer).length > 0) { + if (Object.keys(documentTotal.value.titleSumsTransfer).length > 0) { Object.keys(documentTotal.value.titleSumsTransfer).forEach(key => { returnTitleSumsTransfer[key] = renderCurrency(documentTotal.value.titleSumsTransfer[key]) }) @@ -1072,12 +1090,12 @@ const getDocumentData = () => { zip: itemInfo.value.address.zip || customerData.infoData.zip },*/ recipient: [ - customerData.name, - ... customerData.nameAddition ? [customerData.nameAddition] : [], - ... contactData ? [`${contactData.firstName} ${contactData.lastName}`] : [], - itemInfo.value.address.street, - ... itemInfo.value.address.special ? [itemInfo.value.address.special] : [], - `${itemInfo.value.address.zip} ${itemInfo.value.address.city}`, + customerData.name, + ...customerData.nameAddition ? [customerData.nameAddition] : [], + ...contactData ? [`${contactData.firstName} ${contactData.lastName}`] : [], + itemInfo.value.address.street, + ...itemInfo.value.address.special ? [itemInfo.value.address.special] : [], + `${itemInfo.value.address.zip} ${itemInfo.value.address.city}`, ], /*info: { @@ -1098,16 +1116,16 @@ const getDocumentData = () => { { label: itemInfo.value.documentNumberTitle, content: itemInfo.value.documentNumber || "XXXX", - },{ + }, { label: "Kundennummer", content: customerData.customerNumber, - },{ + }, { label: "Belegdatum", content: itemInfo.value.documentDate ? dayjs(itemInfo.value.documentDate).format("DD.MM.YYYY") : "XXXX", }, - ... itemInfo.value.deliveryDateType !== "Kein Lieferdatum anzeigen" ? [{ - label: itemInfo.value.deliveryDateType, - content: !['Lieferzeitraum','Leistungszeitraum'].includes(itemInfo.value.deliveryDateType) ? (itemInfo.value.deliveryDate ? dayjs(itemInfo.value.deliveryDate).format("DD.MM.YYYY") : "XXXX") : `${itemInfo.value.deliveryDate ? dayjs(itemInfo.value.deliveryDate).format("DD.MM.YYYY") : "XXXX"} - ${itemInfo.value.deliveryDateEnd ? dayjs(itemInfo.value.deliveryDateEnd).format("DD.MM.YYYY") : "XXXX"}`, + ...itemInfo.value.deliveryDateType !== "Kein Lieferdatum anzeigen" ? [{ + label: itemInfo.value.deliveryDateType, + content: !['Lieferzeitraum', 'Leistungszeitraum'].includes(itemInfo.value.deliveryDateType) ? (itemInfo.value.deliveryDate ? dayjs(itemInfo.value.deliveryDate).format("DD.MM.YYYY") : "XXXX") : `${itemInfo.value.deliveryDate ? dayjs(itemInfo.value.deliveryDate).format("DD.MM.YYYY") : "XXXX"} - ${itemInfo.value.deliveryDateEnd ? dayjs(itemInfo.value.deliveryDateEnd).format("DD.MM.YYYY") : "XXXX"}`, }] : [], /*{ label: itemInfo.value.deliveryDateType, @@ -1115,24 +1133,24 @@ const getDocumentData = () => { },*/ { label: "Ansprechpartner", - content: contactPerson.fullName, + content: contactPerson.full_name, }, - ... contactPerson.fixedTel || contactPerson.mobileTel ? [{ + ...contactPerson.fixedTel || contactPerson.mobileTel ? [{ label: "Telefon", content: contactPerson.fixedTel || contactPerson.mobileTel, }] : [], - ... contactPerson.email ? [{ + ...contactPerson.email ? [{ label: "E-Mail", content: contactPerson.email, - }]: [], - ... itemInfo.value.plant ? [{ + }] : [], + ...itemInfo.value.plant ? [{ label: "Objekt", content: plants.value.find(i => i.id === itemInfo.value.plant).name, - }] : [], - ... itemInfo.value.project ? [{ + }] : [], + ...itemInfo.value.project ? [{ label: "Projekt", content: projects.value.find(i => i.id === itemInfo.value.project).name - }]: [] + }] : [] ], title: itemInfo.value.title, description: itemInfo.value.description, @@ -1144,18 +1162,18 @@ 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), - }] : [], + }] : [], { label: "Gesamtbetrag", content: renderCurrency(documentTotal.value.totalGross), @@ -1187,36 +1205,20 @@ const uri = ref("") const generateDocument = async () => { const path = letterheads.value.find(i => i.id === itemInfo.value.letterhead).path - /*const {data,error} = await supabase.functions.invoke('create_pdf',{ + uri.value = await useFunctions().useCreatePDF(await getDocumentData(), path) + /*uri.value = await useNuxtApp().$api("/api/functions/createinvoicepdf",{ + method: "POST", body: { - invoiceData: getDocumentData(), - backgroundPath: path, - returnMode: "base64" + invoiceData: await getDocumentData(), + backgroundPath: path } })*/ - uri.value = await useFunctions().useCreatePDF(getDocumentData(), path) - - - - - //const {data,error} = await supabase.storage.from("files").download(path) - - //console.log(data) - //console.log(error) - - //console.log(JSON.stringify(getDocumentData())) - - //uri.value = `data:${data.mimeType};base64,${data.base64}` - - //uri.value = await useCreatePdf(getDocumentData(), await data.arrayBuffer()) - //alert(uri.value) showDocument.value = true - //console.log(uri.value) } const onChangeTab = (index) => { - if(index === 1) { + if (index === 1) { generateDocument() } } @@ -1225,16 +1227,16 @@ const setPosNumbers = () => { let mainIndex = 1 let subIndex = 1 let rows = itemInfo.value.rows.map(row => { - if(row.mode === 'title') { + if (row.mode === 'title') { row.pos = mainIndex mainIndex += 1 subIndex = 1 - } else if(!['pagebreak','title','text'].includes(row.mode)) { - row.pos = itemInfo.value.rows.filter(i => i.mode === "title").length === 0 ? `${subIndex}` :`${ mainIndex - 1}.${subIndex}` + } else if (!['pagebreak', 'title', 'text'].includes(row.mode)) { + row.pos = itemInfo.value.rows.filter(i => i.mode === "title").length === 0 ? `${subIndex}` : `${mainIndex - 1}.${subIndex}` subIndex += 1 } - if(!row.id) { + if (!row.id) { row.id = uuidv4() } @@ -1265,7 +1267,7 @@ const saveSerialInvoice = async () => { let data = null - if(route.params.id) { + if (route.params.id) { data = await dataStore.updateItem("createddocuments", {...createData, id: itemInfo.value.id}) } else { data = await dataStore.createNewItem("createddocuments", createData) @@ -1274,15 +1276,15 @@ const saveSerialInvoice = async () => { await router.push(`/createDocument/edit/${data.id}`) } -const saveDocument = async (state,resetup = false) => { +const saveDocument = async (state, resetup = false) => { itemInfo.value.state = state - if(state !== "Entwurf") { + if (state !== "Entwurf") { console.log("???") let type = "" - if(itemInfo.value.type === "advanceInvoices" || itemInfo.value.type === "cancellationInvoices"){ + if (itemInfo.value.type === "advanceInvoices" || itemInfo.value.type === "cancellationInvoices") { type = "invoices" } else { type = itemInfo.value.type @@ -1297,13 +1299,11 @@ 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) { + 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 : ""}` } }) @@ -1314,7 +1314,7 @@ const saveDocument = async (state,resetup = false) => { let descriptionText = "" - if(row.agriculture && row.agriculture.description) { + if (row.agriculture && row.agriculture.description) { descriptionText = row.agriculture.description } else { descriptionText = row.description ? row.description : null @@ -1328,7 +1328,7 @@ const saveDocument = async (state,resetup = false) => { let createData = { type: itemInfo.value.type, - taxType: ['invoices','cancellationInvoices','advanceInvoices','qoutes','confirmationOrders'].includes(itemInfo.value.type) ? itemInfo.value.taxType : null, + taxType: ['invoices', 'cancellationInvoices', 'advanceInvoices', 'qoutes', 'confirmationOrders'].includes(itemInfo.value.type) ? itemInfo.value.taxType : null, state: itemInfo.value.state || "Entwurf", customer: itemInfo.value.customer, contact: itemInfo.value.contact, @@ -1343,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, @@ -1357,15 +1358,16 @@ const saveDocument = async (state,resetup = false) => { report: documentReport.value } - if(route.params.id) { - await dataStore.updateItem("createddocuments", {...createData, id: itemInfo.value.id}) + if (route.params.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}`) } - if(resetup) await setupPage() + if (resetup) await setupPage() } const closeDocument = async () => { @@ -1383,13 +1385,16 @@ const closeDocument = async () => { let mappedType = itemInfo.value.type - if(mappedType === "advanceInvoices" || mappedType === "cancellationInvoices"){ + if (mappedType === "advanceInvoices" || mappedType === "cancellationInvoices") { 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(","), @@ -1400,12 +1405,12 @@ const closeDocument = async () => { while (n--) { u8arr[n] = bstr.charCodeAt(n); } - return new File([u8arr], filename, { type: mime }); + return new File([u8arr], filename, {type: mime}); } 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}`) @@ -1415,11 +1420,11 @@ const getTextTemplateByType = (type, pos) => { let finalType = type - if(type === "serialInvoices") { + if (type === "serialInvoices") { finalType = "invoices" } - if(pos) { + if (pos) { return texttemplates.value.filter(i => i.documentType === finalType && i.pos === pos) } else { return texttemplates.value.filter(i => i.documentType === finalType) @@ -1430,7 +1435,7 @@ const getTextTemplateByType = (type, pos) => { const checkCompatibilityWithInputPrice = () => { itemInfo.value.rows.forEach(row => { - if(!row.inputPrice) { + if (!row.inputPrice) { row.inputPrice = row.price } }) @@ -1438,10 +1443,10 @@ const checkCompatibilityWithInputPrice = () => { const updateCustomSurcharge = () => { itemInfo.value.rows.forEach(row => { - if(!["pagebreak","title","text"].includes(row.mode) /*&& !row.linkedEntitys.find(i => i.type === "createddocuments" && i.subtype === "advanceInvoices")*/) { + if (!["pagebreak", "title", "text"].includes(row.mode) /*&& !row.linkedEntitys.find(i => i.type === "createddocuments" && i.subtype === "advanceInvoices")*/) { //setRowData(row) - row.price = Number((row.inputPrice * (1 + itemInfo.value.customSurchargePercentage /100)).toFixed(2)) + row.price = Number((row.inputPrice * (1 + itemInfo.value.customSurchargePercentage / 100)).toFixed(2)) }/* else if(!["pagebreak","title","text"].includes(row.mode) /!*&& row.linkedEntitys.find(i => i.type === "createddocuments" && i.subtype === "advanceInvoices")*!/) { @@ -1452,36 +1457,36 @@ const updateCustomSurcharge = () => { const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {}) => { console.log("Set Row Data") - if(service && service.id) { + if (service && service.id) { row.service = service.id - services.value = await useSupabaseSelect("services","*") + services.value = await useEntities("services").select("*") } - if(product && product.id) { + if (product && product.id) { row.product = product.id - product.value = await useSupabaseSelect("products","*") + product.value = await useEntities("products").select("*") } - if(row.service) { + if (row.service) { row.unit = service.unit ? service.unit : services.value.find(i => i.id === row.service).unit row.inputPrice = ((service.sellingPriceComposed.total || service.sellingPrice) ? (service.sellingPriceComposed.total || service.sellingPrice) : (services.value.find(i => i.id === row.service).sellingPriceComposed.total || services.value.find(i => i.id === row.service).sellingPrice)) row.description = service.description ? service.description : (services.value.find(i => i.id === row.service) ? services.value.find(i => i.id === row.service).description : "") - if(['13b UStG','19 UStG'].includes(itemInfo.value.taxType)) { + if (['13b UStG', '19 UStG'].includes(itemInfo.value.taxType)) { row.taxPercent = 0 } else { row.taxPercent = service.taxPercentage ? service.taxPercentage : services.value.find(i => i.id === row.service).taxPercentage } } - if(row.product) { + if (row.product) { console.log("Product Detected") row.unit = product.unit ? product.unit : products.value.find(i => i.id === row.product).unit row.inputPrice = (product.sellingPrice ? product.sellingPrice : products.value.find(i => i.id === row.product).sellingPrice) //row.price = Number((row.originalPrice * (1 + itemInfo.value.customSurchargePercentage /100)).toFixed(2)) row.description = product.description ? product.description : (products.value.find(i => i.id === row.product) ? products.value.find(i => i.id === row.product).description : "") - if(['13b UStG','19 UStG'].includes(itemInfo.value.taxType)) { + if (['13b UStG', '19 UStG'].includes(itemInfo.value.taxType)) { row.taxPercent = 0 } else { row.taxPercent = product.taxPercentage ? product.taxPercentage : products.value.find(i => i.id === row.product).taxPercentage @@ -1536,9 +1541,9 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { Fertigstellen Serienrechnung @@ -1551,15 +1556,16 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { @@ -1582,19 +1588,19 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { class="flex-auto" > - + - @@ -1670,7 +1675,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { :color="itemInfo.letterhead ? 'primary' : 'rose'" > @@ -1691,16 +1696,18 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { class="flex-auto" > - {{customers.find(i => i.id === itemInfo.customer) ? customers.find(i => i.id === itemInfo.customer).name : "Kein Kunde ausgewählt"}} + {{ customers.find(i => i.id === itemInfo.customer) ? customers.find(i => i.id === itemInfo.customer).name : "Kein Kunde ausgewählt" }} - + - +
- @@ -1785,23 +1791,26 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { :color="itemInfo.contact ? 'primary' : 'none'" variant="outline" class="w-full" - :disabled="!itemInfo.customer" + :disabled="!itemInfo.customer" > - {{itemInfo.contact ? contacts.find(i => i.id === itemInfo.contact).fullName : "Kein Kontakt ausgewählt"}} + {{ itemInfo.contact ? contacts.find(i => i.id === itemInfo.contact).fullName : "Kein Kontakt ausgewählt" }} - + - + @@ -1899,7 +1908,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { /> @@ -1919,29 +1928,29 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { />