Many Changes

This commit is contained in:
2025-01-05 18:23:44 +01:00
parent 1c6c6e4a33
commit efbb97967a
16 changed files with 970 additions and 441 deletions

View File

@@ -457,7 +457,7 @@ const renderCurrency = (value, currency = "€") => {
const documentTotal = computed(() => {
let totalNet = 0
let total19 = 0
let totalGross = 0
let total7 = 0
itemInfo.value.rows.forEach(row => {
if(!['pagebreak','title','text'].includes(row.mode)){
@@ -466,11 +466,13 @@ const documentTotal = computed(() => {
if(row.taxPercent === 19) {
total19 = total19 + Number(rowPrice * 0.19)
} else if(row.taxPercent === 7) {
total7 = total7 + Number(rowPrice * 0.07)
}
}
})
totalGross = totalNet + total19
let totalGross = Number(totalNet.toFixed(2)) + Number(total19.toFixed(2)) + Number(total7.toFixed(2))
let totalGrossAlreadyPaid = 0
@@ -488,19 +490,14 @@ const documentTotal = computed(() => {
let sumToPay = totalGross - totalGrossAlreadyPaid
return {
totalNet: totalNet,
total19: total19,
total7: total7,
totalGross: totalGross,
totalGrossAlreadyPaid: totalGrossAlreadyPaid,
totalSumToPay: sumToPay
}
})
const processDieselPosition = () => {
@@ -831,14 +828,13 @@ const closeDocument = async () => {
await generateDocument()
let fileData = {
tags: [],
project: null
}
let fileData = {}
fileData.project = itemInfo.value.project
fileData.createdDocument = itemInfo.value.id
fileData.tags.push(dataStore.documentTypesForCreation[itemInfo.value.type].labelSingle)
fileData.createddocument = itemInfo.value.id
fileData.folder = (await supabase.from("folders").select("id").eq("tenant", profileStore.currentTenant).eq("function", itemInfo.value.type).eq("year",dayjs().format("YYYY")).single()).data.id
let tag = (await supabase.from("filetags").select("id").eq("tenant", profileStore.currentTenant).eq("createddocumenttype", itemInfo.value.type).single()).data
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(","),
@@ -854,7 +850,7 @@ const closeDocument = async () => {
let file = dataURLtoFile(uri.value, `${itemInfo.value.documentNumber}.pdf`)
await dataStore.uploadFiles(fileData, [file], true)
await dataStore.uploadFiles(fileData, [file],[tag.id], true)
await router.push(`/createDocument/show/${itemInfo.value.id}`)
@@ -894,13 +890,28 @@ const setRowData = (row) => {
<template>
<UDashboardNavbar>
<template #right>
<!-- <ButtonWithConfirm
v-if="itemInfo.state === 'Entwurf'"
color="rose"
variant="outline"
@confirmed="dataStore.updateItem('createddocuments',{id:itemInfo.id,archived: true}),
router.push('/createDocument')"
>
<template #button>
Archivieren
</template>
<template #header>
<span class="text-md text-black font-bold">Archivieren bestätigen</span>
</template>
Möchten Sie diesen Ausgangsbeleg wirklich archivieren?
</ButtonWithConfirm>-->
<UButton
icon="i-mdi-content-save"
@click="saveDocument('Entwurf',true)"
v-if="itemInfo.type !== 'serialInvoices' "
:disabled="!itemInfo.customer"
>
Entwurf
Entwurf speichern
</UButton>
<UButton
@click="closeDocument"
@@ -952,7 +963,7 @@ const setRowData = (row) => {
v-model="itemInfo.type"
value-attribute="type"
option-attribute="label"
@input="setDocumentTypeConfig"
@change="setDocumentTypeConfig"
class="flex-auto"
>
<template #label>

View File

@@ -21,9 +21,16 @@ const linkedDocument =ref({})
const currentTenant = ref({})
const setupPage = async () => {
if(route.params) {
if(route.params.id) itemInfo.value = await useSupabaseSelectSingle("createddocuments",route.params.id,"*")
const {data,error} = await supabase.from("documents").select("id").eq("createdDocument", route.params.id).order("id",{ascending:true})
linkedDocument.value = data[data.length -1]
if(route.params.id) itemInfo.value = await useSupabaseSelectSingle("createddocuments",route.params.id,"*, files(*)")
console.log(itemInfo.value)
linkedDocument.value = await useFiles().selectDocument(itemInfo.value.files[0].id)
//const {data,error} = await supabase.from("files").select("id").eq("createddocument", route.params.id).order("id",{ascending:true})
//linkedDocument.value = data[data.length -1]
}
@@ -72,11 +79,19 @@ const openEmail = () => {
>
E-Mail
</UButton>
<UButton
v-if="itemInfo.project"
@click="router.push(`/standardEntity/projects/show/${itemInfo.project}`)"
icon="i-heroicons-arrow-right-end-on-rectangle"
variant="outline"
>
Projekt
</UButton>
</template>
</UDashboardToolbar>
<UDashboardPanelContent>
<object
:data="dataStore.documents.find(i => i.id === linkedDocument.id) ? dataStore.documents.find(i => i.id === linkedDocument.id).url : ''"
:data="linkedDocument.url"
class="h-full"
/>
</UDashboardPanelContent>

View File

@@ -2,22 +2,66 @@
import {BlobReader, BlobWriter, ZipWriter} from "@zip.js/zip.js";
import {useSupabaseSelectDocuments, useSupabaseSelectSingle} from "~/composables/useSupabase.js";
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
import DocumentDisplayModal from "~/components/DocumentDisplayModal.vue";
import dayjs from "dayjs";
definePageMeta({
middleware: "auth"
})
defineShortcuts({
/*'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},*/
'+': () => {
//Hochladen
uploadModalOpen.value = true
},
'Enter': {
usingInput: true,
handler: () => {
let entry = renderedFileList.value[selectedFileIndex.value]
if(entry.type === "file") {
showFile(entry.id)
console.log(entry)
} else {
changeFolder(currentFolders.value.find(i => i.id === entry.id))
}
}
},
'arrowdown': () => {
if(selectedFileIndex.value < renderedFileList.value.length - 1) {
selectedFileIndex.value += 1
} else {
selectedFileIndex.value = 0
}
},
'arrowup': () => {
if(selectedFileIndex.value === 0) {
selectedFileIndex.value = renderedFileList.value.length - 1
} else {
selectedFileIndex.value -= 1
}
}
})
const dataStore = useDataStore()
const profileStore = useProfileStore()
const supabase = useSupabaseClient()
const user = useSupabaseUser()
const toast = useToast()
const router = useRouter()
const route = useRoute()
const slideover = useSlideover()
const modal = useModal()
dataStore.fetchDocuments()
const uploadModalOpen = ref(false)
const createFolderModalOpen = ref(false)
const uploadInProgress = ref(false)
const fileUploadFormData = ref({
tags: ["Eingang"],
@@ -26,11 +70,18 @@ const fileUploadFormData = ref({
folder: null
})
const files = useFiles()
let tags = dataStore.getDocumentTags
const displayMode = ref("list")
const displayModes = ref([{label: 'Liste',key:'list', icon: 'i-heroicons-list-bullet'},{label: 'Kacheln',key:'rectangles', icon: 'i-heroicons-squares-2x2'}])
const documents = ref([])
const folders = ref([])
const filetags = ref([])
const currentFolder = ref(null)
@@ -39,11 +90,12 @@ const isDragTarget = ref(false)
const setupPage = async () => {
folders.value = await useSupabaseSelect("folders")
documents.value = await useSupabaseSelectDocuments("*",null)
documents.value = await files.selectDocuments()
filetags.value = await useSupabaseSelect("filetags")
if(route.query) {
if(route.query.folder) {
console.log(route.query.folder)
currentFolder.value = await useSupabaseSelectSingle("folders", route.query.folder)
}
}
@@ -135,10 +187,6 @@ const breadcrumbLinks = computed(() => {
}
})
const filteredDocuments = computed(() => {
return documents.value.filter(i => currentFolder.value ? i.folder === currentFolder.value.id : !i.folder)
@@ -151,20 +199,38 @@ const changeFolder = async (newFolder) => {
if(newFolder) {
fileUploadFormData.value.folder = newFolder.id
await router.push(`/documents?folder=${newFolder.id}`)
await router.push(`/files?folder=${newFolder.id}`)
} else {
fileUploadFormData.value.folder = null
await router.push(`/documents`)
await router.push(`/files`)
}
setupPage()
}
const createFolderData = ref({})
const createFolder = async () => {
const {data,error} = await supabase
.from("folders")
.insert({
tenant: profileStore.currentTenant,
parent: currentFolder.value ? currentFolder.value.id : undefined,
name: createFolderData.value.name,
})
createFolderModalOpen.value = false
setupPage()
}
const uploadFiles = async (files) => {
uploadInProgress.value = true;
if(files) {
await dataStore.uploadFiles({tags: ["Ablage"],tenant: profileStore.currentTenant,folder: currentFolder.value.id}, files, true)
//await dataStore.uploadFiles({tags: ["Ablage"],tenant: profileStore.currentTenant,folder: currentFolder.value.id}, files, true)
await dataStore.uploadFiles({tags: ["Ablage"],tenant: profileStore.currentTenant}, files, true)
} else {
await dataStore.uploadFiles(fileUploadFormData.value, document.getElementById("fileUploadInput").files, true)
@@ -237,37 +303,46 @@ const downloadSelected = async () => {
link.click();
}
const renderedFileList = computed(() => {
let files = filteredDocuments.value.map(i => {
return {
label: i.path.split("/")[i.path.split("/").length -1],
id: i.id,
type: "file"
}
})
let folders = currentFolders.value.map(i => {
return {
label: i.name,
id: i.id,
type: "folder"
}
})
return [...folders,...files]
})
const selectedFileIndex = ref(0)
const showFile = (fileId) => {
console.log(fileId)
modal.open(DocumentDisplayModal,{
documentData: documents.value.find(i => i.id === fileId),
})
}
</script>
<template>
<UDashboardNavbar
title="Dateien"
>
</UDashboardNavbar>
<!-- <UDashboardToolbar>
<template #right>
<UButton @click="uploadModalOpen = true">Hochladen</UButton>
&lt;!&ndash; <UButton
@click="downloadSelected"
:disabled="dataStore.documents.filter(doc => doc.selected).length === 0"
>Herunterladen</UButton>&ndash;&gt;
</template>
&lt;!&ndash; <template #right>
<USelectMenu
:options="tags"
v-model="selectedTags"
class="w-40"
>
<template #label>
{{selectedTags}}
</template>
</USelectMenu>
</template>&ndash;&gt;
</UDashboardToolbar>-->
<UDashboardToolbar>
<template #left>
<UBreadcrumb
@@ -275,49 +350,125 @@ const downloadSelected = async () => {
/>
</template>
<template #right>
<UButton @click="uploadModalOpen = true">Hochladen</UButton>
<USelectMenu
:options="displayModes"
value-attribute="key"
option-attribute="label"
v-model="displayMode"
:ui-menu="{ width: 'min-w-max'}"
>
<template #label>
<UIcon class="w-5 h-5" :name="displayModes.find(i => i.key === displayMode).icon"/>
</template>
</USelectMenu>
<UButton @click="uploadModalOpen = true">+ Hochladen</UButton>
<UButton
@click="createFolderModalOpen = true"
variant="outline"
>+ Ordner</UButton>
<UModal
v-model="createFolderModalOpen"
>
<UCard>
<template #header>
Ordner Erstellen
</template>
<UFormGroup
label="Ordner erstellen"
>
<UInput
v-model="createFolderData.name"
/>
</UFormGroup>
<template #footer>
<UButton
@click="createFolder"
>
Erstellen
</UButton>
</template>
</UCard>
</UModal>
</template>
</UDashboardToolbar>
<div id="drop_zone" class="h-full scrollList">
<UDashboardPanelContent v-if="!isDragTarget" >
<div class="flex flex-row w-full flex-wrap" v-if="currentFolders.length > 0">
<a
class="w-1/6 folderIcon flex flex-col p-5 m-2"
v-for="folder in currentFolders"
@click="changeFolder(folder)"
>
<div v-if="displayMode === 'list'">
<table class="w-full">
<thead>
<td class="font-bold">Name</td>
<td class="font-bold">Erstellt am</td>
</thead>
<tr v-for="(entry,index) in renderedFileList">
<td>
<UIcon :name="entry.type === 'folder' ? 'i-heroicons-folder' : 'i-heroicons-document'"/>
<a
:class="[...index === selectedFileIndex ? ['text-primary'] : ['dark:text-white','text-black']]"
@click="entry.type === 'folder' ? changeFolder(currentFolders.find(i => i.id === entry.id)) : showFile(entry.id)"
>{{entry.label}}</a>
<UIcon
name="i-heroicons-folder"
class="w-20 h-20"
</td>
<td>
<span v-if="entry.type === 'file'">{{dayjs(documents.find(i => i.id === entry.id).created_at).format("DD.MM.YY HH:mm")}}</span>
<span v-if="entry.type === 'folder'">{{dayjs(currentFolders.find(i => i.id === entry.id).created_at).format("DD.MM.YY HH:mm")}}</span>
</td>
</tr>
</table>
</div>
<div v-else-if="displayMode === 'rectangles'">
<div class="flex flex-row w-full flex-wrap" v-if="currentFolders.length > 0">
<a
class="w-1/6 folderIcon flex flex-col p-5 m-2"
v-for="folder in currentFolders"
@click="changeFolder(folder)"
>
<UIcon
name="i-heroicons-folder"
class="w-20 h-20"
/>
<span class="text-center truncate">{{folder.name}}</span>
</a>
</div>
<UDivider class="my-5" v-if="currentFolder">{{currentFolder.name}}</UDivider>
<UDivider class="my-5" v-else>Ablage</UDivider>
<div v-if="!loadingDocs">
<DocumentList
v-if="filteredDocuments.length > 0"
:documents="filteredDocuments"
@selectDocument="(info) => console.log(info)"
/>
<span class="text-center truncate">{{folder.name}}</span>
</a>
</div>
<UDivider class="my-5" v-if="currentFolder">{{currentFolder.name}}</UDivider>
<UDivider class="my-5" v-else>Ablage</UDivider>
<div v-if="!loadingDocs">
<DocumentList
v-if="filteredDocuments.length > 0"
:documents="filteredDocuments"
@selectDocument="(info) => console.log(info)"
/>
<UAlert
<UAlert
v-else
class="mt-5 w-1/2 mx-auto"
icon="i-heroicons-light-bulb"
title="Keine Dokumente vorhanden"
color="primary"
variant="outline"
/>
</div>
<UProgress
animation="carousel"
v-else
class="mt-5 w-1/2 mx-auto"
icon="i-heroicons-light-bulb"
title="Keine Dokumente vorhanden"
color="primary"
variant="outline"
class="w-2/3 my-5 mx-auto"
/>
</div>
<UProgress
animation="carousel"
v-else
class="w-2/3 my-5 mx-auto"
/>
</UDashboardPanelContent>
<UCard
@@ -361,7 +512,9 @@ const downloadSelected = async () => {
multiple
searchable
searchable-placeholder="Suchen..."
:options="tags"
option-attribute="name"
value-attribute="id"
:options="filetags"
v-model="fileUploadFormData.tags"
/>
</UFormGroup>
@@ -382,8 +535,6 @@ const downloadSelected = async () => {
</USlideover>
</template>
<style scoped>
.folderIcon {
border: 1px solid lightgrey;
@@ -396,4 +547,8 @@ const downloadSelected = async () => {
color: #69c350;
}
tr:nth-child(odd) {
background-color: rgba(0, 0, 0, 0.2);
}
</style>

View File

@@ -0,0 +1,20 @@
<script setup lang="ts">
</script>
<template>
<UDashboardNavbar>
<template #center>
<h1
:class="['text-xl','font-medium']"
>Zentrales Logbuch</h1>
</template>
</UDashboardNavbar>
<UDashboardPanelContent>
<HistoryDisplay/>
</UDashboardPanelContent>
</template>
<style scoped>
</style>

View File

@@ -96,11 +96,15 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
</UModal>
<UDashboardNavbar title="E-Mail Konten">
<template #right>
<UButton
@click="showEmailAddressModal = true"
>
+ E-Mail Konto
</UButton>
<UTooltip title="In der Beta nicht verfügbar">
<UButton
:disabled="true"
@click="showEmailAddressModal = true"
>
+ E-Mail Konto
</UButton>
</UTooltip>
</template>
</UDashboardNavbar>
<UTable