fix(invoices): keep the stored ROT/RUT personnummer when editing a draft (#1186)

Fixes #1175. The stored personnummer exists only as AES-256-GCM
ciphertext (+ last4), so the editor cannot rehydrate it and sent an
empty string; buildInvoiceWriteData then failed ROT/RUT validation and
every edit of a draft deduction invoice was blocked with "Personnummer
krävs för ROT/RUT-avdrag" unless the user re-entered the customer's
personnummer.

buildInvoiceWriteData accepts the stored ciphertext from the update
path: an empty field on an invoice that still has deduction lines
means keep, a typed value replaces, and removing every deduction line
clears as before. The editor hint shows the kept last4 in edit mode
(new i18n key, sv+en).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-25 12:59:50 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 731a57dd6e
commit 5afd031306
6 changed files with 107 additions and 5 deletions
+5 -1
View File
@@ -2074,7 +2074,11 @@ export default function InvoiceEditor(props: InvoiceEditorProps = { mode: 'creat
{...register('deduction_personnummer')}
/>
<p className="text-xs text-muted-foreground">
{t('deduction_personnummer_hint')}
{/* Stored pn exists only as ciphertext: an empty field on
edit keeps it server-side instead of failing validation. */}
{initial?.deduction_personnummer_last4
? t('deduction_personnummer_kept_hint', { last4: initial.deduction_personnummer_last4 })
: t('deduction_personnummer_hint')}
</p>
</div>
{hasAnyRotLine && (