Use tenant business payment info for invoice QR codes

This commit is contained in:
2026-07-22 19:40:01 +02:00
parent 621243ba7b
commit fbea66b754
4 changed files with 88 additions and 8 deletions

View File

@@ -60,6 +60,15 @@ export const tenants = pgTable(
city: "", city: "",
name: "", name: "",
street: "", street: "",
email: "",
phone: "",
website: "",
taxNumber: "",
vatId: "",
bankName: "",
bankAccountOwner: "",
iban: "",
bic: "",
}), }),
features: jsonb("features").default({ features: jsonb("features").default({

View File

@@ -537,6 +537,9 @@ export function getDocumentDataBackend(
) { ) {
const businessInfo = tenant.businessInfo || {}; // Fallback falls leer const businessInfo = tenant.businessInfo || {}; // Fallback falls leer
const paymentQrBankAccount = bankAccounts.find((account: any) => !account.archived && !account.expired && account.iban) || null const paymentQrBankAccount = bankAccounts.find((account: any) => !account.archived && !account.expired && account.iban) || null
const paymentQrIban = businessInfo.iban || paymentQrBankAccount?.iban
const paymentQrBic = businessInfo.bic || paymentQrBankAccount?.bic
const paymentQrRecipient = businessInfo.bankAccountOwner || paymentQrBankAccount?.ownerName || businessInfo.name || tenant.name
// --- 1. Agriculture Logic --- // --- 1. Agriculture Logic ---
// Prüfen ob 'extraModules' existiert, sonst leeres Array annehmen // Prüfen ob 'extraModules' existiert, sonst leeres Array annehmen
@@ -731,9 +734,10 @@ export function getDocumentDataBackend(
agriculture: itemInfo.agriculture, agriculture: itemInfo.agriculture,
// Falls du AdvanceInvoices brauchst, musst du die Objekte hier übergeben oder leer lassen // Falls du AdvanceInvoices brauchst, musst du die Objekte hier übergeben oder leer lassen
usedAdvanceInvoices: [], usedAdvanceInvoices: [],
paymentQr: paymentQrBankAccount && itemInfo.payment_type === "transfer" ? { paymentQr: paymentQrIban && itemInfo.payment_type === "transfer" ? {
iban: paymentQrBankAccount.iban, iban: paymentQrIban,
recipientName: paymentQrBankAccount.ownerName || businessInfo.name || tenant.name, bic: paymentQrBic,
recipientName: paymentQrRecipient,
amount: totals.totalGross, amount: totals.totalGross,
remittance: itemInfo.documentNumber || itemInfo.title, remittance: itemInfo.documentNumber || itemInfo.title,
} : null } : null

View File

@@ -1411,8 +1411,11 @@ const getDocumentData = async () => {
let customerData = customers.value.find(i => i.id === itemInfo.value.customer) let customerData = customers.value.find(i => i.id === itemInfo.value.customer)
let contactData = contacts.value.find(i => i.id === itemInfo.value.contact) let contactData = contacts.value.find(i => i.id === itemInfo.value.contact)
let businessInfo = auth.activeTenantData.businessInfo let businessInfo = auth.activeTenantData.businessInfo || {}
const paymentQrBankAccount = bankaccounts.value.find(account => !account.archived && !account.expired && account.iban) const paymentQrBankAccount = bankaccounts.value.find(account => !account.archived && !account.expired && account.iban)
const paymentQrIban = businessInfo.iban || paymentQrBankAccount?.iban
const paymentQrBic = businessInfo.bic || paymentQrBankAccount?.bic
const paymentQrRecipient = businessInfo.bankAccountOwner || paymentQrBankAccount?.ownerName || businessInfo.name || auth.activeTenantData.name
if (auth.activeTenantData.extraModules.includes("agriculture")) { if (auth.activeTenantData.extraModules.includes("agriculture")) {
itemInfo.value.rows.forEach(row => { itemInfo.value.rows.forEach(row => {
@@ -1629,9 +1632,10 @@ const getDocumentData = async () => {
usedAdvanceInvoices: itemInfo.value.usedAdvanceInvoices.map(i => { usedAdvanceInvoices: itemInfo.value.usedAdvanceInvoices.map(i => {
return createddocuments.value.find(x => x.id === i) return createddocuments.value.find(x => x.id === i)
}), }),
paymentQr: paymentQrBankAccount && itemInfo.value.payment_type === "transfer" ? { paymentQr: paymentQrIban && itemInfo.value.payment_type === "transfer" ? {
iban: paymentQrBankAccount.iban, iban: paymentQrIban,
recipientName: paymentQrBankAccount.ownerName || businessInfo.name || auth.activeTenantData.name, bic: paymentQrBic,
recipientName: paymentQrRecipient,
amount: documentTotal.value.totalSumToPay, amount: documentTotal.value.totalSumToPay,
remittance: itemInfo.value.documentNumber || itemInfo.value.title, remittance: itemInfo.value.documentNumber || itemInfo.value.title,
} : null } : null

View File

@@ -214,17 +214,34 @@ const activeTelephonyTargetOptions = computed(() => {
if (telephonyExtensionForm.targetType === "branch") return telephonyExtensionOptions.value.branches || [] if (telephonyExtensionForm.targetType === "branch") return telephonyExtensionOptions.value.branches || []
return telephonyExtensionOptions.value.users || [] return telephonyExtensionOptions.value.users || []
}) })
const defaultBusinessInfo = {
name: "",
street: "",
zip: "",
city: "",
email: "",
phone: "",
website: "",
taxNumber: "",
vatId: "",
bankName: "",
bankAccountOwner: "",
iban: "",
bic: "",
}
const normalizeBusinessInfo = (value) => ({ ...defaultBusinessInfo, ...(value || {}) })
const setupPage = async () => { const setupPage = async () => {
itemInfo.value = auth.activeTenantData itemInfo.value = auth.activeTenantData
console.log(itemInfo.value) console.log(itemInfo.value)
businessInfo.value = normalizeBusinessInfo(auth.activeTenantData?.businessInfo)
planningBoardConfig.startTime = auth.activeTenantData?.calendarConfig?.planningBoard?.startTime || "06:00" planningBoardConfig.startTime = auth.activeTenantData?.calendarConfig?.planningBoard?.startTime || "06:00"
planningBoardConfig.endTime = auth.activeTenantData?.calendarConfig?.planningBoard?.endTime || "21:00" planningBoardConfig.endTime = auth.activeTenantData?.calendarConfig?.planningBoard?.endTime || "21:00"
planningBoardConfig.slotMinutes = auth.activeTenantData?.calendarConfig?.planningBoard?.slotMinutes || 180 planningBoardConfig.slotMinutes = auth.activeTenantData?.calendarConfig?.planningBoard?.slotMinutes || 180
} }
const features = ref({ ...defaultFeatures, ...(auth.activeTenantData?.features || {}) }) const features = ref({ ...defaultFeatures, ...(auth.activeTenantData?.features || {}) })
const businessInfo = ref(auth.activeTenantData.businessInfo) const businessInfo = ref(normalizeBusinessInfo(auth.activeTenantData?.businessInfo))
const accountChart = ref(auth.activeTenantData.accountChart || "skr03") const accountChart = ref(auth.activeTenantData.accountChart || "skr03")
const taxEvaluationPeriod = ref(normalizeTaxEvaluationPeriod(auth.activeTenantData.taxEvaluationPeriod)) const taxEvaluationPeriod = ref(normalizeTaxEvaluationPeriod(auth.activeTenantData.taxEvaluationPeriod))
const accountChartOptions = [ const accountChartOptions = [
@@ -245,6 +262,7 @@ const updateTenant = async (newData) => {
itemInfo.value = res itemInfo.value = res
auth.activeTenantData = res auth.activeTenantData = res
features.value = { ...defaultFeatures, ...(res?.features || {}) } features.value = { ...defaultFeatures, ...(res?.features || {}) }
businessInfo.value = normalizeBusinessInfo(res?.businessInfo)
taxEvaluationPeriod.value = normalizeTaxEvaluationPeriod(res?.taxEvaluationPeriod) taxEvaluationPeriod.value = normalizeTaxEvaluationPeriod(res?.taxEvaluationPeriod)
} }
} }
@@ -628,6 +646,51 @@ onMounted(() => {
<UInput v-model="businessInfo.city" class="flex-auto"/> <UInput v-model="businessInfo.city" class="flex-auto"/>
</InputGroup> </InputGroup>
</UFormField> </UFormField>
<UFormField
label="E-Mail:"
>
<UInput v-model="businessInfo.email"/>
</UFormField>
<UFormField
label="Telefon:"
>
<UInput v-model="businessInfo.phone"/>
</UFormField>
<UFormField
label="Website:"
>
<UInput v-model="businessInfo.website"/>
</UFormField>
<UFormField
label="Steuernummer:"
>
<UInput v-model="businessInfo.taxNumber"/>
</UFormField>
<UFormField
label="USt-IdNr.:"
>
<UInput v-model="businessInfo.vatId"/>
</UFormField>
<UFormField
label="Bank:"
>
<UInput v-model="businessInfo.bankName"/>
</UFormField>
<UFormField
label="Kontoinhaber:"
>
<UInput v-model="businessInfo.bankAccountOwner"/>
</UFormField>
<UFormField
label="IBAN:"
>
<UInput v-model="businessInfo.iban"/>
</UFormField>
<UFormField
label="BIC:"
>
<UInput v-model="businessInfo.bic"/>
</UFormField>
<UButton <UButton
class="mt-3" class="mt-3"
@click="updateTenant({businessInfo: businessInfo})" @click="updateTenant({businessInfo: businessInfo})"