Files
FEDEO/stores/data.js

3063 lines
109 KiB
JavaScript

import {defineStore} from 'pinia'
import dayjs from "dayjs"
//import {typeOf} from "uri-js/dist/esnext/util";
import {useNumberRange} from "~/composables/useNumberRange.js";
//const supabase = createClient('https://uwppvcxflrcsibuzsbil.supabase.co','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo')
import projecttype from "~/components/columnRenderings/projecttype.vue"
import customer from "~/components/columnRenderings/customer.vue"
import contact from "~/components/columnRenderings/contact.vue"
import plant from "~/components/columnRenderings/plant.vue"
import vendor from "~/components/columnRenderings/vendor.vue"
import active from "~/components/columnRenderings/active.vue"
import sellingPrice from "~/components/columnRenderings/sellingPrice.vue";
import unit from "~/components/columnRenderings/unit.vue";
import isCompany from "~/components/columnRenderings/isCompany.vue"
import address from "~/components/columnRenderings/address.vue"
import sepa from "~/components/columnRenderings/sepa.vue"
import recurring from "~/components/columnRenderings/recurring.vue"
import description from "~/components/columnRenderings/description.vue"
import purchasePrice from "~/components/columnRenderings/purchasePrice.vue";
import project from "~/components/columnRenderings/project.vue";
import created_at from "~/components/columnRenderings/created_at.vue";
import profile from "~/components/columnRenderings/profile.vue";
import profiles from "~/components/columnRenderings/profiles.vue";
import vehicle from "~/components/columnRenderings/vehicle.vue"
import usePlanning from "~/components/columnRenderings/usePlanning.vue"
import sellingPriceComposedMaterial from "~/components/columnRenderings/sellingPriceComposedMaterial.vue"
import sellingPriceComposedWorker from "~/components/columnRenderings/sellingPriceComposedWorker.vue"
import sellingPriceComposedTotal from "~/components/columnRenderings/sellingPriceComposedTotal.vue"
import startDate from "~/components/columnRenderings/startDate.vue"
import endDate from "~/components/columnRenderings/endDate.vue"
import startDateTime from "~/components/columnRenderings/startDateTime.vue"
import endDateTime from "~/components/columnRenderings/endDateTime.vue"
import serviceCategories from "~/components/columnRenderings/serviceCategories.vue"
import phase from "~/components/columnRenderings/phase.vue"
import vehiclesWithLoad from "~/components/columnRenderings/vehiclesWithLoad.vue"
import inventoryitemsWithLoad from "~/components/columnRenderings/inventoryitemsWithLoad.vue"
import inventoryitemgroupsWithLoad from "~/components/columnRenderings/inventoryitemgroupsWithLoad.vue"
import space from "~/components/columnRenderings/space.vue"
import driver from "~/components/columnRenderings/driver.vue"
import quantity from "~/components/helpRenderings/quantity.vue"
import {useZipCheck} from "~/composables/useZipCheck.js";
import {useFunctions} from "~/composables/useFunctions.js";
// @ts-ignore
export const useDataStore = defineStore('data', () => {
const supabase = useSupabaseClient()
const profileStore = useProfileStore()
const toast = useToast()
const router = useRouter()
const dataTypes = {
tasks: {
label: "Aufgaben",
labelSingle: "Aufgabe",
isStandardEntity: true,
redirect: true,
historyItemHolder: "task",
supabaseSelectWithInformation: "*, plant(*), project(*), customer(*)",
filters: [
{
name: "Nur Offene Aufgaben",
default: true,
"filterFunction": function (row) {
if(row.categorie !== "Erledigt") {
return true
} else {
return false
}
}
},{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}
],
templateColumns: [
{
key: "created_at",
label: "Erstellt am",
component: created_at,
},{
key: "name",
label: "Name",
title: true,
required: true,
inputType: "text"
},{
key: "categorie",
label: "Kategorie",
required: true,
},{
key: "profile",
label: "Mitarbeiter",
component: profile,
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
},{
key: "project",
label: "Projekt",
component: project,
inputType: "select",
selectDataType: "projects",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "customer",
label: "Kunde",
component: customer,
inputType: "select",
selectDataType: "customers",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "plant",
label: "Objekt",
component: plant,
inputType: "select",
selectDataType: "plants",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "description",
label: "Beschreibung"
},
],
showTabs: [{label: 'Informationen'}]
},
customers: {
label: "Kunden",
labelSingle: "Kunde",
isStandardEntity: true,
redirect:true,
numberRangeHolder: "customerNumber",
historyItemHolder: "customer",
supabaseSortColumn: "customerNumber",
supabaseSelectWithInformation: "*, projects(*), plants(*), contracts(*), contacts(*), createddocuments(*), files(*)",
filters: [{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: 'customerNumber',
label: "Kundennummer",
inputIsNumberRange: true,
inputType: "text"
}, {
key: "name",
label: "Firmenname",
required: true,
title: true,
inputType: "text",
disabledFunction: function (item) {
return !item.isCompany
},
},{
key: "firstname",
label: "Vorname",//TODO: Add Conditional Rendering to Datatypes
title: true,
inputType: "text",
inputChangeFunction: function (row) {
if(row.firstname && row.lastname) {
row.name = `${row.firstname} ${row.lastname}`
} else {
row.name = row.firstname
}
},
disabledFunction: function (item) {
return item.isCompany
},
},{
key: "lastname",
label: "Nachname",
title: true,
inputType: "text",
inputChangeFunction: function (row) {
if(row.firstname && row.lastname) {
row.name = `${row.firstname} ${row.lastname}`
} else {
row.name = row.lastname
}
},
disabledFunction: function (item) {
return item.isCompany
},
}, {
key: "isCompany",
label: "Firmenkunde",
component: isCompany,
inputType: "bool"
},{
key: "active",
label: "Aktiv",
component: active,
inputType: "bool"
}, {
key: "customPaymentDays",
label: "Zahlungsziel in Tagen",
inputType: "number"
}, {
key: "infoData.street",
label: "Straße + Hausnummer",
inputType: "text",
disabledInTable: true
},
{
key: "infoData.special",
label: "Adresszusatz",
inputType: "text",
disabledInTable: true
},
{
key: "infoData.zip",
label: "Postleitzahl",
inputType: "number",
inputChangeFunction: async function (row) {
if(row.infoData.zip) {
row.infoData.city = (await useZipCheck(row.infoData.zip))
}
},
disabledInTable: true
},
{
key: "infoData.city",
label: "Stadt",
inputType: "text",
disabledInTable: true
},
{
key: "infoData.country",
label: "Land",
inputType: "select",
selectDataType: "countrys",
selectOptionAttribute: "name",
selectValueAttribute: "name",
disabledInTable: true
},
{
key: "address",
label: "Adresse",
component: address
},
{
key: "infoData.tel",
label: "Telefon",
inputType: "text"
},
{
key: "infoData.email",
label: "E-Mail",
inputType: "text"
},
{
key: "infoData.web",
label: "Web",
inputType: "text"
},
{
key: "infoData.ustid",
label: "USt-Id",
inputType: "text"
},
{
key: "notes",
label: "Notizen",
inputType: "textarea"
},
{
key: "profiles",
label: "Berechtigte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
},
],
showTabs: [{label: 'Informationen'},{label: 'Ansprechpartner'},{label: 'Dateien'},{label: 'Ausgangsbelege'},{label: 'Projekte'},{label: 'Objekte'},{label: 'Verträge'}]
},
contacts: {
label: "Kontakte",
labelSingle: "Kontakt",
isStandardEntity: true,
redirect:true,
historyItemHolder: "contact",
supabaseSelectWithInformation: "*, customer(*), vendor(*)",
filters: [{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: "fullName",
label: "Name",
title: true,
},{
key: "salutation",
label: "Anrede",
inputType: "text",
},{
key: "firstName",
label: "Vorname",
inputType: "text",
inputChangeFunction: function (row) {
row.fullName = `${row.firstName} ${row.lastName}`
}
},{
key: "lastName",
label: "Nachname",
required: true,
inputType: "text",
inputChangeFunction: function (row) {
row.fullName = `${row.firstName} ${row.lastName}`
}
},
{
key: "active",
label: "Aktiv",
component: active,
inputType: "bool"
},
{
key: "customer",
label: "Kunde",
component: customer,
inputType: "select",
selectDataType: "customers",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},
{
key: "vendor",
label: "Lieferant",
component: vendor,
inputType: "select",
selectDataType: "vendors",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},
{
key: "role",
label: "Rolle",
inputType: "text"
},
{
key: "email",
label: "E-Mail",
inputType: "text",
},
{
key: "phoneMobile",
label: "Mobil",
inputType: "text",
},
{
key: "phoneHome",
label: "Festnetz",
inputType: "text",
},
{
key: "birthday",
label: "Geburtstag",
inputType: "date",
},
{
key: "notes",
label: "Notizen",
inputType: "textarea",
},
],
showTabs:[
{
label: 'Informationen',
}
]
},
contracts: {
label: "Verträge",
labelSingle: "Vertrag",
isStandardEntity: true,
redirect:true,
filters:[{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
inputColumns: [
"Allgemeines",
"Abrechnung"
],
supabaseSelectWithInformation: "*, customer(*), files(*)",
templateColumns: [
{
key: "name",
required: true,
label: "Name",
title: true,
inputType: "text",
inputColumn: "Allgemeines"
},{
key: "active",
label: "Aktiv",
component: active,
inputType: "bool",
inputColumn: "Allgemeines"
},{
key: "recurring",
label: "Wiederkehrend",
component: recurring,
inputType: "bool",
inputColumn: "Allgemeines"
},{
key: 'customer',
label: "Kunde",
component: customer,
inputType: "select",
selectDataType: "customers",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
inputColumn: "Allgemeines"
},{
key: 'contact',
label: "Ansprechpartner",
component: contact,
inputType: "select",
selectDataType: "contacts",
selectDataTypeFilter: function (i,item) {
return i.customer === item.customer
},
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
inputColumn: "Allgemeines"
},{
key: 'duration',
label: "mindest Vertragslaufzeit",
inputType: "select",
selectValueAttribute:"label",
selectManualOptions: [
{label:'12 Monate'},
{label:'24 Monate'},
{label:'36 Monate'},
{label:'48 Monate'},
],
inputColumn: "Allgemeines"
},{
key: 'invoiceDispatch',
label: "Rechnungsversand",
inputType: "select",
selectValueAttribute: "label",
selectManualOptions: [
{label:'E-Mail'},
{label:'Post'}
],
inputColumn: "Abrechnung"
},{
key: 'paymentType',
label: "Zahlungsart",
inputType: "select",
selectValueAttribute: "label",
selectManualOptions: [
{label:'Einzug'},
{label:'Überweisung'}
],
inputColumn: "Abrechnung"
},{
key: 'startDate',
label: "Vertragsstart",
inputType: "date",
inputColumn: "Allgemeines"
},{
key: 'endDate',
label: "Vertragsende",
inputType: "date",
inputColumn: "Allgemeines"
},{
key: 'signDate',
label: "Unterschrieben am",
inputType: "date",
inputColumn: "Allgemeines"
},{
key: 'sepaDate',
label: "SEPA Datum",
inputType: "date",
inputColumn: "Abrechnung"
},{
key: 'sepaRef',
label: "Mandatsreferenz",
inputType: "text",
inputColumn: "Abrechnung"
},{
key: 'bankingIban',
label: "IBAN",
inputType: "text",
inputColumn: "Abrechnung"
},{
key: 'bankingOwner',
label: "Inhaber",
inputType: "text",
inputColumn: "Abrechnung"
},{
key: 'bankingName',
label: "Bank",
inputType: "text",
inputColumn: "Abrechnung"
},{
key: 'bankinBIC',
label: "BIC",
inputType: "text",
inputColumn: "Abrechnung"
},{
key: "notes",
label: "Notizen",
inputType: "textarea",
}
],
showTabs: [{label: 'Informationen'},{label: 'Dateien'}]
},
absencerequests: {
label: "Abwesenheiten",
labelSingle: "Abwesenheit",
isStandardEntity: true,
supabaseSortColumn:"startDate",
supabaseSortAscending: false,
supabaseSelectWithInformation: "*",
historyItemHolder: "absencerequest",
redirect:true,
filters:[{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns:[
{
key: "approved",
label: "Genehmigt",
inputType: "select",
selectValueAttribute: "label",
selectManualOptions: [
{label:"Offen"},
{label:"Genehmigt"},
{label:"Abgelehnt"}
]
},{
key: "name",
label: "Name",
required: true,
inputType: "text",
title: true
},
{
key: "profile",
label: "Mitarbeiter",
required: true,
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
component: profile
},{
key: "reason",
label: "Grund",
inputType: "select",
required: true,
selectValueAttribute: "label",
selectManualOptions: [
{label:"Urlaub"},
{label:"Berufsschule"},
{label:"Schlechtwetter"},
{label:"Saison Kurzarbeitergeld"},
{label:"unbezahlter Urlaub"},
{label:"Überstundenausgleich"},
{label:"Sonderurlaub(bezahlt)"},
{label:"Schulung"},
{label:"Mutterschutz"},
{label:"Krankheit ab 2. Tag (mit Attest)"},
{label:"Krankheit 1 Tag (mit Attest)"},
{label:"Krankheit"},
{label:"Kind krank - Kinderbetreuung"},
{label:"Elternzeit"},
]
},{
key: "startDate",
required: true,
label: "Start",
inputType: "date",
component: startDate
},{
key: "endDate",
required: true,
label: "Ende",
inputType: "date",
component: endDate
},{
key: "note",
label: "Notizen",
inputType: "textarea"
}
],
showTabs: [{label: 'Informationen'}]
},
plants: {
label: "Objekte",
labelSingle: "Objekt",
isStandardEntity: true,
redirect:true,
historyItemHolder: "plant",
supabaseSelectWithInformation: "*, customer(id,name)",
filters: [{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: "name",
label: "Name",
required: true,
inputType: "text",
title: true
},
{
key: "customer",
label: "Kunde",
component: customer,
inputType: "select",
selectDataType: "customers",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "description",
label: "Beschreibung",
inputType:"editor",
component: description
},
],
showTabs: [
{
label: "Informationen"
},{
label: "Projekte"
},{
label: "Aufgaben"
},{
label: "Dateien"
}]
},
products: {
label: "Artikel",
labelSingle: "Artikel",
isStandardEntity: true,
redirect:true,
supabaseSelectWithInformation: "*, unit(name)",
historyItemHolder: "product",
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: "manufacturer",
label: "Hersteller",
inputType: "text"
},
{
key: "unit",
label: "Einheit",
required: true,
component: unit,
inputType: "select",
selectDataType: "units",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},
{
key: "purchasePrice",
label: "Einkaufspreis",
component: purchasePrice,
inputType: "number",
inputTrailing: "EUR"
},{
key: "sellingPrice",
label: "Verkaufpreispreis",
required: true,
component: sellingPrice,
inputType: "number",
inputTrailing: "EUR"
},{
key: "taxPercentage",
label: "Umsatzsteuer",
inputType: "select",
selectOptionAttribute: "label",
selectValueAttribute: 'key',
required: true,
selectManualOptions: [
{label: "19 %", key: 19},
{label: "7 %", key: 7},
{label: "0 %", key: 0}]
},
/*{
key: "tags",
label: "Tags"
},*/
{
key: "productcategories",
label: "Artikelkategorien",
inputType: "select",
selectDataType: "productcategories",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
selectMultiple: true
},
{
key: "description",
label: "Beschreibung",
inputType:"textarea"
},
],
showTabs: [
{
label: "Informationen"
}
]
},
projects: {
label: "Projekte",
labelSingle: "Projekt",
isStandardEntity: true,
redirect:true,
historyItemHolder: "project",
numberRangeHolder: "projectNumber",
supabaseSelectWithInformation: "*, customer(id,name), plant(id,name), projecttype(name, id), tasks(*), files(*), createddocuments(*), events(*)",
supabaseSortColumn: "projectNumber",
filters: [
{
name: "Nur Offene Projekte",
default: true,
"filterFunction": function (row) {
if(row.phases && row.phases.length > 0) {
return row.phases.find(i => i.active).label !== "Abgeschlossen"
//return phase.label !== "Abgeschlossen";
} else {
return true
}
}
}, {
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}
],
templateColumns: [
{
key: "projectNumber",
label: "Projektnummer"
},
{
key: "projecttype",
label: "Typ",
required: true,
component: projecttype,
inputType: "select",
selectDataType: "projecttypes",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
inputChangeFunction: function (item,loadedOptions = {}) {
item.phases = loadedOptions.projecttypes.find(i => i.id === item.projecttype).initialPhases
}
},{
key: "phase",
label: "Phase",
component: phase
},{
key: "name",
label: "Name",
required: true,
title: true,
inputType: "text"
},
{
key: "customer",
label: "Kunde",
component: customer,
required: true,
inputType: "select",
selectDataType: "customers",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "plant",
label: "Objekt",
component: plant,
inputType: "select",
selectDataType: "plants",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "customerRef",
label: "Referenz des Kunden",
inputType: "text"
},{
key: "notes",
label: "Notizen",
inputType: "textarea"
},
{
key: "profiles",
label: "Berechtigte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
},],
showTabs: [
{
key: "information",
label: "Informationen"
},
{
key: "phases",
label: "Phasen"
},{
key: "tasks",
label: "Aufgaben"
},{
key: "files",
label: "Dateien"
},{
label: "Ausgangsbelege"
},{
label: "Termine"
}/*,{
key: "timetracking",
label: "Zeiterfassung"
},{
key: "events",
label: "Termine"
},{
key: "material",
label: "Material"
}*/]
},
vehicles: {
label: "Fahrzeuge",
labelSingle: "Fahrzeug",
isStandardEntity: true,
redirect:true,
historyItemHolder: "vehicle",
supabaseSelectWithInformation: "*, checks(*), files(*)",
filters:[{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns:[
{
key: 'active',
label: "Aktiv",
component: active,
inputType: "bool"
},{
key: 'licensePlate',
label: "Kennzeichen",
required: true,
inputType: "text",
title: true
},{
key: 'vin',
label: "Identifikationnummer",
inputType: "text"
},
{
key: "type",
label: "Typ",
inputType: "text"
},
{
key: "driver",
label: "Fahrer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
component: driver
},
{
key: "tankSize",
label: "Tankvolumen",
unit: "L",
inputType: "number"
},
{
key: "buildYear",
label: "Baujahr",
inputType: "number"
},
{
key: "towingCapacity",
label: "Anhängelast",
unit: "Kg",
inputType: "number"
},
{
key: "color",
label: "Farbe",
inputType: "text"
},
{
key: "powerInKW",
label: "Leistung",
unit: "kW",
inputType: "number"
},
{
key: "profiles",
label: "Berechtigte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
},
],
showTabs: [
{
label: 'Informationen',
}, {
label: 'Dateien',
}, {
label: 'Überprüfungen',
}
]
},
vendors: {
label: "Lieferanten",
labelSingle: "Lieferant",
isStandardEntity: true,
redirect:true,
numberRangeHolder: "vendorNumber",
historyItemHolder: "vendor",
supabaseSortColumn: "vendorNumber",
supabaseSelectWithInformation: "*, contacts(*)",
filters: [{
name: "SEPA nicht erteilt",
"filterFunction": function (row) {
return !row.hasSEPA
},
},{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: 'vendorNumber',
label: "Lieferantennummer",
inputType: "text",
inputIsNumberRange: true
},
{
key: "name",
required: true,
label: "Name",
title: true,
inputType: "text"
},
{
key: "infoData.streetNumber",
label: "Straße + Hausnummer",
inputType: "text",
disabledInTable: true
},
{
key: "infoData.special",
label: "Adresszusatz",
inputType: "text",
disabledInTable: true
},
{
key: "infoData.zip",
label: "Postleitzahl",
inputType: "number",
disabledInTable: true,
inputChangeFunction: async function (row) {
if(row.infoData.zip) {
row.infoData.city = (await useZipCheck(row.infoData.zip))
}
},
},
{
key: "infoData.city",
label: "Stadt",
inputType: "text",
disabledInTable: true
},
{
key: "infoData.country",
label: "Land",
inputType: "select",
selectDataType: "countrys",
selectOptionAttribute: "name",
selectValueAttribute: "name",
disabledInTable: true
},
{
key: "address",
label: "Adresse",
component: address
},
{
key: "infoData.tel",
label: "Telefon",
inputType: "text"
},
{
key: "infoData.email",
label: "E-Mail",
inputType: "text"
},
{
key: "infoData.web",
label: "Web",
inputType: "text"
},
{
key: "infoData.ustid",
label: "USt-Id",
inputType: "text"
},
{
key: "hasSEPA",
label: "SEPA Mandat erteilt",
inputType: "bool",
component: sepa
},
{
key: "notes",
label: "Notizen",
inputType: "textarea"
},
{
key: "profiles",
label: "Berechtigte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
},
],
showTabs: [
{
label: 'Informationen',
},{
label: 'Ansprechpartner',
}, {
label: 'Dateien',
}
]
},
messages: {
label: "Nachrichten",
labelSingle: "Nachricht"
},
spaces: {
label: "Lagerplätze",
labelSingle: "Lagerplatz",
isStandardEntity: true,
supabaseSelectWithInformation: "*, files(*)",
supabaseSortColumn: "spaceNumber",
redirect: true,
numberRangeHolder: "spaceNumber",
historyItemHolder: "space",
filters:[{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
inputColumns: [
"Allgemeines",
"Ort"
],
templateColumns: [
{
key: "name",
label: "Name",
inputType: "text",
required: true,
title: true,
inputColumn: "Allgemeines"
},
{
key: 'spaceNumber',
label: "Lagerplatznr.",
inputType: "text",
inputIsNumberRange: true,
inputColumn: "Allgemeines"
},
{
key: "type",
label: "Typ",
inputType: "select",
required: true,
selectValueAttribute: "label",
selectManualOptions: [
{label:"Standort"},
{label:"Regalplatz"},
{label:"Kiste"},
{label:"Palettenplatz"},
{label:"Sonstiges"}
],
inputColumn: "Allgemeines"
},
{
key: "parentSpace",
label: "Übergeordneter Lagerplatz",
inputType: "select",
selectDataType: "spaces",
selectOptionAttribute: "spaceNumber",
selectValueAttribute: "id",
inputColumn: "Allgemeines"
},
{
key: "infoData.streetNumber",
label: "Straße + Hausnummer",
inputType: "text",
disabledInTable: true,
inputColumn: "Ort"
},
{
key: "infoData.special",
label: "Adresszusatz",
inputType: "text",
disabledInTable: true,
inputColumn: "Ort"
},
{
key: "infoData.zip",
label: "Postleitzahl",
inputType: "number",
disabledInTable: true,
inputColumn: "Ort",
inputChangeFunction: async function (row) {
if(row.infoData.zip) {
row.infoData.city = (await useZipCheck(row.infoData.zip))
}
},
},
{
key: "infoData.city",
label: "Stadt",
inputType: "text",
disabledInTable: true,
inputColumn: "Ort"
},
{
key: "infoData.country",
label: "Land",
inputType: "select",
selectDataType: "countrys",
selectOptionAttribute: "name",
selectValueAttribute: "name",
disabledInTable: true,
inputColumn: "Ort"
},
{
key: "address",
label: "Adresse",
component: address
},
{
key: "description",
label: "Beschreibung",
inputType: "textarea",
}
],
showTabs: [
{
label: 'Informationen',
}, {
label: 'Dateien',
},{label: 'Inventarartikel'}
]
},
users: {
label: "Benutzer",
labelSingle: "Benutzer"
},
createddocuments: {
label: "Dokumente",
labelSingle: "Dokument"
},
incominginvoices: {
label: "Eingangsrechnungen",
labelSingle: "Eingangsrechnung",
redirect:true
},
inventoryitems: {
label: "Inventarartikel",
labelSingle: "Inventarartikel",
isStandardEntity: true,
supabaseSelectWithInformation: "*, files(*), vendor(id,name), currentSpace(id,name)",
redirect: true,
numberRangeHolder: "articleNumber",
historyItemHolder: "inventoryitem",
inputColumns: [
"Allgemeines",
"Anschaffung"
],
filters:[{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: "name",
label: "Name",
title: true,
required: true,
inputType: "text",
inputColumn: "Allgemeines"
},
{
key: "usePlanning",
label: "In Plantafel anzeigen",
inputType: "bool",
inputColumn: "Allgemeines",
component: usePlanning
},
{
key: "description",
label: "Beschreibung",
inputType: "textarea",
},
{
key: "currentSpace",
label: "Aktueller Lagerplatz",
inputType: "select",
selectDataType: "spaces",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
inputColumn: "Allgemeines",
component: space
},
{
key: "articleNumber",
label: "Artikelnummer",
inputType: "text",
inputIsNumberRange: true,
inputColumn: "Allgemeines"
},
{
key: "serialNumber",
label: "Seriennummer",
inputType: "text",
inputColumn: "Allgemeines"
},
{
key: "purchaseDate",
label: "Kaufdatum",
inputType: "date",
inputColumn: "Anschaffung"
},
{
key: "vendor",
label: "Lieferant",
inputType: "select",
selectDataType: "vendors",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
inputColumn: "Anschaffung",
component: vendor
},
{
key: "quantity",
label: "Menge",
inputType: "number",
inputColumn: "Allgemeines",
disabledFunction: function (item) {
return item.serialNumber
},
helpComponent: quantity
},
{
key: "purchasePrice",
label: "Kaufpreis",
inputType: "number",
inputStepSize: "0.01",
inputColumn: "Anschaffung"
},
{
key: "manufacturer",
label: "Hersteller",
inputType: "text",
inputColumn: "Anschaffung"
},
{
key: "manufacturerNumber",
label: "Herstellernummer",
inputType: "text",
inputColumn: "Anschaffung"
},
{
key: "profiles",
label: "Berechtigte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
},
{
key: "currentValue",
label: "Aktueller Wert",
inputType: "number",
inputStepSize: "0.01",
inputColumn: "Anschaffung"
},
],
showTabs: [
{
label: 'Informationen',
}, {
label: 'Dateien',
}
]
},
inventoryitemgroups: {
label: "Inventarartikelgruppen",
labelSingle: "Inventarartikelgruppe",
isStandardEntity: true,
historyItemHolder: "inventoryitemgroup",
supabaseSelectWithInformation: "*",
redirect: true,
filters:[{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: "name",
label: "Name",
title: true,
required: true,
inputType: "text",
},
{
key: "description",
label: "Beschreibung",
inputType: "textarea"
},
{
key: "usePlanning",
label: "In Plantafel anzeigen",
inputType: "bool",
component: usePlanning
},{
key: "inventoryitems",
label: "Inventarartikel",
inputType: "select",
selectDataType: "inventoryitems",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
selectMultiple: true,
required: true,
component: inventoryitemsWithLoad
},{
key: "profiles",
label: "Berechtigte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
},
],
showTabs: [
{
label: 'Informationen',
}
]
},
services: {
label: "Leistungen",
labelSingle: "Leistung",
isStandardEntity: true,
redirect: true,
supabaseSelectWithInformation: "*, unit(*)",
historyItemHolder: "service",
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: "unit",
label: "Einheit",
component: unit,
inputType: "select",
selectDataType: "units",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},
{
key: "sellingPrice",
label: "Verkaufspreis",
component: sellingPrice,
},
{
key: "taxPercentage",
label: "Umsatzsteuer",
inputType: "select",
selectOptionAttribute: "label",
selectValueAttribute: 'key',
required: true,
selectManualOptions: [
{label: "19 %", key: 19},
{label: "7 %", key: 7},
{label: "0 %", key: 0}]
//TODO: Default Value
},
{
key: "servicecategories",
label: "Leistungskategorien",
inputType: "select",
selectDataType: "servicecategories",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
selectMultiple: true,
component: serviceCategories
},
{
key: "sellingPriceComposed.worker",
label: "Verkaufspreis Personal pro Einheit",
inputType: "number",
inputTrailing: "EUR",
inputChangeFunction: function (row) {
if(row.sellingPriceComposed.worker) {
row.sellingPriceComposed.total = row.sellingPriceComposed.worker + (row.sellingPriceComposed.material || 0)
row.sellingPrice = row.sellingPriceComposed.total
}
},
component: sellingPriceComposedWorker
},
{
key: "sellingPriceComposed.material",
label: "Verkaufspreis Material pro Einheit",
inputType: "number",
inputTrailing: "EUR",
inputChangeFunction: function (row) {
if(row.sellingPriceComposed.material) {
row.sellingPriceComposed.total = (row.sellingPriceComposed.worker || 0) + row.sellingPriceComposed.material
row.sellingPrice = row.sellingPriceComposed.total
}
},
component: sellingPriceComposedMaterial
},
{
key: "materialComposing",
label: "Zusammensetzung Materialpreis pro Einheit",
inputType: "materialComposing",
},
{
key: "sellingPriceComposed.total",
label: "Verkaufspreis Gesamt pro Einheit",
inputType: "number",
inputTrailing: "EUR",
/*disabledFunction: function (item) {
return item.sellingPriceComposed.worker || item.sellingPriceComposed.material
},*/
inputChangeFunction: function (row) {
if(row.sellingPriceComposed.worker) {
row.sellingPriceComposed.material = row.sellingPriceComposed.total - row.sellingPriceComposed.worker
} else if(row.sellingPriceComposed.material) {
row.sellingPriceComposed.worker = row.sellingPriceComposed.total - row.sellingPriceComposed.material
}
},
component: sellingPriceComposedTotal
},
{
key: "description",
label: "Beschreibung",
inputType:"textarea"
},
],
showTabs: [
{
label: 'Informationen',
}
]
},
events: {
label: "Termine",
labelSingle: "Termin",
isStandardEntity: true,
historyItemHolder: "event",
supabaseSelectWithInformation: "*, project(id,name)",
redirect: true,
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: "startDate",
label: "Start",
required: true,
inputType: "datetime",
component: startDateTime
},
{
key: "endDate",
label: "Ende",
required: true,
inputType: "datetime",
component: endDateTime
},/*{
key: "eventtype",
label: "Typ",
inputType: "select",
selectManualOptions: ["Umsetzung","Vor Ort Termin", "Büro", "Sonstiges"],
},*/{
key: "link",
label: "Link",
inputType: "text"
},{
key: "notes",
label: "Notizen",
inputType: "textarea"
},
{
key: "project",
label: "Projekt",
component: project,
inputType: "select",
selectDataType: "projects",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},{
key: "vehicles",
label: "Fahrzeuge",
inputType: "select",
selectDataType: "vehicles",
selectOptionAttribute: "licensePlate",
selectSearchAttributes: ['licensePlate'],
selectMultiple: true,
component: vehiclesWithLoad,
},{
key: "inventoryitems",
label: "Inventarartikel",
inputType: "select",
selectDataType: "inventoryitems",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
selectMultiple: true,
component: inventoryitemsWithLoad
},{
key: "inventoryitemgroups",
label: "Inventarartikelgruppen",
inputType: "select",
selectDataType: "inventoryitemgroups",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
selectMultiple: true,
component: inventoryitemgroupsWithLoad
},{
key: "profiles",
label: "Beteiligte Benutzer",
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
selectMultiple: true,
component: profiles
}
],
showTabs: [
{
label: 'Informationen',}
]
},
profiles: {
label: "Mitarbeiter",
labelSingle: "Mitarbeiter",
redirect: true,
historyItemHolder: "profile"
},
workingtimes: {
label: "Anwesenheiten",
labelSingle: "Anwesenheit",
redirect: true,
redirectToList: true
},
texttemplates: {
label: "Textvorlagen",
labelSingle: "Textvorlage"
},
bankstatements: {
label: "Kontobewegungen",
labelSingle: "Kontobewegung",
historyItemHolder: "bankStatement",
},
statementallocations: {
label: "Bankzuweisungen",
labelSingle: "Bankzuweisung"
},
productcategories: {
label: "Artikelkategorien",
labelSingle: "Artikelkategorie",
isStandardEntity: true,
redirect: true,
supabaseSelectWithInformation: "*",
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: "description",
label: "Beschreibung",
inputType: "textarea"
}
],
showTabs: [
{
label: 'Informationen',
}
]
},
servicecategories: {
label: "Leistungskategorien",
labelSingle: "Leistungskategorie",
isStandardEntity: true,
redirect: true,
supabaseSelectWithInformation: "*",
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: "description",
label: "Beschreibung",
inputType: "textarea"
}
],
showTabs: [
{
label: 'Informationen',
}
]
},
trackingtrips: {
label: "Fahrten",
labelSingle: "Fahrt",
redirect: true,
historyItemHolder: "trackingtrip",
},
projecttypes: {
label: "Projekttypen",
labelSingle: "Projekttyp",
redirect: true,
historyItemHolder: "projecttype"
},
checks: {
label: "Überprüfungen",
labelSingle: "Überprüfung",
isStandardEntity: true,
supabaseSelectWithInformation: "*, vehicle(id,licensePlate), profile(id, fullName), inventoryitem(name), files(*)",
redirect: true,
historyItemHolder: "check",
filters: [{
name: "Archivierte ausblenden",
default: true,
"filterFunction": function (row) {
if(!row.archived) {
return true
} else {
return false
}
}
}],
templateColumns: [
{
key: "name",
label: "Name",
title: true,
required: true,
inputType: "text"
},
{
key: "vehicle",
label: "Fahrzeug",
component: vehicle,
inputType: "select",
selectDataType: "vehicles",
selectOptionAttribute: "licensePlate",
selectSearchAttributes: ['licensePlate'],
},
{
key: "profile",
label: "Person",
component: profile,
inputType: "select",
selectDataType: "profiles",
selectOptionAttribute: "fullName",
selectSearchAttributes: ['fullName'],
},
{
key: "inventoryitem",
label: "Inventarartikel",
inputType: "select",
selectDataType: "inventoryitems",
selectOptionAttribute: "name",
selectSearchAttributes: ['name'],
},
{
key: "description",
label: "Beschreibung",
inputType: "textarea"
}
],
showTabs: [
{
label: 'Informationen',
}, {label: 'Dateien'}, {label: 'Ausführungen'}]
},
roles: {
label: "Rollen",
labelSingle: "Rolle",
redirect:true,
historyItemHolder: "role",
filters: [],
templateColumns: [
{
key: "name",
label: "Name"
}, {
key: "description",
label: "Beschreibung"
}
]
},
}
const documentTypesForCreation = ref({
invoices: {
label: "Rechnungen",
labelSingle: "Rechnung",
},
serialInvoices: {
label: "Serienrechnungen",
labelSingle: "Serienrechnung",
},
advanceInvoices: {
label: "Abschlagsrechnungen",
labelSingle: "Abschlagsrechnung"
},
cancellationInvoices: {
label: "Stornorechnungen",
labelSingle: "Stornorechnung"
},
quotes: {
label: "Angebote",
labelSingle: "Angebot"
},
deliveryNotes: {
label: "Lieferscheine",
labelSingle: "Lieferschein"
},
confirmationOrders: {
label: "Auftragsbestätigungen",
labelSingle: "Auftragsbestätigung"
}
})
const events = ref([])
const customers = ref([])
const tasks = ref([])
const projects = ref([])
const documents = ref([])
const spaces = ref([])
const units = ref([])
const times = ref([])
const products = ref([])
const movements = ref([])
const forms = ref([])
const contracts = ref([])
const formSubmits = ref([])
const contacts = ref([])
const vendors = ref([])
const incominginvoices = ref([])
const bankAccounts = ref([])
const bankstatements = ref([])
const bankrequisitions = ref([])
const historyItems = ref([])
const notifications = ref([])
const accounts = ref([])
const taxTypes = ref([])
const plants = ref([])
const chats = ref([])
const messages = ref([])
const createddocuments = ref([])
const workingtimes = ref([])
const phasesTemplates = ref([])
const emailAccounts = ref([])
const texttemplates =ref([])
const resources =ref([])
async function fetchData () {
await fetchDocuments()
await fetchEvents()
await fetchTasks()
await fetchProjects()
await fetchTimes()
await fetchCustomers()
await fetchContracts()
await fetchContacts()
await fetchForms()
await fetchFormSubmits()
await fetchProducts()
await fetchUnits()
await fetchMovements()
await fetchSpaces()
await fetchVendors()
await fetchIncomingInvoices()
await fetchBankAccounts()
await fetchBankStatements()
await fetchBankRequisitions()
await fetchHistoryItems()
await fetchNotifications()
await fetchAccounts()
await fetchTaxTypes()
await fetchPlants()
await fetchChats()
await fetchMessages()
await fetchCreatedDocuments()
await fetchWorkingTimes()
await fetchPhasesTemplates()
await fetchEmailAccounts()
await fetchTextTemplates()
await fetchResources()
}
function clearStore () {
events.value= []
customers.value= []
tasks.value= []
projects.value= []
documents.value= []
spaces.value= []
units.value= []
times.value= []
products.value= []
movements.value= []
forms.value= []
contracts.value= []
formSubmits.value= []
contacts.value= []
vendors.value= []
incominginvoices.value= []
bankAccounts.value= []
bankstatements.value= []
bankrequisitions.value= []
historyItems.value = []
notifications.value = []
accounts.value = []
taxTypes.value = []
plants.value = []
chats.value = []
messages.value = []
createddocuments.value = []
workingtimes.value = []
phasesTemplates.value = []
emailAccounts.value = []
texttemplates.value = []
resources.value = []
}
var deepDiffMapper = function () {
return {
VALUE_CREATED: 'created',
VALUE_UPDATED: 'updated',
VALUE_DELETED: 'deleted',
VALUE_UNCHANGED: 'unchanged',
map: function(obj1, obj2, k = null) {
if (this.isFunction(obj1) || this.isFunction(obj2)) {
throw 'Invalid argument. Function given, object expected.';
}
if (this.isValue(obj1) || this.isValue(obj2)) {
return {
type: this.compareValues(obj1, obj2),
data: {o: obj1, n: obj2, k: k}//obj1 === undefined ? obj2 : obj1
};
}
var diff = {};
for (var key in obj1) {
if (this.isFunction(obj1[key])) {
continue;
}
var value2 = undefined;
if (obj2[key] !== undefined) {
value2 = obj2[key];
}
diff[key] = this.map(obj1[key], value2,key);
}
for (var key in obj2) {
if (this.isFunction(obj2[key]) || diff[key] !== undefined) {
continue;
}
diff[key] = this.map(undefined, obj2[key],key);
}
return diff;
},
compareValues: function (value1, value2) {
if (value1 === value2) {
return this.VALUE_UNCHANGED;
}
if (this.isDate(value1) && this.isDate(value2) && value1.getTime() === value2.getTime()) {
return this.VALUE_UNCHANGED;
}
if (value1 === undefined) {
return this.VALUE_CREATED;
}
if (value2 === undefined) {
return this.VALUE_DELETED;
}
return this.VALUE_UPDATED;
},
isFunction: function (x) {
return Object.prototype.toString.call(x) === '[object Function]';
},
isArray: function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
},
isDate: function (x) {
return Object.prototype.toString.call(x) === '[object Date]';
},
isObject: function (x) {
return Object.prototype.toString.call(x) === '[object Object]';
},
isValue: function (x) {
return !this.isObject(x) && !this.isArray(x);
}
}
}();
const generateHistoryItems = async (dataType,newData, oldData=null) => {
//console.log(oldData)
//console.log(newData)
if(dataTypes[dataType].historyItemHolder){
let itemsToCreate = []
const checkPropState = (key,propContent) => {
//console.log(propContent)
if(propContent.type && propContent.data){
if(propContent.type === "updated" ||propContent.type === "created"){
createHistoryItem(key,propContent)
}
} else {
for (let prop in propContent) {
checkPropState(prop,propContent[prop])
}
}
}
const createHistoryItem = (key,prop) => {
//console.log("OLD: " + prop.data.o)
//console.log("NEW: " + prop.data.n)
let name = "" || key
let oldVal = prop.data.o || "-"
let newVal = prop.data.n || "-"
/*console.log(key)
console.log(oldVal)
console.log(newVal)*/
if(key === "project") {
name = "Projekt"
oldVal = oldVal !== "-" ? projects.value.find(i => i.id === prop.data.o).name : "-"
newVal = projects.value.find(i => i.id === prop.data.n).name
} else if (key === "title") {
name = "Titel"
} else if(key === "type") {
name = "Typ"
} else if(key === "notes") {
name = "Notizen"
} else if(key === "link") {
name = "Link"
} else if(key === "start") {
name = "Start"
oldVal = dayjs(prop.data.o).format("DD.MM.YYYY HH:mm")
newVal = dayjs(prop.data.n).format("DD.MM.YYYY HH:mm")
} else if(key === "end") {
name = "Ende"
oldVal = dayjs(prop.data.o).format("DD.MM.YYYY HH:mm")
newVal = dayjs(prop.data.n).format("DD.MM.YYYY HH:mm")
} else if(key === "birthday") {
name = "Geburtstag"
oldVal = dayjs(prop.data.o).format("DD.MM.YYY")
newVal = dayjs(prop.data.n).format("DD.MM.YYY")
} else if(key === "resources") {
name = "Resourcen"
oldVal = prop.data.o.map(i => i.title).join(", ")
newVal = prop.data.n.map(i => i.title).join(", ")
} else if(key === "customerNumber") {
name = "Kundennummer"
} else if(key === "active") {
name = "Aktiv"
if(oldVal === true){
oldVal = "Aktiv"
newVal = "Gesperrt"
} else if(oldVal === "-") {
oldVal = "Gesperrt"
newVal = "Aktiv"
}
} else if(key === "isCompany") {
name = "Firmenkunde"
if(oldVal === true){
oldVal = "Firma"
newVal = "Privatkunde"
} else if(oldVal === "-") {
oldVal = "Privatkunde"
newVal = "Firma"
}
} else if(key === "special") {
name = "Adresszusatz"
} else if(key === "street") {
name = "Straße & Hausnummer"
} else if(key === "city") {
name = "Ort"
} else if(key === "zip") {
name = "Postleitzahl"
} else if(key === "country") {
name = "Land"
} else if(key === "web") {
name = "Webseite"
} else if(key === "email") {
name = "E-Mail"
} else if(key === "tel") {
name = "Telefon"
} else if(key === "ustid") {
name = "USt-ID"
} else if(key === "role") {
name = "Rolle"
} else if(key === "phoneHome") {
name = "Festnetz"
} else if(key === "phoneMobile") {
name = "Mobiltelefon"
} else if(key === "salutation") {
name = "Anrede"
} else if(key === "firstName") {
name = "Vorname"
} else if(key === "lastName") {
name = "Nachname"
} else if(key === "name") {
name = "Name"
} else if(key === "approved") {
name = "Genehmigt"
} else if(key === "manufacturer") {
name = "Hersteller"
} else if(key === "purchasePrice") {
name = "Kaufpreis"
} else if(key === "purchaseDate") {
name = "Kaufdatum"
} else if(key === "serialNumber") {
name = "Seriennummer"
} else if(key === "usePlanning") {
name = "In Plantafel verwenden"
} else if(key === "currentSpace") {
name = "In Plantafel verwenden"
} else if(key === "customer") {
name = "Kunde"
if(prop.data.o) oldVal = customers.value.find(i => i.id === prop.data.o).name
if(prop.data.n) newVal = customers.value.find(i => i.id === prop.data.n).name
} else if(key === "vendor") {
name = "Lieferant"
if(prop.data.o) oldVal = vendors.value.find(i => i.id === prop.data.o).name
if(prop.data.n) newVal = vendors.value.find(i => i.id === prop.data.n).name
} else if(key === "description") {
name = "Beschreibung"
} else if(key === "categorie") {
name = "Kategorie"
} else if(key === "profile") {
name = "Mitarbeiter"
if(prop.data.o) oldVal = profileStore.profiles.find(i => i.id === prop.data.o).fullName
if(prop.data.n) newVal = profileStore.profiles.find(i => i.id === prop.data.n).fullName
} else if(key === "plant") {
name = "Objekt"
if(prop.data.o) oldVal = plants.value.find(i => i.id === prop.data.o).name
if(prop.data.n) newVal = plants.value.find(i => i.id === prop.data.n).name
} else if(key === "annualPaidLeaveDays") {
name = "Urlaubstage"
} else if(key === "employeeNumber") {
name = "Mitarbeiternummer"
} else if(key === "weeklyWorkingDays") {
name = "Wöchentliche Arbeitstage"
} else if(key === "weeklyWorkingHours") {
name = "Wöchentliche Arbeitszeit"
} else if(key === "customerRef") {
name = "Referenz des Kunden"
} else if(key === "licensePlate") {
name = "Kennzeichen"
}else if(key === "tankSize") {
name = "Tankvolumen"
}else if(key === "towingCapacity") {
name = "Anhängelast"
}else if(key === "color") {
name = "Farbe"
}else if(key === "customPaymentDays") {
name = "Zahlungsziel in Tagen"
}else if(key === "powerInKW") {
name = "Leistung"
} else if(key === "driver") {
name = "Fahrer"
if(prop.data.o) oldVal = profileStore.profiles.find(i => i.id === prop.data.o).fullName
if(prop.data.n) newVal = profileStore.profiles.find(i => i.id === prop.data.n).fullName
} else if(key === "projecttype") {
name = "Projekttyp"
//TODO: Resolving for Projecttypes
//if(prop.data.o) oldVal = profiles.value.find(i => i.id === prop.data.o).fullName
//if(prop.data.n) newVal = profiles.value.find(i => i.id === prop.data.n).fullName
} else if(key === "fixed") {
name = "Festgeschrieben"
if(newVal === true){
oldVal = "Nein"
newVal = "Ja"
} else if(newVal === false) {
oldVal = "Ja"
newVal = "Nein"
}
} else if(key === "archived") {
name = "Archiviert"
if(newVal === true){
oldVal = "Nein"
newVal = "Ja"
} else if(newVal === false) {
oldVal = "Ja"
newVal = "Nein"
}
}
let text = ""
if(prop.type === "updated" && newVal !== "-" && oldVal !== "-") {
text = `Gerändert: ${name} von "${oldVal}" zu "${newVal}"`
} else if(prop.type === "updated" && newVal !== "-" && oldVal === "-") {
text = `Hinzugefügt: ${name} "${newVal}"`
} else if(prop.type === "created") {
text = `Hinzugefügt: ${name} "${newVal}"`
} else if(prop.type === "updated" && newVal === "-" && oldVal !== "-") {
text = `Entfernt: ${name} "${oldVal}"`
}
let historyItem = {
text: text,
createdBy: profileStore.activeProfile.id,
oldVal: prop.data.o,
newVal: prop.data.n,
tenant: profileStore.currentTenant
}
historyItem[dataTypes[dataType].historyItemHolder] = newData.id
const checkIfNaN = (x) => {
return typeof x === "number" && x !== x;
}
//console.log(key)
//console.log(checkIfNaN(key))
if(key !== "fullName" && key !== "phases") {
//console.log(historyItem)
itemsToCreate.push(historyItem)
}
}
if(oldData) {
let result = deepDiffMapper.map(oldData,newData)
//console.log(result)
for (let prop in result) {
//console.log(prop)
checkPropState(prop,result[prop])
}
} else {
let historyItem = {
text: `${dataTypes[dataType].labelSingle} erstellt`,
createdBy: profileStore.activeProfile.id,
tenant: profileStore.currentTenant
}
historyItem[dataTypes[dataType].historyItemHolder] = newData.id
//console.log(historyItem)
itemsToCreate.push(historyItem)
}
const {data,error} = await supabase.from("historyitems").insert(itemsToCreate)
if(error) {
console.log(error)
} else {
fetchHistoryItems()
}
}
}
async function createNewItem (dataType,data){
if(typeof(data) === 'object') {
data = {...data, tenant: profileStore.currentTenant}
} else if(typeof(data) === 'array') {
data.map(i => {
return {
...i,
tenant: profileStore.currentTenant
}
})
}
console.log(dataType)
if(dataTypes[dataType].numberRangeHolder) {
if(!data[dataTypes[dataType].numberRangeHolder]) {
data[dataTypes[dataType].numberRangeHolder] = await useFunctions().useNextNumber(dataType)
}
} else if(dataType === "createddocuments" && data.type !== "serialInvoices") {
/*if(data.state !== "Entwurf") {
console.log(data.type)
let type = ""
if(data.type === "advanceInvoices"){
type = "invoices"
} else {
type = data.type
}
const numberRange = useNumberRange(type)
data.documentNumber = await numberRange.useNextNumber()
}*/
}
const {data:supabaseData,error:supabaseError} = await supabase
.from(dataType)
.insert(data)
.select()
if(supabaseError) {
console.log(supabaseError)
toast.add({title: "Es ist ein Fehler bei der Erstellung aufgetreten", color: "rose"})
} else if (supabaseData) {
console.log(supabaseData)
let returnData = supabaseData[0]
await generateHistoryItems(dataType, supabaseData[0])
if(!["statementallocations","absencerequests", "productcategories", "servicecategories", "projecttypes", "checks", "profiles","services", "inventoryitems", "inventoryitemgroups", "incominginvoices"].includes(dataType) ){
await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
}
toast.add({title: `${dataTypes[dataType].labelSingle} hinzugefügt`})
if(dataTypes[dataType].redirect) {
if(dataTypes[dataType].isStandardEntity) {
await router.push(dataTypes[dataType].redirectToList ? `/standardEntity/${dataType}` : `/standardEntity/${dataType}/show/${returnData.id}`)
} else {
await router.push(dataTypes[dataType].redirectToList ? `/${dataType}` : `/${dataType}/show/${returnData.id}`)
}
}
return supabaseData
}
}
async function updateItem (dataType, data, oldData = null) {
//console.log(dataType, data)
//Temporary Fix TODO: Remove and build Solution
data = JSON.parse(JSON.stringify(data))
delete data.users
if(oldData) {
oldData = JSON.parse(JSON.stringify(oldData))
delete oldData.users
}
const {tenants, ...newData} = data
/*if(dataType === "createddocuments" && data.type !== "serialInvoices") {
if(data.state !== "Entwurf") {
console.log(data.type)
let type = ""
if(data.type === "advanceInvoices"){
type = "invoices"
} else {
type = data.type
}
const numberRange = useNumberRange(type)
data.documentNumber = await numberRange.useNextNumber()
}
}*/
await generateHistoryItems(dataType,data,oldData)
const {data:supabaseData,error: supabaseError} = await supabase
.from(dataType)
.update(newData)
.eq('id',newData.id)
.select()
if(supabaseError) {
console.log(supabaseError)
toast.add({title: `Fehler beim Speichern`, color: 'rose'})
} else if(supabaseData) {
//await eval(dataType + '.value[' + dataType + '.value.findIndex(i => i.id === ' + JSON.stringify(data.id) + ')] = ' + JSON.stringify(supabaseData[0]))
//if(dataType === 'profiles') await fetchProfiles()
toast.add({title: `${dataTypes[dataType].labelSingle} gespeichert`})
if(dataTypes[dataType].redirect) {
if(dataTypes[dataType].isStandardEntity) {
await router.push(dataTypes[dataType].redirectToList ? `/standardEntity/${dataType}` : `/standardEntity/${dataType}/show/${data.id}`)
} else {
await router.push(dataTypes[dataType].redirectToList ? `/${dataType}` : `/${dataType}/show/${data.id}`)
}
}
return supabaseData
}
}
const uploadFiles = async (formData, files, upsert) => {
const uploadSingleFile = async (file) => {
const {data:createdFileData,error:createdFileError} = await supabase
.from("files")
.insert({
tenant: profileStore.currentTenant,
})
.select()
.single()
if(createdFileError){
console.log(createdFileError)
toast.add({title: "Hochladen fehlgeschlagen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
} else if(createdFileData) {
console.log(createdFileData)
const {data:uploadData, error: uploadError} = await supabase
.storage
.from("filesdev")
.upload(`${profileStore.currentTenant}/filesbyid/${createdFileData.id}/${file.name}`, file, {upsert: upsert})
if(uploadError) {
console.log(uploadError)
console.log(uploadError.statusCode)
if(uploadError.statusCode === '400') {
console.log("is 400")
toast.add({title: "Hochladen fehlgeschlagen", description: "Die Datei enthält ungültige Zeichen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
} else if(uploadError.statusCode === '409') {
console.log("is 409")
toast.add({title: "Hochladen fehlgeschlagen", description: "Es existiert bereits eine Datei mit diesem Namen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
} else {
toast.add({title: "Hochladen fehlgeschlagen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
}
} else if(uploadData) {
const {data:updateFileData, error:updateFileError} = await supabase
.from("files")
.update({
...formData,
path: uploadData.path,
})
.eq("id", createdFileData.id)
if(updateFileError) {
console.log(updateFileError)
toast.add({title: "Hochladen fehlgeschlagen", icon: "i-heroicons-x-circle", color: "rose", timeout: 10000})
} else {
toast.add({title: "Hochladen erfolgreich"})
}
}
}
}
if(files.length === 1) {
await uploadSingleFile(files[0])
} else if( files.length > 1) {
for(let i = 0; i < files.length; i++){
await uploadSingleFile(files[i])
}
}
}
async function fetchBankAccounts () {
bankAccounts.value = (await supabase.from("bankaccounts").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchBankStatements () {
bankstatements.value = (await supabase.from("bankstatements").select().eq('tenant', profileStore.currentTenant).order("date", {ascending:false})).data
}
async function fetchBankRequisitions () {
bankrequisitions.value = (await supabase.from("bankrequisitions").select().eq('status', "LN")).data
}
async function fetchEvents () {
events.value = (await supabase.from("events").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchContracts () {
contracts.value = (await supabase.from("contracts").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchContacts () {
contacts.value = (await supabase.from("contacts").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchCustomers () {
customers.value = (await supabase.from("customers").select().eq('tenant', profileStore.currentTenant).order("customerNumber", {ascending:true})).data
}
async function fetchTasks () {
tasks.value = (await supabase.from("tasks").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchForms () {
forms.value = (await supabase.from("forms").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchFormSubmits () {
formSubmits.value = (await supabase.from("formSubmits").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchProducts () {
products.value = (await supabase.from("products").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchUnits () {
units.value = (await supabase.from("units").select()).data
}
async function fetchProjects () {
projects.value = (await supabase.from("projects").select().eq("tenant",profileStore.currentTenant)).data
}
async function fetchSpaces () {
spaces.value = (await supabase.from("spaces").select().eq('tenant', profileStore.currentTenant).order("spaceNumber", {ascending:true})).data
}
async function fetchMovements () {
movements.value = (await supabase.from("movements").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchTimes () {
times.value = (await supabase.from("times").select().eq('tenant', profileStore.currentTenant).order("startDate", {ascending:false})).data
}
async function fetchHistoryItems () {
historyItems.value = (await supabase.from("historyitems").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchVendors () {
vendors.value = (await supabase.from("vendors").select().eq('tenant', profileStore.currentTenant).order("vendorNumber", {ascending:true})).data
}
async function fetchIncomingInvoices () {
incominginvoices.value = (await supabase.from("incominginvoices").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchNotifications () {
notifications.value = (await supabase.from("notifications").select().eq('tenant', profileStore.currentTenant).order("created_at", {ascending: false})).data
}
async function fetchAccounts () {
accounts.value = (await supabase.from("accounts").select()).data
}
async function fetchTaxTypes () {
taxTypes.value = (await supabase.from("taxtypes").select()).data
}
async function fetchPlants () {
plants.value = (await supabase.from("plants").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchChats() {
chats.value = (await supabase.from("chats").select()).data
}
async function fetchMessages() {
messages.value = (await supabase.from("messages").select().eq('tenant', profileStore.currentTenant).order('created_at', {ascending:true})).data
}
async function fetchCreatedDocuments() {
createddocuments.value = (await supabase.from("createddocuments").select().eq('tenant', profileStore.currentTenant).order('created_at', {ascending:true})).data
}
async function fetchWorkingTimes() {
workingtimes.value = (await supabase.from("workingtimes").select().eq('tenant', profileStore.currentTenant).order('created_at', {ascending:true})).data
}
async function fetchPhasesTemplates() {
phasesTemplates.value = (await supabase.from("phasesTemplates").select().eq('tenant', profileStore.currentTenant).order('created_at', {ascending:true})).data
}
async function fetchEmailAccounts() {
emailAccounts.value = (await supabase.from("emailAccounts").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchTextTemplates() {
texttemplates.value = (await supabase.from("texttemplates").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchResources() {
resources.value = (await supabase.from("resources").select().eq('tenant', profileStore.currentTenant)).data
}
async function fetchDocuments () {
let tempDocuments = (await supabase.from("documents").select().eq('tenant', profileStore.currentTenant)).data
if(tempDocuments.length > 0){
let paths = []
tempDocuments.forEach(doc => {
paths.push(doc.path)
})
const {data,error} = await supabase.storage.from('files').createSignedUrls(paths,3600)
tempDocuments = tempDocuments.map((doc,index) => {
return {
...doc,
url: data[index].signedUrl
}
})
documents.value = tempDocuments
} else {
documents.value = []
}
}
async function addHistoryItem(text, user, elementId, resourceType) {
let data = {
user: user,
text: text
}
if(resourceType === "customers") {
data.customer = elementId
}
const {data:insertData,error:insertError} = await supabase
.from("historyItems")
.insert([addHistoryItemData.value])
.select()
if(insertError) {
console.log(insertError)
} else {
toast.add({title: "Eintrag erfolgreich erstellt"})
await fetchHistoryItems()
}
}
//Getters
const getDocumentsByProfileId = computed(() => (profileId) => {
return documents.value.filter(item => item.profile === profileId && !item.tags.includes("Archiviert"))
})
const getMessagesByChatId = computed(() => (chatId) => {
return messages.value.filter(i => i.destination === chatId)
})
const getTextTemplatesByDocumentType = computed(() => (documentType) => {
//console.log(documentType)
let type = ""
if(documentType === "serialInvoices") {
type = "invoices"
} else {
type = documentType
}
//console.log(type)
return texttemplates.value.filter(i => i.documentType === type)
})
const getStartedWorkingTimes = computed(() => () => {
return workingtimes.value.filter(i => !i.endDate)
})
const getStockByProductId = computed(() => (productId) => {
let productMovements = movements.value.filter(movement => movement.productId === productId && movement.projectId === null)
let count = 0
productMovements.forEach(movement => {
count += movement.quantity
})
return count
})
const getEventTypes = computed(() => {
return profileStore.ownTenant.calendarConfig.eventTypes
})
const getTimeTypes = computed(() => {
return profileStore.ownTenant.timeConfig.timeTypes
})
const getDocumentTags = computed(() => {
return profileStore.ownTenant.tags.documents
})
const getResources = computed(() => {
return [
...profiles.value.filter(i => i.tenant === profileStore.currentTenant).map(profile => {
return {
type: 'Mitarbeiter',
title: profile.fullName,
id: profile.id
}
}),
/*...vehicles.value.map(vehicle => {
return {
type: 'Fahrzeug',
title: vehicle.licensePlate,
id: `F-${vehicle.id}`
}
}),*/
...inventoryitems.value.filter(i=> i.usePlanning).map(item => {
return {
type: 'Inventar',
title: item.name,
id: `I-${item.id}`
}
})
]
})
const getEvents = computed(() => {
return [
...events.value.map(event => {
let eventColor = profileStore.ownTenant.calendarConfig.eventTypes.find(type => type.label === event.type).color
let title = ""
if(event.title) {
title = event.title
} else if(event.project) {
projects.value.find(i => i.id === event.project) ? projects.value.find(i => i.id === event.project).name : ""
}
return {
...event,
title: title,
borderColor: eventColor,
textColor: eventColor,
backgroundColor: "black"
}
}),
...absencerequests.value.map(absence => {
return {
id: absence.id,
resourceId: absence.user,
resourceType: "person",
title: `Abw.: ${absence.reason}`,
start: dayjs(absence.start).toDate(),
end: dayjs(absence.end).add(1,'day').toDate(),
allDay: true,
}
})
]
})
const getEventsByResource = computed(() => {
let tempEvents = []
events.value.forEach(event => {
console.log(event)
event.resources.forEach(resource => {
console.log(resource)
let eventColor = profileStore.ownTenant.calendarConfig.eventTypes.find(type => type.label === event.type).color
let title = ""
if(event.title) {
title = event.title
} /*else if(event.project) {
projects.value.find(i => i.id === event.project) ? projects.value.find(i => i.id === event.project).name : ""
}*/
tempEvents.push({
...event,
resourceId: /*resource.type !== 'Mitarbeiter' ? `${resource.type[0]}-${resource.id}`:*/ resource.id,
resourceType: "Mitarbeiter",
title: title,
borderColor: eventColor,
textColor: eventColor,
backgroundColor: "black"
})
})
})
return [
...tempEvents,
/*...events.value.map(event => {
let eventColor = profileStore.ownTenant.calendarConfig.eventTypes.find(type => type.label === event.type).color
return {
...event,
title: !event.title ? projects.value.find(i => i.id === event.project).name : event.title,
borderColor: eventColor,
textColor: eventColor,
backgroundColor: "black"
}
}),*/
...absencerequests.value.map(absence => {
return {
id: absence.id,
resourceId: absence.user,
resourceType: "person",
title: `Abw.: ${absence.reason}`,
start: dayjs(absence.start).toDate(),
end: dayjs(absence.end).add(1,'day').toDate(),
allDay: true
}
})
]
})
const getCostCentresComposed = computed(() => {
return [
/*...vehicles.value.map(vehicle => {
return {
label: "Fahrzeug - " + vehicle.licensePlate,
id: vehicle.id
}
}),*/
...projects.value.map(project => {
return {
label: "Projekt - " + project.name,
id: project.id
}
})
]
})
const getServiceById = computed(() => (itemId) => {
return services.value.find(item => item.id === itemId)
})
const getVendorById = computed(() => (itemId) => {
return vendors.value.find(item => item.id === itemId)
})
const getIncomingInvoiceById = computed(() => (itemId) => {
return incominginvoices.value.find(item => item.id === itemId)
})
const getContactById = computed(() => (itemId) => {
return contacts.value.find(item => item.id === itemId)
})
const getDocumentById = computed(() => (itemId) => {
return documents.value.find(item => item.id === itemId)
})
const getCustomerById = computed(() => (itemId) => {
return customers.value.find(item => item.id === itemId)
})
const getAccountById = computed(() => (accountId) => {
return accounts.value.find(item => item.id === accountId)
})
const getCreatedDocumentById = computed(() => (documentId) => {
return createddocuments.value.find(item => item.id === documentId)
})
const getBankAccountById = computed(() => (itemId) => {
return bankAccounts.value.find(item => item.id === itemId)
})
const getWorkingTimeById = computed(() => (itemId) => {
return workingtimes.value.find(item => item.id === itemId)
})
const getProjectById = computed(() => (itemId) => {
if(projects.value.find(i => i.id === itemId)) {
let project = projects.value.find(project => project.id === itemId)
/*let projectHours = 0
let projectTimes = times.value.filter(time => time.projectId === itemId)
projectTimes.forEach(time => projectHours += time.duration)
project.projectHours = projectHours*/
return project
} else {
return null
}
})
return {
uploadFiles,
generateHistoryItems,
dataTypes,
//Data
customers,
tasks,
projects,
documents,
spaces,
units,
times,
products,
movements,
forms,
contracts,
formSubmits,
contacts,
vendors,
incominginvoices,
bankAccounts,
bankstatements,
bankrequisitions,
historyItems,
notifications,
accounts,
taxTypes,
plants,
chats,
messages,
createddocuments,
workingtimes,
phasesTemplates,
emailAccounts,
texttemplates,
documentTypesForCreation,
//Functions
createNewItem,
updateItem,
fetchData,
clearStore,
fetchTimes,
fetchIncomingInvoices,
fetchDocuments,
fetchWorkingTimes,
//Getters
getDocumentsByProfileId,
getMessagesByChatId,
getTextTemplatesByDocumentType,
getStartedWorkingTimes,
getStockByProductId,
getEventTypes,
getTimeTypes,
getDocumentTags,
getResources,
getEvents,
getEventsByResource,
getCostCentresComposed,
getServiceById,
getVendorById,
getIncomingInvoiceById,
getContactById,
getDocumentById,
getCustomerById,
getProjectById,
getAccountById,
getCreatedDocumentById,
getBankAccountById,
getWorkingTimeById,
}
})