IBAN und USt-IdNr. prüfen
Das Skript rechnet die Prüfziffer der IBAN einer Eingangsrechnung nach und prüft, ob die USt-IdNr. die richtige Form hat. Ob die USt-IdNr. tatsächlich vergeben ist, prüft es nicht. Bei einem Fehler geht die Rechnung mit einem Hinweis zur Korrektur an die Person, die sie hochgeladen hat, sonst direkt zur Freigabe. Ohne Skript geht es mit einer Karte: Pflichtangaben prüfen prüft unter anderem die Prüfziffer der IBAN und die Form der USt-IdNr.
Der Workflow
Abschnitt betitelt „Der Workflow“Der Workflow startet für jedes Dokument vom Typ incoming-invoice. Seine Datei workflow.yaml:
$schema: 'https://docs.acriva.de/schemas/workflow.schema.json'format: 1schemaVersion: 4sdk: '1.0.0'key: iban-vat-id-checkname: IBAN und USt-IdNr. prüfentemplate: customtrigger: documentType: incoming-invoicefields: - key: iban kind: text labelDe: IBAN labelEn: IBAN documentTypes: - incoming-invoice - key: vatId kind: text labelDe: USt-IdNr. labelEn: VAT ID documentTypes: - incoming-invoicestart: checksteps: - kind: script name: check label: IBAN und USt-IdNr. prüfen script: check.ts hook: onDocumentArrived inputs: - kind: field key: iban type: text - kind: field key: vatId type: text returns: - key: result type: enumeration values: - valid - invalid branch: result exits: - value: valid next: approve - value: invalid next: fix next: approve - kind: humanTask name: fix label: Bankdaten korrigieren taskKind: fix assignees: - when: null assignee: kind: role role: Buchhaltung fallback: kind: role role: Buchhaltung options: excludeRequester: false excludeActorsOfSteps: [] pickFile: false next: approve - kind: humanTask name: approve label: Freigabe taskKind: approve assignees: - when: null assignee: kind: costCenterResponsible fallback: kind: role role: Buchhaltung options: excludeRequester: true excludeActorsOfSteps: [] pickFile: false next: approved onRejected: rejected - kind: end name: approved label: Freigegeben outcome: approved - kind: end name: rejected label: Zurückgewiesen outcome: rejectedDas Skript check.ts
Abschnitt betitelt „Das Skript check.ts“Hook: onDocumentArrived · Eingaben: iban, vatId · Rückgaben: result (valid, invalid)
import { defineScript } from '@acriva/workflow-sdk';
/** Removes spaces and writes letters in capitals, as IBANs and VAT IDs are compared. */const compact = (value: string) => value.replace(/\s+/g, '').toUpperCase();
/** Whether a text has the form of an IBAN: a country code, two check digits and 11 to 30 letters or digits; 22 characters in Germany. */function ibanFormFits(iban: string): boolean { if (!/^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/.test(iban)) return false; return !iban.startsWith('DE') || iban.length === 22;}
/** * Whether an IBAN's two check digits fit (ISO 13616, mod 97): the first four characters move to the end, every letter * becomes a number (A = 10 … Z = 35), and the whole number leaves the remainder 1 when divided by 97. */function ibanCheckDigitsFit(iban: string): boolean { const rearranged = iban.slice(4) + iban.slice(0, 4); let remainder = 0; // A character at a time, so the number never grows too large; an IBAN has at most 34 characters. for (const char of rearranged) { const value = parseInt(char, 36); remainder = (remainder * (value > 9 ? 100 : 10) + value) % 97; } return remainder === 1;}
/** * Whether a VAT ID has the form of one: a German one is DE and 9 digits, any other a country code and 2 to 12 * characters. It checks the form only, not whether the number is assigned: that only the Federal Central Tax Office * (BZSt) can confirm. */function vatIdFormFits(vatId: string): boolean { if (vatId.startsWith('DE')) return /^DE\d{9}$/.test(vatId); return /^[A-Z]{2}[A-Z0-9]{2,12}$/.test(vatId);}
export default defineScript({ hook: 'onDocumentArrived', outputs: { result: ['valid', 'invalid'] }, run(ctx) { const { iban, vatId } = ctx.document.fields; const problems: string[] = []; // An empty field has nothing to check: not every invoice names an IBAN or a VAT ID. if (iban != null && !ibanFormFits(compact(iban))) { problems.push(`Die IBAN ${iban} hat nicht die Form einer IBAN (in Deutschland 22 Zeichen).`); } else if (iban != null && !ibanCheckDigitsFit(compact(iban))) { problems.push(`Die IBAN ${iban} hat keine gültige Prüfziffer.`); } if (vatId != null && !vatIdFormFits(compact(vatId))) { problems.push( `Die USt-IdNr. ${vatId} hat nicht die Form einer USt-IdNr. (in Deutschland DE und 9 Ziffern).`, ); } if (problems.length === 0) return ctx.branch('valid'); ctx.hint(`${problems.join(' ')} Bitte korrigieren Sie die Angabe anhand der Rechnung.`); return ctx.branch('invalid'); },});Was es tut
Abschnitt betitelt „Was es tut“Ein Test führt jeden dieser Fälle in der Sandbox aus und vergleicht das Ergebnis.
IBAN und USt-IdNr. sind gültig
Abschnitt betitelt „IBAN und USt-IdNr. sind gültig“- Eingabe:
ibanDE89 3704 0044 0532 0130 00,vatIdDE123456789 - Ausgang:
valid - Änderungen: keine
Eine IBAN mit falscher Prüfziffer
Abschnitt betitelt „Eine IBAN mit falscher Prüfziffer“- Eingabe:
ibanDE89 3704 0044 0532 0130 01,vatIdDE123456789 - Ausgang:
invalid - Änderungen: Hinweis an der nächsten Aufgabe: „Die IBAN DE89 3704 0044 0532 0130 01 hat keine gültige Prüfziffer. Bitte korrigieren Sie die Angabe anhand der Rechnung.“
Eine USt-IdNr. mit einer Ziffer zu wenig
Abschnitt betitelt „Eine USt-IdNr. mit einer Ziffer zu wenig“- Eingabe:
ibannull,vatIdDE12345678 - Ausgang:
invalid - Änderungen: Hinweis an der nächsten Aufgabe: „Die USt-IdNr. DE12345678 hat nicht die Form einer USt-IdNr. (in Deutschland DE und 9 Ziffern). Bitte korrigieren Sie die Angabe anhand der Rechnung.“