Start for Dev Branch
This commit is contained in:
@@ -57,7 +57,8 @@ const itemInfo = ref({
|
||||
dateDirection: "Rückwirkend",
|
||||
},
|
||||
letterhead: null,
|
||||
agriculture: {}
|
||||
agriculture: {},
|
||||
usedAdvanceInvoices: []
|
||||
})
|
||||
|
||||
|
||||
@@ -71,7 +72,10 @@ const selectedProductcategorie = ref(null)
|
||||
const services = ref([])
|
||||
const servicecategories = ref([])
|
||||
const selectedServicecategorie = ref(null)
|
||||
const customers = ref([])
|
||||
const contacts = ref([])
|
||||
|
||||
const loaded = ref(false)
|
||||
const setupPage = async () => {
|
||||
|
||||
letterheads.value = (await useSupabaseSelect("letterheads","*")).filter(i => i.documentTypes.length === 0 || i.documentTypes.includes(itemInfo.value.type))
|
||||
@@ -81,6 +85,8 @@ const setupPage = async () => {
|
||||
servicecategories.value = (await useSupabaseSelect("servicecategories","*"))
|
||||
products.value = (await useSupabaseSelect("products","*"))
|
||||
productcategories.value = (await useSupabaseSelect("productcategories","*"))
|
||||
customers.value = (await useSupabaseSelect("customers","*","customerNumber"))
|
||||
contacts.value = (await useSupabaseSelect("contacts","*"))
|
||||
if(productcategories.value.length > 0) selectedProductcategorie.value = productcategories.value[0].id
|
||||
if(servicecategories.value.length > 0) selectedServicecategorie.value = servicecategories.value[0].id
|
||||
|
||||
@@ -165,13 +171,33 @@ const setupPage = async () => {
|
||||
|
||||
}
|
||||
|
||||
if(route.query.project) itemInfo.value.project = Number(route.query.project)
|
||||
if(route.query.project) {
|
||||
itemInfo.value.project = Number(route.query.project)
|
||||
checkForOpenAdvanceInvoices()
|
||||
}
|
||||
if(route.query.contact) itemInfo.value.contact = Number(route.query.contact)
|
||||
if(route.query.customer) {
|
||||
itemInfo.value.customer = Number(route.query.customer)
|
||||
setCustomerData()
|
||||
}
|
||||
}
|
||||
|
||||
loaded.value = true
|
||||
|
||||
}
|
||||
|
||||
const openAdvanceInvoices = ref([])
|
||||
const checkForOpenAdvanceInvoices = async () => {
|
||||
const {data,error} = await supabase.from("createddocuments").select().eq("project", itemInfo.value.project).eq("advanceInvoiceResolved", false).eq("type","advanceInvoices")
|
||||
|
||||
console.log(data)
|
||||
|
||||
openAdvanceInvoices.value = data
|
||||
|
||||
}
|
||||
|
||||
const addAdvanceInvoiceToInvoice = (advanceInvoice) => {
|
||||
itemInfo.value.usedAdvanceInvoices.push(advanceInvoice)
|
||||
}
|
||||
|
||||
const setDocumentTypeConfig = (withTexts = false) => {
|
||||
@@ -201,7 +227,6 @@ const setDocumentTypeConfig = (withTexts = false) => {
|
||||
|
||||
const setCustomerData = () => {
|
||||
|
||||
|
||||
let customer = dataStore.getCustomerById(itemInfo.value.customer)
|
||||
itemInfo.value.contact = null
|
||||
if(customer) {
|
||||
@@ -210,6 +235,8 @@ const setCustomerData = () => {
|
||||
itemInfo.value.address.city = customer.infoData.city
|
||||
itemInfo.value.address.special = customer.infoData.special
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const setContactPersonData = async () => {
|
||||
@@ -256,8 +283,6 @@ const importPositions = () => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const getRowAmount = (row) => {
|
||||
return String(Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(2)).replace('.',',')
|
||||
}
|
||||
@@ -332,13 +357,6 @@ const addPosition = (mode) => {
|
||||
|
||||
}
|
||||
|
||||
|
||||
const showEditRowDescription = ref(false)
|
||||
const rowToEdit = ref("")
|
||||
|
||||
|
||||
|
||||
|
||||
const removePosition = (id) => {
|
||||
let rows = itemInfo.value.rows.filter(row => row.id !== id)
|
||||
/*rows = rows.sort((a,b) => a.pos - b.pos)
|
||||
@@ -353,6 +371,15 @@ const removePosition = (id) => {
|
||||
|
||||
}
|
||||
|
||||
const getRowMargin = (row) => {
|
||||
if(row.mode === "normal" && row.product) {
|
||||
let purchasePrice = dataStore.getProductById(row.product).purchasePrice || 0
|
||||
return row.price - purchasePrice
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
const findDocumentErrors = computed(() => {
|
||||
let errors = []
|
||||
|
||||
@@ -405,6 +432,7 @@ const tabItems = computed(() => {
|
||||
const renderCurrency = (value, currency = "€") => {
|
||||
return Number(value).toFixed(2).replace(".",",") + " €"
|
||||
}
|
||||
|
||||
const documentTotal = computed(() => {
|
||||
let totalNet = 0
|
||||
let total19 = 0
|
||||
@@ -412,7 +440,7 @@ const documentTotal = computed(() => {
|
||||
|
||||
itemInfo.value.rows.forEach(row => {
|
||||
if(!['pagebreak','title','text'].includes(row.mode)){
|
||||
let rowPrice = Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(2)
|
||||
let rowPrice = Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(3)
|
||||
totalNet = totalNet + Number(rowPrice)
|
||||
|
||||
if(row.taxPercent === 19) {
|
||||
@@ -421,11 +449,33 @@ const documentTotal = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
totalGross = totalNet + total19
|
||||
|
||||
let totalGrossAlreadyPaid = 0
|
||||
|
||||
itemInfo.value.usedAdvanceInvoices.forEach(advanceInvoiceId => {
|
||||
let advanceInvoice = openAdvanceInvoices.value.find(i => i.id === advanceInvoiceId)
|
||||
|
||||
let priceNet = advanceInvoice.rows.find(i => i.advanceInvoiceData).price
|
||||
|
||||
let partSum = priceNet * ((100 + advanceInvoice.rows.find(i => i.advanceInvoiceData).taxPercent) / 100)
|
||||
|
||||
totalGrossAlreadyPaid += partSum
|
||||
})
|
||||
|
||||
console.log(totalGrossAlreadyPaid)
|
||||
|
||||
let sumToPay = totalGross - totalGrossAlreadyPaid
|
||||
|
||||
|
||||
|
||||
return {
|
||||
totalNet: `${String(totalNet.toFixed(2)).replace(".",",")} €`,
|
||||
total19: `${String(total19.toFixed(2)).replace(".",",")} €`,
|
||||
totalGross: `${String(Number(totalNet + total19).toFixed(2)).replace(".",",")} €`
|
||||
totalGross: renderCurrency(totalGross),
|
||||
totalGrossAlreadyPaid: renderCurrency(totalGrossAlreadyPaid),
|
||||
totalSumToPay: renderCurrency(sumToPay)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -476,7 +526,6 @@ const processDieselPosition = () => {
|
||||
itemInfo.value.agriculture = {...itemInfo.value.agriculture, ...agricultureData}
|
||||
}
|
||||
|
||||
|
||||
const getDocumentData = () => {
|
||||
|
||||
let customerData = dataStore.getCustomerById(itemInfo.value.customer)
|
||||
@@ -532,6 +581,7 @@ const getDocumentData = () => {
|
||||
return {
|
||||
vorname:contactData && contactData.firstName,
|
||||
nachname: contactData && contactData.lastName,
|
||||
kundenname: customerData && customerData.name,
|
||||
zahlungsziel_in_tagen:itemInfo.paymentDays,
|
||||
diesel_gesamtverbrauch: (itemInfo.agriculture && itemInfo.agriculture.dieselUsageTotal) && itemInfo.agriculture.dieselUsageTotal
|
||||
}
|
||||
@@ -566,7 +616,10 @@ const getDocumentData = () => {
|
||||
startText: templateStartText(generateContext(itemInfo.value, contactData)),
|
||||
rows: rows,
|
||||
total: documentTotal.value,
|
||||
agriculture: itemInfo.value.agriculture
|
||||
agriculture: itemInfo.value.agriculture,
|
||||
usedAdvanceInvoices: itemInfo.value.usedAdvanceInvoices.map(i => {
|
||||
return openAdvanceInvoices.value.find(x => x.id === i)
|
||||
})
|
||||
}
|
||||
|
||||
//console.log(returnData)
|
||||
@@ -574,7 +627,6 @@ const getDocumentData = () => {
|
||||
return returnData
|
||||
}
|
||||
|
||||
|
||||
const showDocument = ref(false)
|
||||
const uri = ref("")
|
||||
const generateDocument = async () => {
|
||||
@@ -712,7 +764,8 @@ const saveDocument = async (state) => {
|
||||
contactPerson: itemInfo.value.contactPerson,
|
||||
linkedDocument: itemInfo.value.linkedDocument,
|
||||
agriculture: itemInfo.value.agriculture,
|
||||
letterhead: itemInfo.value.letterhead
|
||||
letterhead: itemInfo.value.letterhead,
|
||||
usedAdvanceInvoices: itemInfo.value.usedAdvanceInvoices
|
||||
}
|
||||
|
||||
if(route.params.id) {
|
||||
@@ -796,7 +849,7 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UDashboardPanelContent>
|
||||
<UTabs class="p-5" :items="tabItems" @change="onChangeTab">
|
||||
<UTabs class="p-5" :items="tabItems" @change="onChangeTab" v-if="loaded">
|
||||
<template #item="{item}">
|
||||
|
||||
|
||||
@@ -940,11 +993,9 @@ setupPage()
|
||||
<UFormGroup
|
||||
label="Kunde:"
|
||||
>
|
||||
<InputGroup
|
||||
class="w-full"
|
||||
>
|
||||
<div class="flex flex-row">
|
||||
<USelectMenu
|
||||
:options="dataStore.customers"
|
||||
:options="customers"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
:search-attributes="['name']"
|
||||
@@ -952,14 +1003,15 @@ setupPage()
|
||||
searchable-placeholder="Suche..."
|
||||
v-model="itemInfo.customer"
|
||||
@change="setCustomerData"
|
||||
class="flex-auto"
|
||||
class="flex-auto mr-2"
|
||||
>
|
||||
<UButton
|
||||
:color="itemInfo.customer ? 'primary' : 'rose'"
|
||||
variant="outline"
|
||||
class="w-full">
|
||||
<span class="truncate">{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kein Kunde ausgewählt"}}</span>
|
||||
|
||||
class="w-full"
|
||||
>
|
||||
<!-- <span class="truncate text-left">{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kein Kunde ausgewählt"}}</span>-->
|
||||
{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kein Kunde ausgewählt"}}
|
||||
|
||||
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform text-gray-400 dark:text-gray-500" :class="['transform rotate-90']" />
|
||||
</UButton>
|
||||
@@ -969,11 +1021,14 @@ setupPage()
|
||||
</USelectMenu>
|
||||
<UButton
|
||||
variant="outline"
|
||||
class="w-25"
|
||||
v-if="itemInfo.customer"
|
||||
icon="i-heroicons-arrow-right-end-on-rectangle"
|
||||
@click="router.push(`/customers/show/${itemInfo.customer}`)"
|
||||
>Kunde</UButton>
|
||||
</InputGroup>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<UAlert
|
||||
v-if="itemInfo.customer"
|
||||
@@ -997,7 +1052,7 @@ setupPage()
|
||||
>
|
||||
<InputGroup>
|
||||
<USelectMenu
|
||||
:options="dataStore.getContactsByCustomerId(itemInfo.customer)"
|
||||
:options="contacts.filter(i => i.customer === itemInfo.customer)"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
:search-attributes="['name']"
|
||||
@@ -1121,9 +1176,13 @@ setupPage()
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Zahlungziel in Tagen:"
|
||||
class="flex-auto"
|
||||
class="w-full"
|
||||
>
|
||||
<template #label>
|
||||
<span class="truncate">
|
||||
Zahlungsziel in Tagen:
|
||||
</span>
|
||||
</template>
|
||||
<UInput
|
||||
type="number"
|
||||
v-model="itemInfo.paymentDays"
|
||||
@@ -1169,6 +1228,7 @@ setupPage()
|
||||
:search-attributes="['name']"
|
||||
class="w-full"
|
||||
:disabled="!itemInfo.customer"
|
||||
@change="checkForOpenAdvanceInvoices"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getProjectById(itemInfo.project) ? dataStore.getProjectById(itemInfo.project).name : "Kein Projekt ausgewählt"}}
|
||||
@@ -1270,9 +1330,6 @@ setupPage()
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<UDivider
|
||||
class="my-3"
|
||||
/>
|
||||
@@ -1389,6 +1446,7 @@ setupPage()
|
||||
<UInput
|
||||
v-model="row.text"
|
||||
placeholder="Name"
|
||||
class="min-w-40"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
@@ -1558,7 +1616,8 @@ setupPage()
|
||||
<UInput
|
||||
v-model="row.price"
|
||||
type="number"
|
||||
step="0.01"
|
||||
step="0.001"
|
||||
:color="getRowMargin(row) > 0 ? 'primary' : 'rose'"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
@@ -1715,18 +1774,21 @@ setupPage()
|
||||
<UButton
|
||||
@click="addPosition('service')"
|
||||
class="mt-3"
|
||||
:disabled="itemInfo.type === 'advanceInvoices'"
|
||||
>
|
||||
+ Leistung
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="addPosition('normal')"
|
||||
class="mt-3"
|
||||
:disabled="itemInfo.type === 'advanceInvoices'"
|
||||
>
|
||||
+ Artikel
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="addPosition('free')"
|
||||
class="mt-3"
|
||||
:disabled="itemInfo.type === 'advanceInvoices'"
|
||||
>
|
||||
+ Freie Position
|
||||
</UButton>
|
||||
@@ -1750,6 +1812,44 @@ setupPage()
|
||||
</UButton>
|
||||
</InputGroup>
|
||||
|
||||
<UDivider
|
||||
class="mt-5 mb-3"
|
||||
v-if="openAdvanceInvoices.length > 0"
|
||||
>
|
||||
Noch nicht abgerechnete Abschlagsrechnungen
|
||||
</UDivider>
|
||||
|
||||
<!-- Abzurechnende Abschlagsrechnungen -->
|
||||
|
||||
<div
|
||||
v-for="advanceInvoice in openAdvanceInvoices"
|
||||
:key="advanceInvoice.id"
|
||||
class="flex flex-row justify-between my-2"
|
||||
>
|
||||
<span>{{advanceInvoice.documentNumber}}</span>
|
||||
<span>Summe: {{renderCurrency(advanceInvoice.rows[0].price * (1 + advanceInvoice.rows[0].taxPercent/100))}}</span>
|
||||
<InputGroup>
|
||||
<UButton
|
||||
@click="addAdvanceInvoiceToInvoice(advanceInvoice.id)"
|
||||
:disabled="itemInfo.usedAdvanceInvoices.includes(advanceInvoice.id)"
|
||||
class="mr-2"
|
||||
>
|
||||
Verwenden
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="itemInfo.usedAdvanceInvoices = itemInfo.usedAdvanceInvoices.filter(i => i !== advanceInvoice.id)"
|
||||
:disabled="!itemInfo.usedAdvanceInvoices.includes(advanceInvoice.id)"
|
||||
color="rose"
|
||||
variant="outline"
|
||||
>
|
||||
X
|
||||
</UButton>
|
||||
</InputGroup>
|
||||
</div>
|
||||
|
||||
<UDivider class="my-3" v-if="itemInfo.rows.length > 0"/>
|
||||
|
||||
|
||||
<div class="w-full flex justify-end" v-if="itemInfo.type !== 'deliveryNotes'">
|
||||
<table class="w-1/3" v-if="itemInfo.rows.length > 0">
|
||||
<tr>
|
||||
@@ -1764,6 +1864,19 @@ setupPage()
|
||||
<td class="font-bold">Brutto:</td>
|
||||
<td class="text-right">{{documentTotal.totalGross}}</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr v-if="documentTotal.totalGrossAlreadyPaid !== '0,00 €'">
|
||||
<td class="font-bold">Bereits bezahlt:</td>
|
||||
<td class="text-right">{{documentTotal.totalGrossAlreadyPaid}}</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr v-if="documentTotal.totalGrossAlreadyPaid !== '0,00 €'">
|
||||
<td class="font-bold">Offene Summe:</td>
|
||||
<td class="text-right">{{documentTotal.totalSumToPay}}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1815,6 +1928,7 @@ setupPage()
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
<UProgress animation="carousel" v-else/>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user