fix: use corrected invoice total for bank allocation
All checks were successful
Build and Push Docker Images / build-frontend (push) Successful in 37s
Build and Push Docker Images / build-central-services-api (push) Successful in 35s
Build and Push Docker Images / build-central-services-admin (push) Successful in 35s
Build and Push Docker Images / build-backend (push) Successful in 58s
Build and Push Docker Images / build-website (push) Successful in 34s
Build and Push Docker Images / build-docs (push) Successful in 36s

This commit is contained in:
2026-08-09 17:14:53 +02:00
parent 7ad55aaa0b
commit 7d3e9a383f

View File

@@ -41,6 +41,60 @@ export default async function bankingRoutes(server: FastifyInstance) {
const ManualInvoices = aliasedTable(incominginvoices, "manual_invoices")
const ManualInvoiceVendors = aliasedTable(vendors, "manual_invoice_vendors")
const useCurrentIncomingInvoiceAmount = async (tenantId: number, allocation: any) => {
const invoiceId = Number(allocation.incominginvoice)
const statementId = Number(allocation.bankstatement)
if (!invoiceId || !statementId) return allocation
const [[invoice], [statement], invoiceAllocations, statementAllocations] = await Promise.all([
server.db.select().from(incominginvoices).where(and(
eq(incominginvoices.id, invoiceId),
eq(incominginvoices.tenant, tenantId)
)).limit(1),
server.db.select().from(bankstatements).where(and(
eq(bankstatements.id, statementId),
eq(bankstatements.tenant, tenantId)
)).limit(1),
server.db.select({ amount: statementallocations.amount }).from(statementallocations).where(and(
eq(statementallocations.incominginvoice, invoiceId),
eq(statementallocations.tenant, tenantId),
eq(statementallocations.archived, false)
)),
server.db.select({ amount: statementallocations.amount }).from(statementallocations).where(and(
eq(statementallocations.bankstatement, statementId),
eq(statementallocations.tenant, tenantId),
eq(statementallocations.archived, false)
)),
])
if (!invoice || !statement) return allocation
const accountTotals = (invoice.accounts as any[] || []).reduce((totals, account) => ({
net: totals.net + Number(account.amountNet || 0),
tax: totals.tax + Number(account.amountTax || 0),
}), { net: 0, tax: 0 })
const correctedTax = invoice.taxAmountOverride !== null && invoice.taxAmountOverride !== undefined && invoice.taxAmountOverride !== ""
? Number(invoice.taxAmountOverride)
: accountTotals.tax
const legacyRemaining = Math.max(0, Math.abs(accountTotals.net + accountTotals.tax)
- invoiceAllocations.reduce((sum, item) => sum + Math.abs(Number(item.amount || 0)), 0))
const correctedRemaining = Math.max(0, Math.abs(accountTotals.net + correctedTax)
- invoiceAllocations.reduce((sum, item) => sum + Math.abs(Number(item.amount || 0)), 0))
const statementRemaining = Math.max(0, Math.abs(Number(statement.amount || 0))
- statementAllocations.reduce((sum, item) => sum + Math.abs(Number(item.amount || 0)), 0))
const requestedAmount = Number(allocation.amount || 0)
const legacyAssignment = Math.min(legacyRemaining, statementRemaining)
// Nur den automatisch vorgeschlagenen Altbetrag ersetzen. Bewusst eingegebene Teilbeträge bleiben erhalten.
if (Math.abs(Math.abs(requestedAmount) - legacyAssignment) >= 0.005) return allocation
const currentAssignment = Math.min(correctedRemaining, statementRemaining)
return {
...allocation,
amount: Number((Math.sign(requestedAmount || (invoice.expense ? -1 : 1)) * currentAssignment).toFixed(2)),
}
}
const normalizeManualSide = (payload: any, keys: string[]) =>
keys.filter((key) => payload[key] !== null && payload[key] !== undefined && payload[key] !== "")
@@ -1108,6 +1162,7 @@ export default async function bankingRoutes(server: FastifyInstance) {
const { data: payload } = req.body as { data: any }
const prepared = prepareStatementAllocationPayload(payload)
if (prepared.error) return reply.code(400).send({ error: prepared.error })
prepared.data = await useCurrentIncomingInvoiceAmount(req.user.tenant_id, prepared.data)
const inserted = await server.db.insert(statementallocations).values({
...prepared.data,