From 842afcfdb2624f4fec4801d57a1fc7b823fd0cbc Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Sat, 19 Apr 2025 17:34:02 +0200 Subject: [PATCH 1/4] Added Hourrates --- components/MainNav.vue | 5 +++++ composables/useRole.js | 12 +++++++++++ stores/data.js | 46 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/components/MainNav.vue b/components/MainNav.vue index ec84260..0910382 100644 --- a/components/MainNav.vue +++ b/components/MainNav.vue @@ -234,6 +234,11 @@ const links = computed(() => { to: "/profiles", icon: "i-heroicons-user-group" }, + { + label: "Stundensätze", + to: "/standardEntity/hourrates", + icon: "i-heroicons-user-group" + }, ... role.checkRight("vehicles") ? [{ label: "Fahrzeuge", to: "/standardEntity/vehicles", diff --git a/composables/useRole.js b/composables/useRole.js index 7f17605..9548a13 100644 --- a/composables/useRole.js +++ b/composables/useRole.js @@ -258,6 +258,18 @@ export const useRole = () => { label: "Dokuemntenboxen erstellen", parent: "documentboxes" }, + hourrates: { + label: "Stundensätze", + showToAllUsers: false + }, + "hourrates-viewAll": { + label: "Alle Stundensätze einsehen", + parent: "hourrates" + }, + "hourrates-create": { + label: "Stundensätze erstellen", + parent: "hourrates" + }, "inventory": { label: "Lager", }, diff --git a/stores/data.js b/stores/data.js index d071fb5..b35b8f9 100644 --- a/stores/data.js +++ b/stores/data.js @@ -1719,6 +1719,52 @@ export const useDataStore = defineStore('data', () => { } ] }, + hourrates: { + isArchivable: true, + label: "Stundensätze", + labelSingle: "Stundensatz", + isStandardEntity: true, + redirect: true, + supabaseSelectWithInformation: "*", + historyItemHolder: "hourrate", + filters: [{ + name: "Archivierte ausblenden", + default: true, + "filterFunction": function (row) { + if(!row.archived) { + return true + } else { + return false + } + } + }], + templateColumns: [ + { + key: "name", + label: "Name", + required: true, + title: true, + inputType: "text" + }, + { + key: "purchasePrice", + label: "Einkauspreis", + inputType: "number", + component: purchasePrice, + }, + { + key: "sellingPrice", + label: "Verkaufspreis", + inputType: "number", + component: sellingPrice, + }, + ], + showTabs: [ + { + label: 'Informationen', + } + ] + }, events: { isArchivable: true, label: "Termine", From d762bb32283193850c5a4b378776eeac6deacd2e Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Sat, 19 Apr 2025 17:34:29 +0200 Subject: [PATCH 2/4] Added Personal Composition --- components/EntityEdit.vue | 9 ++ components/personalComposing.vue | 149 +++++++++++++++++++++++++++++++ stores/data.js | 5 ++ 3 files changed, 163 insertions(+) create mode 100644 components/personalComposing.vue diff --git a/components/EntityEdit.vue b/components/EntityEdit.vue index 4c05219..7e1a4c3 100644 --- a/components/EntityEdit.vue +++ b/components/EntityEdit.vue @@ -1,6 +1,7 @@ + + + + \ No newline at end of file diff --git a/stores/data.js b/stores/data.js index b35b8f9..7238447 100644 --- a/stores/data.js +++ b/stores/data.js @@ -1687,6 +1687,11 @@ export const useDataStore = defineStore('data', () => { label: "Zusammensetzung Materialpreis pro Einheit", inputType: "materialComposing", }, + { + key: "personalComposing", + label: "Zusammensetzung Personal pro Einheit", + inputType: "personalComposing", + }, { key: "sellingPriceComposed.total", label: "Verkaufspreis Gesamt pro Einheit", From 8edd996b89ebf9f9cecc3a77d55359dc5f86fdb2 Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Sat, 19 Apr 2025 17:34:45 +0200 Subject: [PATCH 3/4] Added Document Report --- pages/createDocument/edit/[[id]].vue | 143 ++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 3 deletions(-) diff --git a/pages/createDocument/edit/[[id]].vue b/pages/createDocument/edit/[[id]].vue index c031e21..725db60 100644 --- a/pages/createDocument/edit/[[id]].vue +++ b/pages/createDocument/edit/[[id]].vue @@ -696,6 +696,74 @@ const documentTotal = computed(() => { } }) +const documentReport = computed(() => { + + let totalProductsPurchasePrice = 0 + let totalProductsFromServicesPurchasePrice = 0 + let totalHoursFromServices = { + total: 0, + totalPurchasePrice: 0, + byName: {} + } + let totalHoursSellingPrice = 0 + + + itemInfo.value.rows.forEach(row => { + if(row.product) { + let product = products.value.find(i => i.id === row.product) + console.log(product) + + totalProductsPurchasePrice += product.purchasePrice * row.quantity + + } else if(row.service) { + let service = services.value.find(i => i.id === row.service) + console.log(service) + + if(service.materialComposition) { + service.materialComposition.forEach(entry => { + let productData = products.value.find(i => i.id === entry.product) + console.log(productData) + + totalProductsFromServicesPurchasePrice += productData.purchasePrice * entry.quantity * row.quantity + }) + } + + if(service.personalComposition) { + service.personalComposition.forEach(entry => { + totalHoursFromServices.total += entry.quantity + + totalHoursFromServices.totalPurchasePrice += entry.quantity * entry.purchasePrice + totalHoursSellingPrice += entry.quantity * entry.price + + if(totalHoursFromServices.byName[entry.name]) { + totalHoursFromServices.byName[entry.name] += entry.quantity + } else { + totalHoursFromServices.byName[entry.name] = entry.quantity + } + + + + }) + } + + //totalProductsPurchasePrice += product.purchasePrice * row.quantity + + } + }) + + let totalMargin = documentTotal.value.totalNet - totalProductsPurchasePrice - totalProductsFromServicesPurchasePrice - totalHoursFromServices.totalPurchasePrice + + + return { + totalProductsPurchasePrice, + totalProductsFromServicesPurchasePrice, + totalMargin, + totalHoursFromServices, + totalHoursSellingPrice, + } + +}) + const processDieselPosition = () => { let agricultureData = { dieselUsageTotal: 0, @@ -2499,11 +2567,41 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = { - Gesamt + Auswertung & Gesamt -
- +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Einkaufspreis Artikel Gesamt:{{useCurrency(documentReport.totalProductsPurchasePrice)}}
Einkaufspreis Artikel aus Leistungen Gesamt:{{useCurrency(documentReport.totalProductsFromServicesPurchasePrice)}}
Einkaufspreis Personal aus Leistungen Gesamt:{{useCurrency(documentReport.totalHoursFromServices.totalPurchasePrice)}}
Gewinn Gesamt:{{useCurrency(documentReport.totalMargin)}}
Lohnkosten Verkauf:{{useCurrency(documentReport.totalHoursSellingPrice)}}
{{key}}{{documentReport.totalHoursFromServices.byName[key]}} h
Stunden Gesamt:{{documentReport.totalHoursFromServices.total}} h
+ @@ -2527,6 +2625,45 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
Netto: {{renderCurrency(documentTotal.totalNet)}}
+ + + + From ec741acf7cd0c09125129e3dafb46d9a547f17a9 Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Sat, 19 Apr 2025 17:34:58 +0200 Subject: [PATCH 4/4] Added THs --- components/materialComposing.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/materialComposing.vue b/components/materialComposing.vue index 1079cd6..d43ebb5 100644 --- a/components/materialComposing.vue +++ b/components/materialComposing.vue @@ -69,6 +69,12 @@ const setRowData = (row) => { + + + + + +
ArtikelMengeEinheitVerkaufspreis