Changes in RLS and Tenants

Many Changes in Invoice Editor
Page Loading Rebuilt
Started Rights Management
This commit is contained in:
2024-01-30 21:18:46 +01:00
parent 3167b6a20a
commit fe74e7d91b
13 changed files with 885 additions and 527 deletions

View File

@@ -3,47 +3,20 @@
import GlobalSearch from "~/components/GlobalSearch.vue"; import GlobalSearch from "~/components/GlobalSearch.vue";
const supabase = useSupabaseClient()
const user = useSupabaseUser() const user = useSupabaseUser()
//console.log(user.value) //console.log(user.value)
const router = useRouter()
const route = useRoute() const route = useRoute()
const colorMode = useColorMode()
const supabase = useSupabaseClient()
const tenants = (await supabase.from("tenants").select()).data const tenants = (await supabase.from("tenants").select()).data
const dataStore = useDataStore() const dataStore = useDataStore()
const isLight = computed({
get () {
return colorMode.value !== 'dark'
},
set () {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
const userProfile = (user.value ? dataStore.getProfileById(user.value.id) : {})
//console.log(userProfile) //console.log(userProfile)
const showUserMenu = ref(false)
const userMenuItems = ref([
{
label: "Profil",
badge: dataStore.notifications.filter(item => item.read).length,
icon: "i-heroicons-user-20-solid"
},
{
label: "Nummernkreise",
icon: "i-heroicons-cog-8-tooth",
to: "/settings/numberRanges"
},
{
label: 'Benutzer',
icon: 'i-heroicons-user-group',
to: "/users"
}
])
@@ -56,151 +29,9 @@ watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
}) })
dataStore.fetchData() dataStore.initializeData()
const navLinks = [
{
label: "Home",
to: "/",
icon: 'i-heroicons-home'
},
{
label: "Kontakte",
icon: 'i-heroicons-user-group',
children: [
{
label: "Kunden",
to: "/customers",
icon: "i-heroicons-user-group"
},
{
label: "Lieferanten",
to: "/vendors",
icon: "i-heroicons-truck"
},
{
label: "Ansprechpartner",
to: "/contacts",
icon: "i-heroicons-user-group"
},
]
},
{
label: "Buchhaltung",
icon: 'i-heroicons-document-chart-bar',
children: [
{
label: "Eingangsrechnungen",
to: "/incominginvoices",
icon: "i-heroicons-document-text"
},
/*{
label: "Ausgangsrechnungen",
to: "/customerinvoices",
icon: "i-heroicons-document-text"
},*/
{
label: "Bank",
to: "/banking",
icon: "i-heroicons-currency-euro"
},
]
},
{
label: "Aufträge",
icon: "i-heroicons-square-3-stack-3d",
children: [
{
label: "Projekte",
to: "/projects",
icon: "i-heroicons-clipboard-document-check"
},
{
label: "Verträge",
to: "/contracts",
icon: "i-heroicons-clipboard-document"
},
{
label: "Objekte",
to: "/plants",
icon: "i-heroicons-clipboard-document"
},
]
},
{
label: "Verwaltung",
icon: "i-heroicons-square-3-stack-3d",
children: [
{
label: "Aufgaben",
to: "/tasks",
icon: "i-heroicons-rectangle-stack"
},
{
label: "Plantafel",
to: "/calendar/timeline",
icon: "i-heroicons-calendar-days"
},
{
label: "Kalender",
to: "/calendar/grid",
icon: "i-heroicons-calendar-days"
},
{
label: "Dokumente",
to: "/documents",
icon: "i-heroicons-document"
},
]
},
{
label: "Chat",
to: "/chat",
icon:'i-heroicons-chat-bubble-left-right'
},
{
label: "Mitarbeiter",
icon: 'i-heroicons-user',
children: [
{
label: "Zeiterfassung",
to: "/employees/timetracking",
icon: "i-heroicons-clock"
},
{
label: "Abwesenheiten",
to: "/absenceRequests",
icon: "i-heroicons-document-text"
}
]
},
{
label: "Lager",
icon: 'i-heroicons-home',
children: [
{
label: "Steuerung",
to: "/inventory",
icon: "i-heroicons-square-3-stack-3d"
},
{
label: "Artikelstamm",
to: "/products",
icon: "i-heroicons-puzzle-piece"
},
{
label: "Lagerplätze",
to: "/spaces",
icon: "i-heroicons-square-3-stack-3d"
},
{
label: "Fahrzeuge",
to: "/vehicles",
icon: "i-heroicons-truck"
},
]
},
]
const linksForBreadcrumbs = ref([]) const linksForBreadcrumbs = ref([])
@@ -209,8 +40,8 @@ const linksForBreadcrumbs = ref([])
const userTenant = ref({}) //const userTenant = ref({})
if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant) //if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant)
@@ -275,189 +106,10 @@ const items = [
</script> </script>
<template> <template>
<UHeader :links="navLinks" :to="null">
<template #logo>
<div id="logo">
<img
:src="!isLight ? '/spaces.svg' : '/spaces_hell.svg'"
alt="Logo"
/>
</div>
</template> <NuxtLayout>
<NuxtPage/>
<template #panel> </NuxtLayout>
<UNavigationTree :links="navLinks"/>
</template>
<template #right>
<!-- <ClientOnly>
<UButton
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="gray"
variant="ghost"
aria-label="Theme"
@click="isLight = !isLight"
/>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>-->
<GlobalSearch/>
<!-- <UPopover :popper="{placement: 'bottom-start'}">
<ClientOnly>
<UChip
:show="dataStore.notifications.filter(notification => !notification.read).length > 0"
inset
>
<UButton
icon="i-heroicons-envelope-20-solid"
variant="ghost"
color="gray"
class="mx-2"
/>
</UChip>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>
<template #panel>
<div class="w-60 p-3">
<UAlert
class="mb-3"
v-for="(notification,index) in dataStore.notifications"
:color="!notification.read ? 'primary' : 'grey'"
variant="outline"
:description="notification.text"
:title="notification.title"
/>
</div>
</template>
</UPopover>-->
<UButton
@click="showUserMenu = true"
variant="ghost"
color="gray"
>
<UAvatar
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
icon="i-heroicons-user-20-solid"
:chip-color="dataStore.notifications.filter(item => !item.read).length > 0 ? 'primary' : null"
/>
</UButton>
<USlideover
v-model="showUserMenu"
>
<UCard
class="h-full"
>
<UDivider
class="my-3"
label="Menü"
/>
<UVerticalNavigation
:links="userMenuItems"
/>
<UDivider
class="my-3"
label="Benachrichtigungen"
/>
<UAlert
class="mb-3"
v-for="(notification) in dataStore.notifications"
:color="!notification.read ? 'primary' : 'white'"
:variant="!notification.read ? 'outline' : 'soft'"
:description="notification.text"
:title="notification.title"
:close-button="!notification.read ? { icon: 'i-heroicons-x-mark-20-solid', color: 'gray', variant: 'link', padded: false } : null"
@close="async () => {
const {error} = await supabase.from('notifications').update({read:true}).eq('id', notification.id)
if(error) console.log(error)
dataStore.fetchNotifications()
}"
/>
<template #footer>
<InputGroup>
<UButton
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="white"
variant="outline"
aria-label="Theme"
@click="isLight = !isLight"
/>
<UButton
color="rose"
variant="outline"
@click="async () => {
showUserMenu = false
await supabase.auth.signOut()
await dataStore.clearStore()
await router.push('/login')
}"
>
Ausloggen
</UButton>
</InputGroup>
</template>
</UCard>
</USlideover>
<!-- <UDropdown :items="items" :ui="{ item: { disabled: 'cursor-text select-text' } }" :popper="{ placement: 'bottom-start' }">
<UAvatar
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
icon="i-heroicons-user-20-solid"
/>
<template #account="{ item }">
<div class="text-left">
<p>
Eingeloggt als
</p>
<p class="truncate font-medium text-gray-900 dark:text-white">
{{ item.label }}
</p>
</div>
</template>
<template #item="{ item }">
<span class="truncate">{{ item.label }}</span>
<UIcon :name="item.icon" class="flex-shrink-0 h-4 w-4 text-gray-400 dark:text-gray-500 ms-auto" />
</template>
</UDropdown>-->
</template>
</UHeader>
<UDivider />
<div class="m-3" id="contentContainer">
<NuxtLayout>
<NuxtPage/>
</NuxtLayout>
</div>
<!-- <UFooter> <!-- <UFooter>
<template #left> <template #left>
<p class="text-gray-500 dark:text-gray-400 text-sm"> <p class="text-gray-500 dark:text-gray-400 text-sm">
@@ -472,11 +124,9 @@ const items = [
</template> </template>
</UFooter>--> </UFooter>-->
<UNotifications/> <UNotifications/>
<VitePwaManifest/> <VitePwaManifest/>
<!-- <UCard id="page"> <!-- <UCard id="page">
<template #header> <template #header>
<div id="menu"> <div id="menu">
@@ -490,7 +140,7 @@ const items = [
&lt;!&ndash;<router-link to="/customers" class="mr-2"><UButton>Kunden</UButton></router-link> &lt;!&ndash;<router-link to="/customers" class="mr-2"><UButton>Kunden</UButton></router-link>
<router-link to="/projects" class="mr-2"><UButton>Projekte</UButton></router-link> <router-link to="/projects" class="mr-2"><UButton>Projekte</UButton></router-link>
- -
<router-link to="/incominginvoices" class="mr-2"><UButton>Eingangsrechnungen</UButton></router-link> <router-link to="/receipts" class="mr-2"><UButton>Eingangsrechnungen</UButton></router-link>
<router-link to="/timetracking" class="mr-2"><UButton>Zeiterfassung</UButton></router-link> <router-link to="/timetracking" class="mr-2"><UButton>Zeiterfassung</UButton></router-link>
<router-link to="/products" class="mr-2"><UButton>Artikel</UButton></router-link> <router-link to="/products" class="mr-2"><UButton>Artikel</UButton></router-link>

View File

@@ -77,7 +77,7 @@ const createVendorInvoice = async () => {
dataStore.fetchIncomingInvoices() dataStore.fetchIncomingInvoices()
await router.push("/incominginvoices") await router.push("/receipts")
} }
} }

View File

@@ -1,17 +1,388 @@
<script setup> <script setup>
const dataStore = useDataStore() const dataStore = useDataStore()
const colorMode = useColorMode()
const userProfile = dataStore.getOwnProfile
const supabase = useSupabaseClient()
const router = useRouter()
const isLight = computed({
get () {
return colorMode.value !== 'dark'
},
set () {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
const navLinks = [
{
label: "Home",
to: "/",
icon: 'i-heroicons-home'
},
{
label: "Kontakte",
icon: 'i-heroicons-user-group',
children: [
{
label: "Kunden",
to: "/customers",
icon: "i-heroicons-user-group"
},
{
label: "Lieferanten",
to: "/vendors",
icon: "i-heroicons-truck"
},
{
label: "Ansprechpartner",
to: "/contacts",
icon: "i-heroicons-user-group"
},
]
},
{
label: "Buchhaltung",
icon: 'i-heroicons-document-chart-bar',
children: [
{
label: "Belege",
to: "/receipts",
icon: "i-heroicons-document-text"
},
/*{
label: "Ausgangsrechnungen",
to: "/customerinvoices",
icon: "i-heroicons-document-text"
},*/
{
label: "Bank",
to: "/banking",
icon: "i-heroicons-currency-euro"
},
]
},
{
label: "Aufträge",
icon: "i-heroicons-square-3-stack-3d",
children: [
{
label: "Projekte",
to: "/projects",
icon: "i-heroicons-clipboard-document-check"
},
{
label: "Verträge",
to: "/contracts",
icon: "i-heroicons-clipboard-document"
},
{
label: "Objekte",
to: "/plants",
icon: "i-heroicons-clipboard-document"
},
]
},
{
label: "Verwaltung",
icon: "i-heroicons-square-3-stack-3d",
children: [
{
label: "Aufgaben",
to: "/tasks",
icon: "i-heroicons-rectangle-stack"
},
{
label: "Plantafel",
to: "/calendar/timeline",
icon: "i-heroicons-calendar-days"
},
{
label: "Kalender",
to: "/calendar/grid",
icon: "i-heroicons-calendar-days"
},
{
label: "Dokumente",
to: "/documents",
icon: "i-heroicons-document"
},
]
},
{
label: "Chat",
to: "/chat",
icon:'i-heroicons-chat-bubble-left-right'
},
{
label: "Mitarbeiter",
icon: 'i-heroicons-user',
children: [
{
label: "Zeiterfassung",
to: "/employees/timetracking",
icon: "i-heroicons-clock"
},
{
label: "Abwesenheiten",
to: "/absenceRequests",
icon: "i-heroicons-document-text"
}
]
},
{
label: "Lager",
icon: 'i-heroicons-home',
children: [
{
label: "Steuerung",
to: "/inventory",
icon: "i-heroicons-square-3-stack-3d"
},
{
label: "Artikelstamm",
to: "/products",
icon: "i-heroicons-puzzle-piece"
},
{
label: "Lagerplätze",
to: "/spaces",
icon: "i-heroicons-square-3-stack-3d"
},
{
label: "Fahrzeuge",
to: "/vehicles",
icon: "i-heroicons-truck"
},
]
},
]
const showUserMenu = ref(false)
const userMenuItems = ref([
{
label: "Profil",
badge: dataStore.notifications.filter(item => item.read).length,
icon: "i-heroicons-user-20-solid"
},
{
label: "Nummernkreise",
icon: "i-heroicons-cog-8-tooth",
to: "/settings/numberRanges"
},
{
label: 'Benutzer',
icon: 'i-heroicons-user-group',
to: "/users"
}
])
</script> </script>
<template> <template>
<div v-if="dataStore.loaded">
<UHeader :links="navLinks" :to="null">
<template #logo>
<div id="logo">
<img
:src="!isLight ? '/spaces.svg' : '/spaces_hell.svg'"
alt="Logo"
/>
</div>
</template>
<template #panel>
<UNavigationTree :links="navLinks"/>
</template>
<template #right>
<slot v-if="dataStore.loaded"/>
<!-- <ClientOnly>
<UButton
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="gray"
variant="ghost"
aria-label="Theme"
@click="isLight = !isLight"
/>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>-->
<GlobalSearch/>
<!-- <UPopover :popper="{placement: 'bottom-start'}">
<ClientOnly>
<UChip
:show="dataStore.notifications.filter(notification => !notification.read).length > 0"
inset
>
<UButton
icon="i-heroicons-envelope-20-solid"
variant="ghost"
color="gray"
class="mx-2"
/>
</UChip>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>
<template #panel>
<div class="w-60 p-3">
<UAlert
class="mb-3"
v-for="(notification,index) in dataStore.notifications"
:color="!notification.read ? 'primary' : 'grey'"
variant="outline"
:description="notification.text"
:title="notification.title"
/>
</div>
</template>
</UPopover>-->
<UButton
@click="showUserMenu = true"
variant="ghost"
color="gray"
>
<UAvatar
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
icon="i-heroicons-user-20-solid"
:chip-color="dataStore.notifications.filter(item => !item.read).length > 0 ? 'primary' : null"
/>
</UButton>
<USlideover
v-model="showUserMenu"
>
<UCard
class="h-full"
>
<UDivider
class="my-3"
label="Tenant"
/>
<USelectMenu
:options="dataStore.getOwnProfile.tenants"
option-attribute="name"
value-attribute="id"
v-model="dataStore.currentTenant"
@change="dataStore.changeTenant()"
/>
<UDivider
class="my-3"
label="Menü"
/>
<UVerticalNavigation
:links="userMenuItems"
/>
<UDivider
class="my-3"
label="Benachrichtigungen"
/>
<UAlert
class="mb-3"
v-for="(notification) in dataStore.notifications"
:color="!notification.read ? 'primary' : 'white'"
:variant="!notification.read ? 'outline' : 'soft'"
:description="notification.text"
:title="notification.title"
:close-button="!notification.read ? { icon: 'i-heroicons-x-mark-20-solid', color: 'gray', variant: 'link', padded: false } : null"
@close="async () => {
const {error} = await supabase.from('notifications').update({read:true}).eq('id', notification.id)
if(error) console.log(error)
dataStore.fetchNotifications()
}"
/>
<template #footer>
<InputGroup>
<UButton
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="white"
variant="outline"
aria-label="Theme"
@click="isLight = !isLight"
/>
<UButton
color="rose"
variant="outline"
@click="async () => {
showUserMenu = false
await supabase.auth.signOut()
await dataStore.clearStore()
await router.push('/login')
}"
>
Ausloggen
</UButton>
</InputGroup>
</template>
</UCard>
</USlideover>
<!-- <UDropdown :items="items" :ui="{ item: { disabled: 'cursor-text select-text' } }" :popper="{ placement: 'bottom-start' }">
<UAvatar
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
icon="i-heroicons-user-20-solid"
/>
<template #account="{ item }">
<div class="text-left">
<p>
Eingeloggt als
</p>
<p class="truncate font-medium text-gray-900 dark:text-white">
{{ item.label }}
</p>
</div>
</template>
<template #item="{ item }">
<span class="truncate">{{ item.label }}</span>
<UIcon :name="item.icon" class="flex-shrink-0 h-4 w-4 text-gray-400 dark:text-gray-500 ms-auto" />
</template>
</UDropdown>-->
</template>
</UHeader>
<UDivider />
<div class="m-3" id="contentContainer">
<slot/>
</div>
</div>
<div <div
v-else v-else
class="flex-col mx-auto my-auto mt-10 w-3/4"
> >
<UProgress animation="carousel" /> <img src="/spaces.svg" class="w-1/3 mx-auto"/>
<UProgress animation="carousel" class=" " />
</div> </div>
</template> </template>

View File

@@ -2,6 +2,11 @@
import dayjs from "dayjs" import dayjs from "dayjs"
const dataStore = useDataStore() const dataStore = useDataStore()
const user = useSupabaseUser() const user = useSupabaseUser()
const route = useRoute()
const tabItems = [ const tabItems = [
{ {
@@ -13,52 +18,46 @@ const tabItems = [
] ]
const itemInfo = ref({ const itemInfo = ref({
customer: 13, type: "invoices",
contact: 8, customer: null,
contact: null,
address: { address: {
street: null, street: null,
special: null, special: null,
zip: null, zip: null,
city: null, city: null,
}, },
project: 6, project: null,
documentNumber: "RE23-1409", documentNumber: null,
documentDate: "10.01.2024", documentDate: null,
deliveryDate: "10.01.2024", deliveryDate: null,
dateOfPerformance: null, dateOfPerformance: null,
createdBy: user.value.id, createdBy: user.value.id,
title: "TITEL", title: null,
description: "BESCHREIBUNG", description: null,
startText: "Sehr geehrte Frau Sindern,\n" + startText: "Sehr geehrte Frau Sindern,\n" +
"wir bedanken uns für Ihr entgegengebrachtes Vertrauen und Ihren Auftrag und stellen Ihnen\n" + "wir bedanken uns für Ihr entgegengebrachtes Vertrauen und Ihren Auftrag und stellen Ihnen\n" +
"folgende Positionen in Rechnung: ", "folgende Positionen in Rechnung: ",
endText: "Bitte überweisen Sie den Rechnungsbetrag unter Angabe der Rechnungsnummer im Verwendungszweck innerhalb von 10 Tagen auf das unten angegebene Konto. Wir bedanken uns für das entgegengebrachte Vertrauen und freuen uns auf eine weitere gute Zusammenarbeit.", endText: "Bitte überweisen Sie den Rechnungsbetrag unter Angabe der Rechnungsnummer im Verwendungszweck innerhalb von 10 Tagen auf das unten angegebene Konto. Wir bedanken uns für das entgegengebrachte Vertrauen und freuen uns auf eine weitere gute Zusammenarbeit.",
rows: [ rows: [
{
id: 1,
pos: 1,
mode: "free",
text: "FahrtkostenFahrtkostenFahrtkostenFahrtkosten",
quantity: 204,
unit: 3,
price: 0.80,
taxPercent: 19,
discountPercent: 0
},
{
id: 2,
pos: 2,
mode: "free",
text: "Test",
quantity: 1,
unit: 1,
price: 10,
taxPercent: 19,
discountPercent: 0
}
] ]
}) })
const setupPage = () => {
if(route.params) {
if(route.params.id) itemInfo.value = dataStore.getCreatedDocumentById(Number(route.params.id))
}
if(route.query) {
if(route.query.type) itemInfo.value.type = route.query.type
if(route.query.project) itemInfo.value.project = Number(route.query.project)
if(route.query.customer) itemInfo.value.customer = Number(route.query.customer)
}
}
const getRowAmount = (row) => { 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('.',',')
} }
@@ -218,7 +217,6 @@ const generateDocument = async () => {
uri.value = await useCreatePdf(getDocumentData()) uri.value = await useCreatePdf(getDocumentData())
//alert(uri.value) //alert(uri.value)
showDocument.value = true showDocument.value = true
} }
const onChangeTab = (index) => { const onChangeTab = (index) => {
@@ -238,20 +236,80 @@ const setPosNumbers = () => {
}) })
} }
const saveDocument = async () => {
let createData = {
type: itemInfo.value.type,
customer: itemInfo.value.customer,
contact: itemInfo.value.contact,
address: itemInfo.value.address,
project: itemInfo.value.project,
documentNumber: itemInfo.value.documentNumber,
documentDate: itemInfo.value.documentDate,
state: "Entwurf",
info: {
},
createdBy: itemInfo.value.createdBy,
title: itemInfo.value.title,
description: itemInfo.value.description,
startText: itemInfo.value.startText,
endText: itemInfo.value.endText,
rows: itemInfo.value.rows
}
if(route.params.id) {
await dataStore.updateItem("createdDocuments", {...createData, id: itemInfo.value.id})
} else {
await dataStore.createNewItem("createdDocuments", createData)
}
}
const closeDocument = () => {
generateDocument()
console.log(uri)
}
setupPage()
</script> </script>
<template> <template>
<!-- <UButton
@click="createPdf"
>TEST</UButton>-->
<UCard class="h-fit"> <UCard class="h-fit">
<InputGroup class="mb-3">
<UButton
icon="i-mdi-content-save"
@click="saveDocument"
>
Entwurf
</UButton>
<UButton
@click="closeDocument"
>
Fertigstellen
</UButton>
</InputGroup>
<UTabs :items="tabItems" @change="onChangeTab"> <UTabs :items="tabItems" @change="onChangeTab">
<template #item="{item}"> <template #item="{item}">
<div v-if="item.label === 'Editor'"> <div v-if="item.label === 'Editor'">
<InputGroup> <InputGroup>
<div class="flex-auto mr-5"> <div class="flex-auto mr-5">
<UFormGroup
label="Dokumenttyp:"
>
<USelectMenu
:options="Object.keys(dataStore.documentTypesForCreation).map(i => {return {label: dataStore.documentTypesForCreation[i].labelSingle, type: i }})"
v-model="itemInfo.type"
value-attribute="type"
option-attribute="label"
>
<template #label>
{{dataStore.documentTypesForCreation[itemInfo.type].labelSingle}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup <UFormGroup
label="Kunde:" label="Kunde:"
> >
@@ -324,6 +382,7 @@ const setPosNumbers = () => {
> >
<UInput <UInput
v-model="itemInfo.documentNumber" v-model="itemInfo.documentNumber"
placeholder="Leer lassen für automatisch generierte Nummer"
/> />
</UFormGroup> </UFormGroup>
<UFormGroup <UFormGroup
@@ -735,27 +794,6 @@ const setPosNumbers = () => {
</table> </table>
<table>
<tr>
<td class="font-bold">Netto:</td>
<td>{{documentTotal.totalNet}}</td>
</tr>
<tr>
<td class="font-bold">zzgl. 19 % USt:</td>
<td>{{documentTotal.total19}}</td>
</tr>
<tr>
<td class="font-bold">Brutto:</td>
<td>{{documentTotal.totalGross}}</td>
</tr>
</table>
<InputGroup> <InputGroup>
<UButton <UButton
@click="addPosition('normal')" @click="addPosition('normal')"
@@ -777,6 +815,21 @@ const setPosNumbers = () => {
</UButton> </UButton>
</InputGroup> </InputGroup>
<table>
<tr>
<td class="font-bold">Netto:</td>
<td>{{documentTotal.totalNet}}</td>
</tr>
<tr>
<td class="font-bold">zzgl. 19 % USt:</td>
<td>{{documentTotal.total19}}</td>
</tr>
<tr>
<td class="font-bold">Brutto:</td>
<td>{{documentTotal.totalGross}}</td>
</tr>
</table>
<UDivider <UDivider
@@ -797,7 +850,6 @@ const setPosNumbers = () => {
> >
Show Show
</UButton>--> </UButton>-->
<object <object
:data="uri" :data="uri"
v-if="showDocument" v-if="showDocument"

View File

@@ -0,0 +1,25 @@
<script setup>
const dataStore = useDataStore()
const route = useRoute()
const itemInfo = ref({})
const setupPage = () => {
if(route.params) {
if(route.params.id) itemInfo.value = dataStore.getCreatedDocumentById(Number(route.params.id))
}
}
setupPage()
</script>
<template>
{{itemInfo}}
</template>
<style scoped>
</style>

View File

@@ -12,11 +12,24 @@ const {fetchData} = useDataStore()
const email = ref("") const email = ref("")
const password = ref("") const password = ref("")
const fields = [{
name: 'email',
type: 'text',
label: 'Email',
placeholder: 'E-Mail Adresse'
}, {
name: 'password',
label: 'Password',
type: 'password',
placeholder: 'Passwort'
}]
const onSubmit = async (data) => {
const onSubmit = async () => {
const { error } = await supabase.auth.signInWithPassword({ const { error } = await supabase.auth.signInWithPassword({
email: email.value, email: data.email,
password: password.value password: data.password
}) })
if(error) { if(error) {
console.log(error.toString()) console.log(error.toString())
@@ -33,7 +46,7 @@ const onSubmit = async () => {
</script> </script>
<template> <template>
<div id="loginSite"> <!-- <div id="loginSite">
<div id="loginForm"> <div id="loginForm">
<UFormGroup <UFormGroup
label="E-Mail:" label="E-Mail:"
@@ -59,7 +72,23 @@ const onSubmit = async () => {
</UButton> </UButton>
</div> </div>
</div> </div>-->
<UCard class="max-w-sm w-full mx-auto mt-5">
<UAuthForm
title="Login"
description="Geben Sie Ihre Anmeldedaten ein um Zugriff auf Ihren Account zu bekommen"
align="bottom"
icon="i-heroicons-user-circle"
:fields="fields"
:loading="false"
@submit="onSubmit"
>
</UAuthForm>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -309,11 +309,24 @@ setupPage()
</UAccordion> </UAccordion>
</div> </div>
<div v-else-if="item.key === 'documents'" class="space-y-3"> <div v-else-if="item.key === 'documents'" class="space-y-3">
<UButton <InputGroup>
@click="uploadModalOpen = true" <UButton
> @click="uploadModalOpen = true"
Hochladen >
</UButton> Hochladen
</UButton>
<UButton
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=quotes&customer=${currentItem.customer}`)"
>
+ Angebot
</UButton>
<UButton
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=invoices&customer=${currentItem.customer}`)"
>
+ Rechnung
</UButton>
</InputGroup>
<UModal <UModal
v-model="uploadModalOpen" v-model="uploadModalOpen"
> >

View File

@@ -94,7 +94,7 @@ const setState = async (newState) => {
} else if(mode.value === 'edit') { } else if(mode.value === 'edit') {
await dataStore.updateItem('incomingInvoices',{...itemInfo.value, state: newState}) await dataStore.updateItem('incomingInvoices',{...itemInfo.value, state: newState})
} }
await router.push("/incominginvoices") await router.push("/receipts")
} }
@@ -133,11 +133,11 @@ setupPage()
Status zu Entwurf Status zu Entwurf
</UButton> </UButton>
<UButton <UButton
@click="setState('Offen')" @click="setState('Gebucht')"
v-if="currentVendorInvoice.state !== 'Offen'" v-if="currentVendorInvoice.state !== 'Gebucht'"
color="rose" color="rose"
> >
Status zu Offen Status auf Gebucht
</UButton> </UButton>
</InputGroup> </InputGroup>
@@ -372,13 +372,13 @@ setupPage()
> >
Position entfernen Position entfernen
</UButton> </UButton>
<HistoryDisplay
type="incomingInvoice"
v-if="currentVendorInvoice"
:element-id="currentVendorInvoice.id"
/>
</div>
</div>
<HistoryDisplay
type="incomingInvoice"
v-if="currentVendorInvoice"
:element-id="currentVendorInvoice.id"
/>
</div> </div>
</div> </div>

View File

@@ -8,6 +8,11 @@
v-model="searchString" v-model="searchString"
placeholder="Suche..." placeholder="Suche..."
/> />
<UCheckbox
v-model="showDrafts"
label="Entwürfe Anzeigen"
/>
</div> </div>
@@ -18,16 +23,20 @@
@select="selectItem" @select="selectItem"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
> >
<template #type-data="{row}">
<span v-if="row.type === 'incomingInvoice'">Eingangsrechnung</span>
<span v-else>{{dataStore.documentTypesForCreation[row.type].labelSingle}}</span>
</template>
<template #state-data="{row}"> <template #state-data="{row}">
<span <span
v-if="row.state === 'Entwurf'" v-if="row.state === 'Entwurf'"
class="text-cyan-500" class="text-rose-500"
> >
{{row.state}} {{row.state}}
</span> </span>
<span <span
v-if="row.state === 'Offen'" v-if="row.state === 'Gebucht'"
class="text-rose-500" class="text-cyan-500"
> >
{{row.state}} {{row.state}}
</span> </span>
@@ -41,6 +50,10 @@
<template #vendor-data="{row}"> <template #vendor-data="{row}">
{{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}} {{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}}
</template> </template>
<template #reference-data="{row}">
<span v-if="row.type === 'incomingInvoice'">{{row.reference}}</span>
<span v-else>{{row.documentNumber}}</span>
</template>
<template #date-data="{row}"> <template #date-data="{row}">
<span v-if="row.date">{{row.date ? dayjs(row.date).format("DD.MM.YY") : ''}}</span> <span v-if="row.date">{{row.date ? dayjs(row.date).format("DD.MM.YY") : ''}}</span>
</template> </template>
@@ -52,7 +65,12 @@
<span v-if="!row.paid" :class="dayjs(row.dueDate).diff(dayjs()) <= 0 ? ['text-rose-500'] : ['text-cyan-500'] ">Offen</span> <span v-if="!row.paid" :class="dayjs(row.dueDate).diff(dayjs()) <= 0 ? ['text-rose-500'] : ['text-cyan-500'] ">Offen</span>
</template> </template>
<template #amount-data="{row}"> <template #amount-data="{row}">
<div class="text-right font-bold">{{getRowAmount(row) === 0 ? '' : `${String(getRowAmount(row).toFixed(2)).replace('.',',')}`}}</div> <div
class="text-right font-bold"
v-if="row.type === 'incomingInvoice'"
>
{{getRowAmount(row) === 0 ? '' : `${String(getRowAmount(row).toFixed(2)).replace('.',',')}`}}
</div>
</template> </template>
</UTable> </UTable>
@@ -74,6 +92,10 @@ const mode = ref("show")
const itemColumns = [ const itemColumns = [
{ {
key: 'type',
label: "Typ",
sortable: true
},{
key: 'state', key: 'state',
label: "Status.", label: "Status.",
sortable: true sortable: true
@@ -113,13 +135,25 @@ const itemColumns = [
const selectItem = (item) => { const selectItem = (item) => {
console.log(item) console.log(item)
if(item.state === "Entwurf") {
console.log("ENTWURF") if(item.type === "incomingInvoice"){
router.push(`/incominginvoices/edit/${item.id} `) if(item.state === "Entwurf") {
} else if(item.state === "Offen") { router.push(`/receipts/incominginvoices/edit/${item.id} `)
router.push(`/incominginvoices/show/${item.id}`) } else if(item.state === "Gebucht") {
router.push(`/receipts/incominginvoices/show/${item.id}`)
}
} else {
if(item.state === "Entwurf"){
router.push(`/createDocument/edit/${item.id}`)
} else if(item.state !== "Entwurf") {
router.push(`/createDocument/show/${item.id}`)
}
} }
} }
const getRowAmount = (row) => { const getRowAmount = (row) => {
@@ -135,13 +169,25 @@ const getRowAmount = (row) => {
const searchString = ref('') const searchString = ref('')
const showDrafts = ref(false)
const filteredRows = computed(() => { const filteredRows = computed(() => {
if(!searchString.value) { let items = [...dataStore.incomingInvoices.map(i => {return {...i, type: "incomingInvoice"}}),...dataStore.createdDocuments]
return dataStore.incomingInvoices
console.log(dataStore.createdDocuments)
if(showDrafts.value === true) {
items = items.filter(i => i.state === "Entwurf")
} else {
items = items.filter(i => i.state !== "Entwurf")
} }
return dataStore.incomingInvoices.filter(item => {
if(!searchString.value) {
return items
}
return items.filter(item => {
return Object.values(item).some((value) => { return Object.values(item).some((value) => {
return String(value).toLowerCase().includes(searchString.value.toLowerCase()) return String(value).toLowerCase().includes(searchString.value.toLowerCase())
}) })

View File

@@ -36,11 +36,13 @@ const resources = {
}, },
spaces: { spaces: {
label: "Lagerplätze" label: "Lagerplätze"
},
invoices: {
label: "Rechnungen"
} }
} }
const updateNumberRange = async (range) => { const updateNumberRange = async (range) => {
console.log(range)
const {data,error} = await supabase const {data,error} = await supabase
.from("numberRanges") .from("numberRanges")

View File

@@ -0,0 +1,78 @@
<script setup>
const supabase = useSupabaseClient()
const data = await supabase.from("profiles").select('* , tenants (id, name)')
console.log(data)
let rights = {
createUser: {label: "Benutzer erstellen"},
modifyUser: {label: "Benutzer bearbeiten"},
deactivateUser: {label: "Benutzer sperren"},
createProject: {label: "Projekt erstellen"},
viewOwnProjects: {label: "Eigene Projekte sehen"},
viewAllProjects: {label: "Alle Projekte sehen"},
createTask: {label: "Aufgabe erstellen"},
viewOwnTasks: {label:"Eigene Aufgaben sehen"},
viewAllTasks: {label: "Alle Aufgaben sehen"},
trackOwnTime: {label:""},
createOwnTime: {label:""},
createTime: {label:""},
viewOwnTimes: {label:""},
viewAllTimesTimes: {label:""},
}
let roles = [
{
key: "tenantAdmin",
label: "Firmenadministrator",
rights: [
...Object.keys(rights)
]
},
{
key:"worker",
label: "Monteur",
rights: [
"viewOwnProjects",
"createTasks",
"viewOwnTasks"
]
},
{
key:"manager",
label: "Vorarbeiter",
rights: [
"createProjects",
"viewOwnProjects",
"createTasks",
"viewOwnTasks",
]
},
{
key:"booker",
label: "Buchhalter",
rights: [
"createTasks",
"viewOwnTasks",
"createTime",
"viewAllTimes"
]
}
]
</script>
<template>
</template>
<style scoped>
</style>

View File

@@ -141,7 +141,7 @@ setupPage()
<UTable <UTable
:rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)" :rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)"
:columns="incomingInvoicesColumns" :columns="incomingInvoicesColumns"
@select="(row) => router.push('/incominginvoices/show/' + row.id)" @select="(row) => router.push('/receipts/show/' + row.id)"
> >
<template #vendor-data="{row}"> <template #vendor-data="{row}">
{{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ""}} {{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ""}}

View File

@@ -1,6 +1,7 @@
import {defineStore} from 'pinia' import {defineStore} from 'pinia'
import dayjs from "dayjs" import dayjs from "dayjs"
import {typeOf} from "uri-js/dist/esnext/util"; import {typeOf} from "uri-js/dist/esnext/util";
import {useNumberRange} from "~/composables/useNumberRange.js";
//const supabase = createClient('https://uwppvcxflrcsibuzsbil.supabase.co','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo') //const supabase = createClient('https://uwppvcxflrcsibuzsbil.supabase.co','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo')
@@ -21,7 +22,8 @@ export const useDataStore = defineStore('data', () => {
customers: { customers: {
label: "Kunden", label: "Kunden",
labelSingle: "Kunde", labelSingle: "Kunde",
redirect:true redirect:true,
numberRangeHolder: "customerNumber"
}, },
contacts: { contacts: {
label: "Kontakte", label: "Kontakte",
@@ -61,7 +63,8 @@ export const useDataStore = defineStore('data', () => {
vendors: { vendors: {
label: "Lieferanten", label: "Lieferanten",
labelSingle: "Lieferant", labelSingle: "Lieferant",
redirect:true redirect:true,
numberRangeHolder: "vendorNumber"
}, },
messages: { messages: {
label: "Nachrichten", label: "Nachrichten",
@@ -70,29 +73,58 @@ export const useDataStore = defineStore('data', () => {
spaces: { spaces: {
label: "Lagerplätze", label: "Lagerplätze",
labelSingle: "Lagerplatz", labelSingle: "Lagerplatz",
redirect: true redirect: true,
numberRangeHolder: "spaceNumber"
}, },
users: { users: {
label: "Benutzer", label: "Benutzer",
labelSingle: "Benutzer" labelSingle: "Benutzer"
},
createdDocuments: {
label: "Dokumente",
labelSingle: "Dokument"
},
incomingInvoices: {
label: "Eingangsrechnungen",
labelSingle: "Eingangsrechnung"
} }
} }
const documentTypesForCreation = ref({
invoices: {
label: "Rechnungen",
labelSingle: "Rechnung",
},
quotes: {
label: "Angebote",
labelSingle: "Angebot"
},
deliveryNotes: {
label: "Lieferscheine",
labelSingle: "Lieferschein"
}
})
const loaded = ref(false) const loaded = ref(false)
const ownTenant = ref({ const ownTenant = ref({
calendarConfig: { calendarConfig: {
eventTypes: [] as any[] eventTypes: []
}, },
timeConfig: { timeConfig: {
timeTypes: [] as any[] timeTypes: []
}, },
tags: { tags: {
documents: [] as any[], documents: [] ,
products: [] as any[] products: []
}, },
measures: [] as {name:String, short:String}[] measures: []
}) })
const profiles = ref([]) const profiles = ref([])
const currentTenant = ref(null)
const events = ref([]) const events = ref([])
const customers = ref([]) const customers = ref([])
const tasks = ref([]) const tasks = ref([])
@@ -122,11 +154,30 @@ export const useDataStore = defineStore('data', () => {
const inventoryItems = ref([]) const inventoryItems = ref([])
const chats = ref([]) const chats = ref([])
const messages = ref([]) const messages = ref([])
const createdDocuments = ref([])
async function initializeData () {
await fetchProfiles()
currentTenant.value = profiles.value.find(i => i.id === user.value.id).tenants[0].id
await fetchData()
}
async function changeTenant() {
loaded.value = false
await clearStore()
await fetchData()
router.push("/")
loaded.value = true
}
async function fetchData () { async function fetchData () {
await fetchProfiles()
fetchDocuments() fetchDocuments()
await fetchOwnTenant() await fetchOwnTenant()
await fetchProfiles()
await fetchEvents() await fetchEvents()
await fetchTasks() await fetchTasks()
await fetchProjects() await fetchProjects()
@@ -156,6 +207,7 @@ export const useDataStore = defineStore('data', () => {
await fetchInventoryItems() await fetchInventoryItems()
await fetchChats() await fetchChats()
await fetchMessages() await fetchMessages()
await fetchCreatedDocuments()
loaded.value = true loaded.value = true
} }
@@ -193,6 +245,7 @@ export const useDataStore = defineStore('data', () => {
inventoryItems.value = [] inventoryItems.value = []
chats.value = [] chats.value = []
messages.value = [] messages.value = []
createdDocuments.value = []
} }
//Realtime Update //Realtime Update
@@ -218,7 +271,20 @@ export const useDataStore = defineStore('data', () => {
) )
.subscribe() .subscribe()
async function createNewItem (dataType:string,data:Array){ async function createNewItem (dataType,data){
console.log(dataType)
if(dataTypes[dataType].numberRangeHolder) {
const numberRange = useNumberRange(dataType)
data[dataTypes[dataType].numberRangeHolder] = await numberRange.useNextNumber()
} else if(dataType === "createdDocuments") {
console.log(data.type)
const numberRange = useNumberRange(data.type)
data.documentNumber = await numberRange.useNextNumber()
}
const {data:supabaseData,error:supabaseError} = await supabase const {data:supabaseData,error:supabaseError} = await supabase
.from(dataType) .from(dataType)
.insert(typeOf(data) === 'Object' ? [data] : data) .insert(typeOf(data) === 'Object' ? [data] : data)
@@ -233,7 +299,7 @@ export const useDataStore = defineStore('data', () => {
} }
} }
async function updateItem (dataType:string, data:Object) { async function updateItem (dataType, data) {
const {data:supabaseData,error: supabaseError} = await supabase const {data:supabaseData,error: supabaseError} = await supabase
.from(dataType) .from(dataType)
.update(data) .update(data)
@@ -251,108 +317,116 @@ export const useDataStore = defineStore('data', () => {
} }
async function fetchOwnTenant () { async function fetchOwnTenant () {
ownTenant.value = (await supabase.from("tenants").select().eq('id', user.value?.app_metadata.tenant)).data[0] ownTenant.value = (await supabase.from("tenants").select().eq('id', currentTenant.value)).data[0]
} }
async function fetchProfiles () { async function fetchProfiles () {
profiles.value = (await supabase.from("profiles").select()).data profiles.value = (await supabase.from("profiles").select('* , tenants (id, name)')).data
} }
async function fetchBankAccounts () { async function fetchBankAccounts () {
bankAccounts.value = (await supabase.from("bankAccounts").select()).data bankAccounts.value = (await supabase.from("bankaccounts").select().eq('tenant', currentTenant.value)).data
} }
async function fetchBankStatements () { async function fetchBankStatements () {
bankStatements.value = (await supabase.from("bankStatements").select().order("date", {ascending:false})).data bankStatements.value = (await supabase.from("bankstatements").select().eq('tenant', currentTenant.value).order("date", {ascending:false})).data
} }
async function fetchEvents () { async function fetchEvents () {
events.value = (await supabase.from("events").select()).data events.value = (await supabase.from("events").select().eq('tenant', currentTenant.value)).data
} }
async function fetchContracts () { async function fetchContracts () {
contracts.value = (await supabase.from("contracts").select()).data contracts.value = (await supabase.from("contracts").select().eq('tenant', currentTenant.value)).data
} }
async function fetchContacts () { async function fetchContacts () {
contacts.value = (await supabase.from("contacts").select()).data contacts.value = (await supabase.from("contacts").select().eq('tenant', currentTenant.value)).data
} }
async function fetchCustomers () { async function fetchCustomers () {
customers.value = (await supabase.from("customers").select().order("customerNumber", {ascending:true})).data customers.value = (await supabase.from("customers").select().eq('tenant', currentTenant.value).order("customerNumber", {ascending:true})).data
} }
async function fetchTasks () { async function fetchTasks () {
tasks.value = (await supabase.from("tasks").select()).data tasks.value = (await supabase.from("tasks").select().eq('tenant', currentTenant.value)).data
} }
async function fetchForms () { async function fetchForms () {
forms.value = (await supabase.from("forms").select()).data forms.value = (await supabase.from("forms").select().eq('tenant', currentTenant.value)).data
} }
async function fetchFormSubmits () { async function fetchFormSubmits () {
formSubmits.value = (await supabase.from("formSubmits").select()).data formSubmits.value = (await supabase.from("formSubmits").select().eq('tenant', currentTenant.value)).data
} }
async function fetchProducts () { async function fetchProducts () {
products.value = (await supabase.from("products").select()).data products.value = (await supabase.from("products").select().eq('tenant', currentTenant.value)).data
} }
async function fetchUnits () { async function fetchUnits () {
units.value = (await supabase.from("units").select()).data units.value = (await supabase.from("units").select()).data
} }
async function fetchProjects () { async function fetchProjects () {
projects.value = (await supabase.from("projects").select()).data projects.value = (await supabase.from("projects").select().eq("tenant",currentTenant.value)).data
} }
async function fetchSpaces () { async function fetchSpaces () {
spaces.value = (await supabase.from("spaces").select().order("spaceNumber", {ascending:true})).data spaces.value = (await supabase.from("spaces").select().eq('tenant', currentTenant.value).order("spaceNumber", {ascending:true})).data
} }
async function fetchMovements () { async function fetchMovements () {
movements.value = (await supabase.from("movements").select()).data movements.value = (await supabase.from("movements").select().eq('tenant', currentTenant.value)).data
} }
async function fetchVehicles () { async function fetchVehicles () {
vehicles.value = (await supabase.from("vehicles").select()).data vehicles.value = (await supabase.from("vehicles").select().eq('tenant', currentTenant.value)).data
} }
async function fetchTimes () { async function fetchTimes () {
times.value = (await supabase.from("times").select().order("start", {ascending:false})).data times.value = (await supabase.from("times").select().eq('tenant', currentTenant.value).order("start", {ascending:false})).data
} }
async function fetchHistoryItems () { async function fetchHistoryItems () {
historyItems.value = (await supabase.from("historyItems").select()).data historyItems.value = (await supabase.from("historyitems").select().eq('tenant', currentTenant.value)).data
} }
async function fetchVendors () { async function fetchVendors () {
vendors.value = (await supabase.from("vendors").select().order("vendorNumber", {ascending:true})).data vendors.value = (await supabase.from("vendors").select().eq('tenant', currentTenant.value).order("vendorNumber", {ascending:true})).data
} }
async function fetchIncomingInvoices () { async function fetchIncomingInvoices () {
incomingInvoices.value = (await supabase.from("incomingInvoices").select()).data incomingInvoices.value = (await supabase.from("incominginvoices").select().eq('tenant', currentTenant.value)).data
} }
async function fetchNumberRanges () { async function fetchNumberRanges () {
numberRanges.value = (await supabase.from("numberRanges").select()).data numberRanges.value = (await supabase.from("numberranges").select().eq('tenant', currentTenant.value)).data
} }
async function fetchNotifications () { async function fetchNotifications () {
notifications.value = (await supabase.from("notifications").select().order("created_at", {ascending: false})).data notifications.value = (await supabase.from("notifications").select().eq('tenant', currentTenant.value).order("created_at", {ascending: false})).data
} }
async function fetchAbsenceRequests () { async function fetchAbsenceRequests () {
absenceRequests.value = (await supabase.from("absenceRequests").select()).data absenceRequests.value = (await supabase.from("absencerequests").select().eq('tenant', currentTenant.value)).data
} }
async function fetchAccounts () { async function fetchAccounts () {
accounts.value = (await supabase.from("accounts").select()).data accounts.value = (await supabase.from("accounts").select()).data
} }
async function fetchTaxTypes () { async function fetchTaxTypes () {
taxTypes.value = (await supabase.from("taxTypes").select()).data taxTypes.value = (await supabase.from("taxtypes").select()).data
} }
async function fetchPlants () { async function fetchPlants () {
plants.value = (await supabase.from("plants").select()).data plants.value = (await supabase.from("plants").select().eq('tenant', currentTenant.value)).data
} }
async function fetchInventoryItems () { async function fetchInventoryItems () {
inventoryItems.value = (await supabase.from("inventoryItems").select()).data inventoryItems.value = (await supabase.from("inventoryitems").select().eq('tenant', currentTenant.value)).data
} }
async function fetchChats() { async function fetchChats() {
chats.value = (await supabase.from("chats").select()).data chats.value = (await supabase.from("chats").select()).data
} }
async function fetchMessages() { async function fetchMessages() {
messages.value = (await supabase.from("messages").select().order('created_at', {ascending:true})).data messages.value = (await supabase.from("messages").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
}
async function fetchCreatedDocuments() {
createdDocuments.value = (await supabase.from("createddocuments").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
} }
async function fetchDocuments () { async function fetchDocuments () {
documents.value = (await supabase.from("documents").select()).data let tempDocuments = (await supabase.from("documents").select().eq('tenant', currentTenant.value)).data
for(const [index,doc] of documents.value.entries()){ if(tempDocuments.length > 0) {
// @ts-ignore for(const [index,doc] of tempDocuments.entries()){
documents.value[index].url = (await supabase.storage.from('files').createSignedUrl(doc.path, 60 * 60)).data.signedUrl // @ts-ignore
tempDocuments[index].url = (await supabase.storage.from('files').createSignedUrl(doc.path, 60 * 60)).data.signedUrl
}
} }
documents.value = tempDocuments
} }
async function addHistoryItem(text: String, user: String, elementId: String, resourceType: String) { async function addHistoryItem(text, user, elementId, resourceType) {
let data = { let data = {
user: user, user: user,
text: text text: text
@@ -382,55 +456,59 @@ export const useDataStore = defineStore('data', () => {
return tasks.value.filter(task => task.categorie != "Erledigt").length return tasks.value.filter(task => task.categorie != "Erledigt").length
}) })
const getMovementsBySpace = computed(() => (spaceId:string) => { const getOwnProfile = computed(() => {
return profiles.value.find(profile => profile.id === user.value.id)
})
const getMovementsBySpace = computed(() => (spaceId) => {
return movements.value.filter(movement => movement.spaceId === spaceId) return movements.value.filter(movement => movement.spaceId === spaceId)
}) })
const getContactsByCustomerId = computed(() => (customerId:string) => { const getContactsByCustomerId = computed(() => (customerId) => {
return contacts.value.filter(item => item.customer === customerId) return contacts.value.filter(item => item.customer === customerId)
}) })
const getContactsByVendorId = computed(() => (vendorId:string) => { const getContactsByVendorId = computed(() => (vendorId) => {
return contacts.value.filter(item => item.vendor === vendorId) return contacts.value.filter(item => item.vendor === vendorId)
}) })
const getDocumentsByProjectId = computed(() => (projectId:string) => { const getDocumentsByProjectId = computed(() => (projectId) => {
return documents.value.filter(item => item.project === projectId) return documents.value.filter(item => item.project === projectId)
}) })
const getEventsByProjectId = computed(() => (projectId:string) => { const getEventsByProjectId = computed(() => (projectId) => {
return events.value.filter(item => item.project === projectId) return events.value.filter(item => item.project === projectId)
}) })
const getTimesByProjectId = computed(() => (projectId:string) => { const getTimesByProjectId = computed(() => (projectId) => {
return times.value.filter(time => time.projectId === projectId) return times.value.filter(time => time.projectId === projectId)
}) })
const getTasksByProjectId = computed(() => (projectId:string) => { const getTasksByProjectId = computed(() => (projectId) => {
return tasks.value.filter(item => item.project === projectId) return tasks.value.filter(item => item.project === projectId)
}) })
const getTasksByPlantId = computed(() => (plantId:string) => { const getTasksByPlantId = computed(() => (plantId) => {
return tasks.value.filter(item => item.plant === plantId) return tasks.value.filter(item => item.plant === plantId)
}) })
const getProjectsByPlantId = computed(() => (plantId:string) => { const getProjectsByPlantId = computed(() => (plantId) => {
return projects.value.filter(item => item.plant === plantId) return projects.value.filter(item => item.plant === plantId)
}) })
const getIncomingInvoicesByVehicleId = computed(() => (vehicleId:string) => { const getIncomingInvoicesByVehicleId = computed(() => (vehicleId) => {
return incomingInvoices.value.filter(i => i.accounts.find(a => a.costCentre === vehicleId)) return incomingInvoices.value.filter(i => i.accounts.find(a => a.costCentre === vehicleId))
}) })
const getMovementsBySpaceId = computed(() => (spaceId:string) => { const getMovementsBySpaceId = computed(() => (spaceId) => {
return movements.value.filter(movement => movement.spaceId === spaceId) return movements.value.filter(movement => movement.spaceId === spaceId)
}) })
const getMessagesByChatId = computed(() => (chatId:string) => { const getMessagesByChatId = computed(() => (chatId) => {
return messages.value.filter(i => i.destination === chatId) return messages.value.filter(i => i.destination === chatId)
}) })
const getStockByProductId = computed(() => (productId:string) => { const getStockByProductId = computed(() => (productId) => {
let productMovements = movements.value.filter(movement => movement.productId === productId) let productMovements = movements.value.filter(movement => movement.productId === productId)
let count = 0 let count = 0
@@ -595,63 +673,67 @@ export const useDataStore = defineStore('data', () => {
//Get Item By Id //Get Item By Id
const getProductById = computed(() => (itemId:string) => { const getProductById = computed(() => (itemId) => {
return products.value.find(item => item.id === itemId) return products.value.find(item => item.id === itemId)
}) })
const getVendorById = computed(() => (itemId:string) => { const getVendorById = computed(() => (itemId) => {
return vendors.value.find(item => item.id === itemId) return vendors.value.find(item => item.id === itemId)
}) })
const getIncomingInvoiceById = computed(() => (itemId:string) => { const getIncomingInvoiceById = computed(() => (itemId) => {
return incomingInvoices.value.find(item => item.id === itemId) return incomingInvoices.value.find(item => item.id === itemId)
}) })
const getContractById = computed(() => (itemId:string) => { const getContractById = computed(() => (itemId) => {
return contracts.value.find(item => item.id === itemId) return contracts.value.find(item => item.id === itemId)
}) })
const getContactById = computed(() => (itemId:string) => { const getContactById = computed(() => (itemId) => {
return contacts.value.find(item => item.id === itemId) return contacts.value.find(item => item.id === itemId)
}) })
const getVehicleById = computed(() => (itemId:string) => { const getVehicleById = computed(() => (itemId) => {
return vehicles.value.find(item => item.id === itemId) return vehicles.value.find(item => item.id === itemId)
}) })
const getDocumentById = computed(() => (itemId:string) => { const getDocumentById = computed(() => (itemId) => {
return documents.value.find(item => item.id === itemId) return documents.value.find(item => item.id === itemId)
}) })
const getSpaceById = computed(() => (itemId:string) => { const getSpaceById = computed(() => (itemId) => {
return spaces.value.find(item => item.id === itemId) return spaces.value.find(item => item.id === itemId)
}) })
const getCustomerById = computed(() => (itemId:number) => { const getCustomerById = computed(() => (itemId) => {
return customers.value.find(item => item.id === itemId) return customers.value.find(item => item.id === itemId)
}) })
const getTaskById = computed(() => (itemId:string) => { const getTaskById = computed(() => (itemId) => {
return tasks.value.find(item => item.id === itemId) return tasks.value.find(item => item.id === itemId)
}) })
const getAbsenceRequestById = computed(() => (itemId:string) => { const getAbsenceRequestById = computed(() => (itemId) => {
return absenceRequests.value.find(item => item.id === itemId) return absenceRequests.value.find(item => item.id === itemId)
}) })
const getProfileById = computed(() => (itemId:string) => { const getProfileById = computed(() => (itemId) => {
return profiles.value.find(item => item.id === itemId) return profiles.value.find(item => item.id === itemId)
}) })
const getAccountById = computed(() => (accountId:string) => { const getAccountById = computed(() => (accountId) => {
return accounts.value.find(item => item.id === accountId) return accounts.value.find(item => item.id === accountId)
}) })
const getPlantById = computed(() => (plantId:string) => { const getPlantById = computed(() => (plantId) => {
return plants.value.find(item => item.id === plantId) return plants.value.find(item => item.id === plantId)
}) })
const getProjectById = computed(() => (itemId:string) => { const getCreatedDocumentById = computed(() => (documentId) => {
return createdDocuments.value.find(item => item.id === documentId)
})
const getProjectById = computed(() => (itemId) => {
if(projects.value.find(i => i.id === itemId)) { if(projects.value.find(i => i.id === itemId)) {
let project = projects.value.find(project => project.id === itemId) let project = projects.value.find(project => project.id === itemId)
@@ -672,8 +754,14 @@ export const useDataStore = defineStore('data', () => {
}) })
return { return {
//General
currentTenant,
loaded, loaded,
ownTenant, ownTenant,
initializeData,
changeTenant,
//Data
profiles, profiles,
events, events,
customers, customers,
@@ -704,6 +792,8 @@ export const useDataStore = defineStore('data', () => {
inventoryItems, inventoryItems,
chats, chats,
messages, messages,
createdDocuments,
documentTypesForCreation,
//Functions //Functions
createNewItem, createNewItem,
updateItem, updateItem,
@@ -741,6 +831,7 @@ export const useDataStore = defineStore('data', () => {
addHistoryItem, addHistoryItem,
//Getters //Getters
getOpenTasksCount, getOpenTasksCount,
getOwnProfile,
getMovementsBySpace, getMovementsBySpace,
getContactsByCustomerId, getContactsByCustomerId,
getContactsByVendorId, getContactsByVendorId,
@@ -776,7 +867,8 @@ export const useDataStore = defineStore('data', () => {
getProjectById, getProjectById,
getProfileById, getProfileById,
getAccountById, getAccountById,
getPlantById getPlantById,
getCreatedDocumentById
} }