Changed Plants to Objects
Changes in outgoinginvoices
This commit is contained in:
@@ -44,7 +44,8 @@ const itemInfo = ref({
|
||||
end: "",
|
||||
notes: null,
|
||||
projectId: null,
|
||||
type: null
|
||||
type: null,
|
||||
state: "Entwurf"
|
||||
})
|
||||
|
||||
|
||||
@@ -300,9 +301,10 @@ const setState = async (newState) => {
|
||||
:dark="useColorMode().value !== 'light'"
|
||||
:format="format"
|
||||
:preview-format="format"
|
||||
:disabled="itemInfo.state !== 'Entwurf'"
|
||||
:disabled="configTimeMode === 'create' ? false : itemInfo.state !== 'Entwurf'"
|
||||
/>
|
||||
</UFormGroup>
|
||||
{{itemInfo.state === 'Entwurf'}}{{itemInfo.state}}
|
||||
<UFormGroup
|
||||
label="Ende:"
|
||||
>
|
||||
@@ -316,7 +318,7 @@ const setState = async (newState) => {
|
||||
:dark="useColorMode().value !== 'light'"
|
||||
:format="format"
|
||||
:preview-format="format"
|
||||
:disabled="itemInfo.state !== 'Entwurf'"
|
||||
:disabled="configTimeMode === 'create' ? false : itemInfo.state !== 'Entwurf'"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<!-- <UFormGroup
|
||||
@@ -334,7 +336,7 @@ const setState = async (newState) => {
|
||||
v-model="itemInfo.user"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
:disabled="itemInfo.state !== 'Entwurf'"
|
||||
:disabled="configTimeMode === 'create' ? false : itemInfo.state !== 'Entwurf'"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.profiles.find(profile => profile.id === itemInfo.user) ? dataStore.profiles.find(profile => profile.id === itemInfo.user).firstName : "Benutzer auswählen"}}
|
||||
@@ -352,7 +354,7 @@ const setState = async (newState) => {
|
||||
searchable
|
||||
searchable-placeholder="Suche..."
|
||||
:search-attributes="['name']"
|
||||
:disabled="itemInfo.state !== 'Entwurf'"
|
||||
:disabled="configTimeMode === 'create' ? false : itemInfo.state !== 'Entwurf'"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.projects.find(project => project.id === itemInfo.projectId) ? dataStore.projects.find(project => project.id === itemInfo.projectId).name : "Projekt auswählen"}}
|
||||
@@ -367,7 +369,7 @@ const setState = async (newState) => {
|
||||
:options="timeTypes"
|
||||
option-attribute="label"
|
||||
value-attribute="label"
|
||||
:disabled="itemInfo.state !== 'Entwurf'"
|
||||
:disabled="configTimeMode === 'create' ? false : itemInfo.state !== 'Entwurf'"
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.type ? itemInfo.type : "Kategorie auswählen"}}
|
||||
@@ -379,7 +381,7 @@ const setState = async (newState) => {
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.notes"
|
||||
:disabled="itemInfo.state !== 'Entwurf'"
|
||||
:disabled="configTimeMode === 'create' ? false : itemInfo.state !== 'Entwurf'"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
|
||||
835
spaces/pages/outgoingInvoices.vue
Normal file
835
spaces/pages/outgoingInvoices.vue
Normal file
@@ -0,0 +1,835 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs"
|
||||
const dataStore = useDataStore()
|
||||
const user = useSupabaseUser()
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
label: "Editor"
|
||||
},
|
||||
{
|
||||
label: "Vorschau"
|
||||
}
|
||||
]
|
||||
|
||||
const itemInfo = ref({
|
||||
customer: 13,
|
||||
contact: 8,
|
||||
address: {
|
||||
street: null,
|
||||
special: null,
|
||||
zip: null,
|
||||
city: null,
|
||||
},
|
||||
project: 6,
|
||||
documentNumber: "RE23-1409",
|
||||
documentDate: "10.01.2024",
|
||||
deliveryDate: "10.01.2024",
|
||||
dateOfPerformance: null,
|
||||
createdBy: user.value.id,
|
||||
title: "TITEL",
|
||||
description: "BESCHREIBUNG",
|
||||
startText: "Sehr geehrte Frau Sindern,\n" +
|
||||
"wir bedanken uns für Ihr entgegengebrachtes Vertrauen und Ihren Auftrag und stellen Ihnen\n" +
|
||||
"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.",
|
||||
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 getRowAmount = (row) => {
|
||||
return String(Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(2)).replace('.',',')
|
||||
}
|
||||
|
||||
const addPosition = (mode) => {
|
||||
|
||||
let lastId = 0
|
||||
itemInfo.value.rows.forEach(row => {
|
||||
if(row.id > lastId) lastId = row.id
|
||||
})
|
||||
|
||||
if(mode === 'free'){
|
||||
itemInfo.value.rows.push({
|
||||
id: lastId +1,
|
||||
mode: "free",
|
||||
text: "",
|
||||
quantity: 1,
|
||||
unit: 1,
|
||||
price: 0,
|
||||
taxPercent: 19,
|
||||
discountPercent: 0
|
||||
})
|
||||
} else if(mode === 'normal'){
|
||||
itemInfo.value.rows.push({
|
||||
id: lastId +1,
|
||||
mode: "normal",
|
||||
quantity: 1,
|
||||
price: 0,
|
||||
taxPercent: 19,
|
||||
discountPercent: 0
|
||||
})
|
||||
} else if(mode === "pagebreak") {
|
||||
itemInfo.value.rows.push({
|
||||
id: lastId +1,
|
||||
mode: "pagebreak",
|
||||
})
|
||||
}
|
||||
|
||||
setPosNumbers()
|
||||
|
||||
|
||||
}
|
||||
|
||||
const removePosition = (id) => {
|
||||
let rows = itemInfo.value.rows.filter(row => row.id !== id)
|
||||
/*rows = rows.sort((a,b) => a.pos - b.pos)
|
||||
|
||||
rows.forEach((row,index) => {
|
||||
rows[index] = {...row, pos: index + 1}
|
||||
})*/
|
||||
|
||||
itemInfo.value.rows = rows
|
||||
setPosNumbers()
|
||||
|
||||
|
||||
}
|
||||
|
||||
const documentTotal = computed(() => {
|
||||
let totalNet = 0
|
||||
let total19 = 0
|
||||
let totalGross = 0
|
||||
|
||||
itemInfo.value.rows.forEach(row => {
|
||||
if(row.mode === 'free' || row.mode === 'normal'){
|
||||
let rowPrice = Number(Number(row.quantity) * Number(row.price)).toFixed(2)
|
||||
totalNet += Number(rowPrice)
|
||||
|
||||
if(row.taxPercent === 19) {
|
||||
total19 += Number(rowPrice * 0.19)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
totalNet: `${String(totalNet.toFixed(2)).replace(".",",")} €`,
|
||||
total19: `${String(total19.toFixed(2)).replace(".",",")} €`,
|
||||
totalGross: `${String(Number(totalNet + total19).toFixed(2)).replace(".",",")} €`
|
||||
}
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
const getDocumentData = () => {
|
||||
|
||||
let customerData = dataStore.getCustomerById(itemInfo.value.customer)
|
||||
let contactData = dataStore.getContactById(itemInfo.value.contact)
|
||||
let userData = dataStore.getProfileById(user.value.id)
|
||||
|
||||
|
||||
|
||||
|
||||
let rows = itemInfo.value.rows.map(row => {
|
||||
|
||||
let unit = dataStore.units.find(i => i.id === row.unit)
|
||||
|
||||
if(row.mode === 'free' || row.mode === 'normal') {
|
||||
if(row.mode === 'normal') row.text = dataStore.getProductById(row.product).name
|
||||
|
||||
return {
|
||||
...row,
|
||||
rowAmount: `${getRowAmount(row)} €`,
|
||||
quantity: String(row.quantity).replace(".",","),
|
||||
unit: unit.short,
|
||||
pos: String(row.pos),
|
||||
price: `${String(row.price.toFixed(2)).replace(".",",")} €`,
|
||||
discountText: `(Rabatt: ${row.discountPercent} %)`
|
||||
}
|
||||
} else {
|
||||
return row
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
const returnData = {
|
||||
|
||||
recipient: {
|
||||
name: customerData.name,
|
||||
contact: `${contactData.firstName} ${contactData.lastName}`,
|
||||
street: customerData.infoData.street,
|
||||
special: "",
|
||||
city: customerData.infoData.city,
|
||||
zip: customerData.infoData.zip
|
||||
},
|
||||
info: {
|
||||
customerNumber: customerData.customerNumber,
|
||||
documentNumber: itemInfo.value.documentNumber,
|
||||
documentDate: dayjs(itemInfo.value.documentDate, 'DD.MM.YYYY').format("DD.MM.YYYY"),
|
||||
deliveryDate: dayjs(itemInfo.value.deliveryDate, 'DD.MM.YYYY').format("DD.MM.YYYY"),
|
||||
contactPerson: userData.fullName ||"",
|
||||
contactTel: userData.mobileTel ||"",
|
||||
contactEMail: userData.email,
|
||||
project: dataStore.getProjectById(itemInfo.value.project).name
|
||||
},
|
||||
title: itemInfo.value.title,
|
||||
description: itemInfo.value.description,
|
||||
endText: itemInfo.value.endText,
|
||||
startText: itemInfo.value.startText,
|
||||
rows: rows,
|
||||
total: documentTotal.value
|
||||
}
|
||||
|
||||
console.log(returnData)
|
||||
|
||||
return returnData
|
||||
}
|
||||
|
||||
|
||||
const showDocument = ref(false)
|
||||
const uri = ref("")
|
||||
const generateDocument = async () => {
|
||||
uri.value = await useCreatePdf(getDocumentData())
|
||||
//alert(uri.value)
|
||||
showDocument.value = true
|
||||
|
||||
}
|
||||
|
||||
const onChangeTab = (index) => {
|
||||
if(index === 1) {
|
||||
generateDocument()
|
||||
}
|
||||
}
|
||||
|
||||
const setPosNumbers = () => {
|
||||
let index = 1
|
||||
let rows = itemInfo.value.rows.map(row => {
|
||||
if(row.mode === 'free' ||row.mode === 'normal') {
|
||||
row.pos = index
|
||||
index += 1
|
||||
}
|
||||
return row
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <UButton
|
||||
@click="createPdf"
|
||||
>TEST</UButton>-->
|
||||
<UCard class="h-fit">
|
||||
<UTabs :items="tabItems" @change="onChangeTab">
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Editor'">
|
||||
<InputGroup>
|
||||
<div class="flex-auto mr-5">
|
||||
<UFormGroup
|
||||
label="Kunde:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="dataStore.customers"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
:search-attributes="['name']"
|
||||
searchable
|
||||
searchable-placeholder="Suche..."
|
||||
v-model="itemInfo.customer"
|
||||
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kein Kunde ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Ansprechpartner:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="dataStore.getContactsByCustomerId(itemInfo.customer)"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
:search-attributes="['name']"
|
||||
searchable
|
||||
searchable-placeholder="Suche..."
|
||||
v-model="itemInfo.contact"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getContactById(itemInfo.contact) ? dataStore.getContactById(itemInfo.contact).fullName : "Kein Kontakt ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Adresse:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.address.street"
|
||||
:placeholder="dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).infoData.street : 'Straße + Hausnummer'"
|
||||
/>
|
||||
<UInput
|
||||
v-model="itemInfo.address.special"
|
||||
class="mt-3"
|
||||
:placeholder="dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).infoData.special : 'Adresszusatz'"
|
||||
|
||||
/>
|
||||
<InputGroup class="mt-3">
|
||||
<UInput
|
||||
class="flex-auto"
|
||||
v-model="itemInfo.address.zip"
|
||||
:placeholder="dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).infoData.zip : 'PLZ'"
|
||||
/>
|
||||
<UInput
|
||||
class="flex-auto"
|
||||
v-model="itemInfo.address.city"
|
||||
:placeholder="dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).infoData.city : 'Ort'"
|
||||
|
||||
/>
|
||||
</InputGroup>
|
||||
</UFormGroup>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="flex-auto">
|
||||
<UFormGroup
|
||||
label="Rechnungsnummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.documentNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Datum:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.documentDate"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Lieferdatum:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.deliveryDate"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Ansprechpartner:"
|
||||
>
|
||||
<UInput
|
||||
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Kontakt Telefon:"
|
||||
>
|
||||
<UInput
|
||||
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Kontakt E-Mail:"
|
||||
>
|
||||
<UInput
|
||||
|
||||
/>
|
||||
</UFormGroup><UFormGroup
|
||||
label="Kontakt E-Mail:"
|
||||
>
|
||||
<UInput
|
||||
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Projekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="dataStore.projects"
|
||||
v-model="itemInfo.project"
|
||||
value-attribute="id"
|
||||
option-attribute="name"
|
||||
searchable
|
||||
searchable-placeholder="Suche..."
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getProjectById(itemInfo.project) ? dataStore.getProjectById(itemInfo.project).name : "Kein Projekt ausgewählt"}}
|
||||
</template>
|
||||
<template #option="{option: project}">
|
||||
{{dataStore.getCustomerById(project.customer).name}} - {{project.name}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
</div>
|
||||
</InputGroup>
|
||||
|
||||
<UDivider
|
||||
class="my-3"
|
||||
/>
|
||||
|
||||
<UFormGroup
|
||||
label="Titel:"
|
||||
>
|
||||
<UInput v-model="itemInfo.title"/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
class="mt-3"
|
||||
>
|
||||
<UInput v-model="itemInfo.description"/>
|
||||
</UFormGroup>
|
||||
|
||||
<UDivider
|
||||
class="my-3"
|
||||
/>
|
||||
|
||||
<UFormGroup
|
||||
label="Einleitung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.startText"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UDivider
|
||||
class="my-3"
|
||||
/>
|
||||
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Pos.</th>
|
||||
<th>Produkt / Leistung</th>
|
||||
<th>Menge</th>
|
||||
<th>Einheit</th>
|
||||
<th>Preis</th>
|
||||
<th>Steuer</th>
|
||||
<th>Rabatt</th>
|
||||
<th>Gesamt</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
<draggable
|
||||
v-model="itemInfo.rows"
|
||||
handle=".handle"
|
||||
tag="tbody"
|
||||
itemKey="pos"
|
||||
@end="setPosNumbers"
|
||||
>
|
||||
<template #item="{element: row}">
|
||||
<tr
|
||||
|
||||
>
|
||||
<td>
|
||||
<UIcon
|
||||
class="handle"
|
||||
name="i-mdi-menu"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
v-if="row.mode === 'pagebreak'"
|
||||
colspan="8"
|
||||
>
|
||||
<UDivider/>
|
||||
</td>
|
||||
<td
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>{{row.pos}}</td>
|
||||
<td
|
||||
class="w-120"
|
||||
v-if="row.mode === 'free'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.text"
|
||||
maxlength="40"
|
||||
placeholder="Name"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
class="w-120"
|
||||
v-else-if="row.mode === 'normal'"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="dataStore.products"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
searchable-placeholder="Suche ..."
|
||||
:search-attributes="['name']"
|
||||
v-model="row.product"
|
||||
@change="row.unit = dataStore.getProductById(row.product).unit,
|
||||
row.price = dataStore.getProductById(row.product).sellingPrice || 0"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getProductById(row.product) ?dataStore.getProductById(row.product).name : "Kein Produkt ausgewählt" }}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</td>
|
||||
<td
|
||||
class="w-20"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.quantity"
|
||||
type="number"
|
||||
:step="dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).step : '1' "
|
||||
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
class="w-40"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="row.unit"
|
||||
:options="dataStore.units"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).name : "Keine Einheit gewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</td>
|
||||
<td
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.price"
|
||||
type="number"
|
||||
step="0.01"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</td>
|
||||
<td
|
||||
class="w-40"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['19','7','0']"
|
||||
v-model="row.taxPercent"
|
||||
>
|
||||
<template #option="{option}">
|
||||
{{option}} %
|
||||
</template>
|
||||
<template #label>
|
||||
{{row.taxPercent}} %
|
||||
</template>
|
||||
</USelectMenu>
|
||||
|
||||
</td>
|
||||
<td
|
||||
class="w-40"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.discountPercent"
|
||||
type="number"
|
||||
step="0.01"
|
||||
placeholder="0"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">%</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</td>
|
||||
<td
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<div class="text-right font-bold">{{getRowAmount(row)}} €</div>
|
||||
</td>
|
||||
<td>
|
||||
<UButton
|
||||
variant="ghost"
|
||||
color="rose"
|
||||
icon="i-heroicons-x-mark-16-solid"
|
||||
@click="removePosition(row.id)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</draggable>
|
||||
|
||||
|
||||
|
||||
<!-- <template v-for="row in itemInfo.rows">
|
||||
<tr
|
||||
|
||||
>
|
||||
<td
|
||||
v-if="row.mode === 'pagebreak'"
|
||||
colspan="8"
|
||||
>
|
||||
<UDivider/>
|
||||
</td>
|
||||
<td
|
||||
rowspan="2"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>{{row.pos}}</td>
|
||||
<td
|
||||
class="w-120"
|
||||
v-if="row.mode === 'free'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.text"
|
||||
maxlength="40"
|
||||
placeholder="Name"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
class="w-120"
|
||||
v-else-if="row.mode === 'normal'"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="dataStore.products"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
searchable-placeholder="Suche ..."
|
||||
:search-attributes="['name']"
|
||||
v-model="row.product"
|
||||
@change="row.unit = dataStore.getProductById(row.product).unit,
|
||||
row.price = dataStore.getProductById(row.product).sellingPrice || 0"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getProductById(row.product) ?dataStore.getProductById(row.product).name : "Kein Produkt ausgewählt" }}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</td>
|
||||
<td
|
||||
class="w-20"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.quantity"
|
||||
type="number"
|
||||
:step="dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).step : '1' "
|
||||
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
class="w-40"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="row.unit"
|
||||
:options="dataStore.units"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.units.find(i => i.id === row.unit) ? dataStore.units.find(i => i.id === row.unit).name : "Keine Einheit gewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</td>
|
||||
<td
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.price"
|
||||
type="number"
|
||||
step="0.01"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</td>
|
||||
<td
|
||||
class="w-40"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['19','7','0']"
|
||||
v-model="row.taxPercent"
|
||||
>
|
||||
<template #option="{option}">
|
||||
{{option}} %
|
||||
</template>
|
||||
<template #label>
|
||||
{{row.taxPercent}} %
|
||||
</template>
|
||||
</USelectMenu>
|
||||
<!– <UInput
|
||||
v-model="row.taxPercent"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">%</span>
|
||||
</template>
|
||||
</UInput>–>
|
||||
</td>
|
||||
<td
|
||||
class="w-40"
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
>
|
||||
<UInput
|
||||
v-model="row.discountPercent"
|
||||
type="number"
|
||||
step="0.01"
|
||||
placeholder="0"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">%</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</td>
|
||||
<td
|
||||
v-if="row.mode === 'free' || row.mode === 'normal'"
|
||||
rowspan="2"
|
||||
>
|
||||
<div class="text-right font-bold">{{getRowAmount(row)}} €</div>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<UButton
|
||||
variant="ghost"
|
||||
color="rose"
|
||||
icon="i-heroicons-x-mark-16-solid"
|
||||
@click="removePosition(row.pos)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<UTextarea
|
||||
v-model="row.description"
|
||||
placeholder="Beschreibung"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</template>-->
|
||||
|
||||
</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>
|
||||
<UButton
|
||||
@click="addPosition('normal')"
|
||||
class="mt-3"
|
||||
>
|
||||
+ Artikelposition
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="addPosition('free')"
|
||||
class="mt-3"
|
||||
>
|
||||
+ Freitextposition
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="addPosition('pagebreak')"
|
||||
class="mt-3"
|
||||
>
|
||||
+ Seitenumbruch
|
||||
</UButton>
|
||||
</InputGroup>
|
||||
|
||||
|
||||
|
||||
<UDivider
|
||||
class="my-3"
|
||||
/>
|
||||
|
||||
<UFormGroup
|
||||
label="Nachbemerkung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.endText"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Vorschau'">
|
||||
<!-- <UButton
|
||||
@click="generateDocument"
|
||||
>
|
||||
Show
|
||||
</UButton>-->
|
||||
|
||||
<object
|
||||
:data="uri"
|
||||
v-if="showDocument"
|
||||
type="application/pdf"
|
||||
class="w-full previewDocument"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
|
||||
|
||||
</UCard>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: .4em;
|
||||
}
|
||||
|
||||
/*tr:hover {
|
||||
border: 1px solid #69c350;
|
||||
}*/
|
||||
|
||||
.previewDocument {
|
||||
height: 80vh;
|
||||
}
|
||||
</style>
|
||||
@@ -12,6 +12,11 @@ const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
const editor = useEditor({
|
||||
content: "<p>I'm running Tiptap with Vue.js. 🎉</p>",
|
||||
extensions: [TiptapStarterKit],
|
||||
});
|
||||
|
||||
let currentItem = null
|
||||
|
||||
//Working
|
||||
@@ -25,6 +30,8 @@ const tabItems = [
|
||||
label: "Projekte"
|
||||
},{
|
||||
label: "Aufgaben"
|
||||
},{
|
||||
label: "Dokumentation"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -93,6 +100,11 @@ setupPage()
|
||||
|
||||
</UTable>
|
||||
</div>
|
||||
<div v-if="item.label === 'Dokumentation'">
|
||||
|
||||
<Editor/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div id="main">
|
||||
<InputGroup>
|
||||
<UButton @click="router.push(`/plants/create/`)">+ Anlage</UButton>
|
||||
<UButton @click="router.push(`/plants/create/`)">+ Objekt</UButton>
|
||||
|
||||
<UInput
|
||||
v-model="searchString"
|
||||
|
||||
@@ -479,7 +479,7 @@ setupPage()
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Anlage:"
|
||||
label="Objekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.plant"
|
||||
@@ -490,7 +490,7 @@ setupPage()
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getPlantById(itemInfo.plant) ? dataStore.getPlantById(itemInfo.plant).name : "Anlage auswählen"}}
|
||||
{{dataStore.getPlantById(itemInfo.plant) ? dataStore.getPlantById(itemInfo.plant).name : "Objekt auswählen"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
@@ -54,7 +54,7 @@ const itemColumns = [
|
||||
},
|
||||
{
|
||||
key: "plant",
|
||||
label: "Anlage",
|
||||
label: "Objekt",
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -55,7 +55,7 @@ const itemColumns = [
|
||||
|
||||
const selectItem = (item) => {
|
||||
console.log(item)
|
||||
router.push(`/inventory/spaces/show/${item.id} `)
|
||||
router.push(`/spaces/show/${item.id} `)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ setupPage()
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Anlage:"
|
||||
label="Objekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.plant"
|
||||
@@ -174,7 +174,7 @@ setupPage()
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getPlantById(itemInfo.plant) ? dataStore.getPlantById(itemInfo.plant).name : "Keine Anlage ausgewählt"}}
|
||||
{{dataStore.getPlantById(itemInfo.plant) ? dataStore.getPlantById(itemInfo.plant).name : "Kein Objekt ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
@@ -76,7 +76,7 @@ const columns = [
|
||||
sortable: true
|
||||
},{
|
||||
key: "plant",
|
||||
label: "Anlage:",
|
||||
label: "Objekt:",
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user