SEPA-Mandate in Verträge und Ausgangsrechnungen einbauen #183
This commit is contained in:
@@ -224,6 +224,33 @@ const availableSepaMandates = computed(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getSelectedSepaMandate = () => {
|
||||||
|
return availableSepaMandates.value.find((mandate) => mandate.id === itemInfo.value.outgoingsepamandate) || null
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapContractPaymentType = (paymentType) => {
|
||||||
|
if (paymentType === "Einzug") return "direct-debit"
|
||||||
|
if (paymentType === "Überweisung") return "transfer"
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyContractPaymentData = () => {
|
||||||
|
const selectedContract = contracts.value.find((contract) => contract.id === itemInfo.value.contract)
|
||||||
|
if (!selectedContract) return
|
||||||
|
|
||||||
|
const mappedPaymentType = mapContractPaymentType(selectedContract.paymentType)
|
||||||
|
if (mappedPaymentType) {
|
||||||
|
itemInfo.value.payment_type = mappedPaymentType
|
||||||
|
}
|
||||||
|
|
||||||
|
const contractMandateId = selectedContract.outgoingsepamandate?.id || selectedContract.outgoingsepamandate
|
||||||
|
if (mappedPaymentType === "direct-debit" && contractMandateId) {
|
||||||
|
itemInfo.value.outgoingsepamandate = contractMandateId
|
||||||
|
} else if (mappedPaymentType === "transfer") {
|
||||||
|
itemInfo.value.outgoingsepamandate = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const applyDefaultSepaMandate = () => {
|
const applyDefaultSepaMandate = () => {
|
||||||
if (itemInfo.value.payment_type !== "direct-debit") {
|
if (itemInfo.value.payment_type !== "direct-debit") {
|
||||||
itemInfo.value.outgoingsepamandate = null
|
itemInfo.value.outgoingsepamandate = null
|
||||||
@@ -246,6 +273,11 @@ const applyDefaultSepaMandate = () => {
|
|||||||
itemInfo.value.outgoingsepamandate = defaultMandate?.id || null
|
itemInfo.value.outgoingsepamandate = defaultMandate?.id || null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => itemInfo.value.contract,
|
||||||
|
() => applyContractPaymentData()
|
||||||
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [itemInfo.value.customer, itemInfo.value.contract, itemInfo.value.payment_type, outgoingsepamandates.value.length],
|
() => [itemInfo.value.customer, itemInfo.value.contract, itemInfo.value.payment_type, outgoingsepamandates.value.length],
|
||||||
() => applyDefaultSepaMandate()
|
() => applyDefaultSepaMandate()
|
||||||
@@ -2268,6 +2300,24 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|||||||
class="w-full"
|
class="w-full"
|
||||||
/>
|
/>
|
||||||
</UFormField>
|
</UFormField>
|
||||||
|
<UFormField
|
||||||
|
class="min-w-0 flex-1"
|
||||||
|
label="Individueller Aufschlag:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
type="number"
|
||||||
|
step="0.01"
|
||||||
|
v-model="itemInfo.customSurchargePercentage"
|
||||||
|
@change="updateCustomSurcharge"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
<template #trailing>
|
||||||
|
<span class="text-gray-500 dark:text-gray-400 text-xs">%</span>
|
||||||
|
</template>
|
||||||
|
</UInput>
|
||||||
|
</UFormField>
|
||||||
|
</InputGroup>
|
||||||
|
<InputGroup class="w-full items-start flex-wrap md:flex-nowrap">
|
||||||
<UFormField
|
<UFormField
|
||||||
class="min-w-0 flex-1"
|
class="min-w-0 flex-1"
|
||||||
label="Zahlungsart:"
|
label="Zahlungsart:"
|
||||||
@@ -2289,39 +2339,38 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|||||||
class="min-w-0 flex-1"
|
class="min-w-0 flex-1"
|
||||||
label="SEPA-Mandat:"
|
label="SEPA-Mandat:"
|
||||||
>
|
>
|
||||||
<USelectMenu
|
<InputGroup>
|
||||||
v-model="itemInfo.outgoingsepamandate"
|
<USelectMenu
|
||||||
value-key="id"
|
v-model="itemInfo.outgoingsepamandate"
|
||||||
label-key="reference"
|
value-key="id"
|
||||||
:items="availableSepaMandates"
|
label-key="reference"
|
||||||
:search-input="{ placeholder: 'Suche...' }"
|
:items="availableSepaMandates"
|
||||||
:filter-fields="['reference', 'status']"
|
:search-input="{ placeholder: 'Suche...' }"
|
||||||
class="w-full"
|
:filter-fields="['reference', 'status']"
|
||||||
:disabled="!itemInfo.customer"
|
class="w-full"
|
||||||
>
|
:disabled="!itemInfo.customer"
|
||||||
<template #default>
|
>
|
||||||
{{ itemInfo.outgoingsepamandate ? availableSepaMandates.find(i => i.id === itemInfo.outgoingsepamandate)?.reference : "Kein Mandat ausgewählt" }}
|
<template #default>
|
||||||
</template>
|
{{ getSelectedSepaMandate()?.reference || "Kein Mandat ausgewählt" }}
|
||||||
<template #item="{ item: mandate }">
|
</template>
|
||||||
{{ mandate.reference }} - {{ mandate.bankaccount?.displayLabel || "Bankverbindung" }}
|
<template #item="{ item: mandate }">
|
||||||
</template>
|
{{ mandate.reference }} - {{ mandate.bankaccount?.displayLabel || "Bankverbindung" }}
|
||||||
</USelectMenu>
|
</template>
|
||||||
</UFormField>
|
</USelectMenu>
|
||||||
<UFormField
|
<UButton
|
||||||
class="min-w-0 flex-1"
|
variant="outline"
|
||||||
label="Individueller Aufschlag:"
|
color="error"
|
||||||
>
|
v-if="itemInfo.outgoingsepamandate"
|
||||||
<UInput
|
icon="i-heroicons-x-mark"
|
||||||
type="number"
|
@click="itemInfo.outgoingsepamandate = null"
|
||||||
step="0.01"
|
/>
|
||||||
v-model="itemInfo.customSurchargePercentage"
|
<EntityModalButtons
|
||||||
@change="updateCustomSurcharge"
|
type="outgoingsepamandates"
|
||||||
class="w-full"
|
:id="itemInfo.outgoingsepamandate"
|
||||||
>
|
:create-query="{customer: itemInfo.customer}"
|
||||||
<template #trailing>
|
@return-data="(data) => itemInfo.outgoingsepamandate = data.id"
|
||||||
<span class="text-gray-500 dark:text-gray-400 text-xs">%</span>
|
/>
|
||||||
</template>
|
</InputGroup>
|
||||||
</UInput>
|
|
||||||
</UFormField>
|
</UFormField>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<UFormField
|
<UFormField
|
||||||
@@ -2438,7 +2487,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|||||||
>
|
>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<USelectMenu
|
<USelectMenu
|
||||||
:items="contracts.filter(i => i.customer?.id === itemInfo.customer && (itemInfo.plant ? itemInfo.plant === i.plant : true))"
|
:items="contracts.filter(i => (i.customer?.id || i.customer) === itemInfo.customer && (itemInfo.plant ? itemInfo.plant === i.plant : true))"
|
||||||
v-model="itemInfo.contract"
|
v-model="itemInfo.contract"
|
||||||
value-key="id"
|
value-key="id"
|
||||||
label-key="name"
|
label-key="name"
|
||||||
@@ -2463,7 +2512,7 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
|||||||
@click="itemInfo.contract = null"
|
@click="itemInfo.contract = null"
|
||||||
/>
|
/>
|
||||||
<EntityModalButtons
|
<EntityModalButtons
|
||||||
type="projects"
|
type="contracts"
|
||||||
:id="itemInfo.contract"
|
:id="itemInfo.contract"
|
||||||
:create-query="{customer: itemInfo.customer}"
|
:create-query="{customer: itemInfo.customer}"
|
||||||
@return-data="(data) => itemInfo.contract = data.id"
|
@return-data="(data) => itemInfo.contract = data.id"
|
||||||
|
|||||||
@@ -957,10 +957,14 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
inputType: "select",
|
inputType: "select",
|
||||||
selectDataType: "outgoingsepamandates",
|
selectDataType: "outgoingsepamandates",
|
||||||
selectOptionAttribute: "reference",
|
selectOptionAttribute: "reference",
|
||||||
selectSearchAttributes: ["reference"],
|
selectSearchAttributes: ["reference", "status"],
|
||||||
selectDataTypeFilter: function (i, item) {
|
selectDataTypeFilter: function (i, item) {
|
||||||
const mandateCustomer = i.customer?.id || i.customer
|
const mandateCustomer = i.customer?.id || i.customer
|
||||||
return !item.customer || mandateCustomer === item.customer
|
return !i.archived && i.status === "Aktiv" && (!item.customer || mandateCustomer === item.customer)
|
||||||
|
},
|
||||||
|
entityModalButtonsType: "outgoingsepamandates",
|
||||||
|
entityModalCreateQueryFunction: function (item) {
|
||||||
|
return {customer: item.customer}
|
||||||
},
|
},
|
||||||
showFunction: function (item) {
|
showFunction: function (item) {
|
||||||
return item.paymentType === "Einzug"
|
return item.paymentType === "Einzug"
|
||||||
|
|||||||
Reference in New Issue
Block a user