Fix/invoice delivery and payment accounts (#1116)
* fix: reconcile annual reports with final closing entries * test: cover annual report depreciation and VAT balances * Merge remote-tracking branch 'origin/main' into fix/usr-fdbck-ch * fix: show exact invoice delivery details * fix: use currency account in invoice emails * fix: address invoice delivery review feedback * fix: harden invoice delivery and payment accounts * test: assert RLS-denied zero-row updates * fix: close remaining invoice compliance gaps * fix: harden invoice archive authorization * fix: close invoice delivery review findings * fix: verify delivery finalization results * fix: cap combined invoice email recipients * fix: close final invoice compliance findings * fix: prevent stale payment account saves * test: prove invoice delivery isolation * fix: close invoice privacy review findings * test: normalize delivery retention dates
This commit is contained in:
@@ -431,6 +431,43 @@ describe('invoice email templates', () => {
|
||||
expect(text).toMatch(/1[\s ]234,56 EUR/)
|
||||
})
|
||||
|
||||
it('uses the matching EUR payment account in both email variants', () => {
|
||||
const eurInvoice = makeInvoice({ invoice_number: '1042', currency: 'EUR', total: 1234.56 })
|
||||
const multiCurrencyCompany = makeCompanySettings({
|
||||
bank_name: 'Legacy SEK Bank',
|
||||
clearing_number: '5037',
|
||||
account_number: '1231231',
|
||||
iban: 'SE0011111111111111111111',
|
||||
bic: 'NDEASESS',
|
||||
invoice_payment_accounts: {
|
||||
EUR: {
|
||||
bank_name: 'Mock ASPSP',
|
||||
clearing_number: null,
|
||||
account_number: null,
|
||||
bankgiro: null,
|
||||
plusgiro: null,
|
||||
swish: null,
|
||||
iban: 'SE4550000000058398257466',
|
||||
bic: 'ESSESESS',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const data = { invoice: eurInvoice, customer: svCustomer, company: multiCurrencyCompany }
|
||||
const html = generateInvoiceEmailHtml(data)
|
||||
const text = generateInvoiceEmailText(data)
|
||||
|
||||
for (const rendered of [html, text]) {
|
||||
expect(rendered).toContain('Mock ASPSP')
|
||||
expect(rendered).toContain('SE4550000000058398257466')
|
||||
expect(rendered).toContain('ESSESESS')
|
||||
expect(rendered).not.toContain('Legacy SEK Bank')
|
||||
expect(rendered).not.toContain('5037-1231231')
|
||||
expect(rendered).not.toContain('SE0011111111111111111111')
|
||||
expect(rendered).not.toContain('NDEASESS')
|
||||
}
|
||||
})
|
||||
|
||||
it('subtracts the ROT/RUT deduction so the email states what the customer owes', () => {
|
||||
const rotInvoice = makeInvoice({ invoice_number: '1042', total: 1234.56, deduction_total: 500 })
|
||||
const html = generateInvoiceEmailHtml({ invoice: rotInvoice, customer: svCustomer, company })
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Invoice, Customer, CompanySettings, InvoiceDocumentType } from '@/types'
|
||||
import { formatDate, getCompanyDisplayName, getCompanyPrimaryName } from '@/lib/utils'
|
||||
import { getAmountToPay } from '@/lib/invoices/rounding'
|
||||
import { companyWithInvoicePaymentAccount } from '@/lib/invoices/payment-accounts'
|
||||
import { applyPlaceholders, escapeHtml, sanitizeSubjectLine, userTextToHtml } from './user-text'
|
||||
|
||||
type EmailLang = 'sv' | 'en'
|
||||
@@ -197,7 +198,8 @@ function safeBrandingColor(value: string | null | undefined, fallback: string):
|
||||
* Generate HTML email for sending an invoice
|
||||
*/
|
||||
export function generateInvoiceEmailHtml(data: InvoiceEmailData): string {
|
||||
const { invoice, customer, company } = data
|
||||
const { invoice, customer } = data
|
||||
const company = companyWithInvoicePaymentAccount(data.company, invoice.currency)
|
||||
|
||||
const lang = resolveLang(customer)
|
||||
const L = LABELS[lang]
|
||||
@@ -353,7 +355,8 @@ export function generateInvoiceEmailHtml(data: InvoiceEmailData): string {
|
||||
* Generate plain text email for sending an invoice
|
||||
*/
|
||||
export function generateInvoiceEmailText(data: InvoiceEmailData): string {
|
||||
const { invoice, customer, company } = data
|
||||
const { invoice, customer } = data
|
||||
const company = companyWithInvoicePaymentAccount(data.company, invoice.currency)
|
||||
|
||||
const lang = resolveLang(customer)
|
||||
const L = LABELS[lang]
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
export interface SendEmailOptions {
|
||||
to: string | string[]
|
||||
cc?: string | string[]
|
||||
bcc?: string | string[]
|
||||
subject: string
|
||||
html: string
|
||||
text?: string
|
||||
|
||||
Reference in New Issue
Block a user