Buchungsfelder vorbereiten
Der Workflow legt die Felder Buchungstext und Sachkonto an und füllt sie, sobald eine Rechnung eingeht: den Buchungstext aus Lieferant und Rechnungsnummer mit höchstens 60 Zeichen, wie DATEV ihn annimmt, und das Sachkonto aus einer Tabelle im Skript. Ein zu langer Lieferantenname wird an einer Wortgrenze gekürzt, damit die Rechnungsnummer vollständig bleibt. Die Felder stehen am Dokument für die Buchhaltung bereit; der DATEV-Export bildet seinen Buchungstext selbst aus Lieferant und Rechnungsnummer und liest diese Felder nicht.
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: datev-fieldsname: Buchungsfelder vorbereitentemplate: customtrigger: documentType: incoming-invoicefields: - key: bookingText kind: text labelDe: Buchungstext labelEn: Booking text documentTypes: - incoming-invoice - key: glAccount kind: text labelDe: Sachkonto labelEn: G/L account documentTypes: - incoming-invoicestart: preparesteps: - kind: script name: prepare label: DATEV-Felder vorbereiten script: prepare.ts hook: onDocumentArrived inputs: - kind: field key: vendorName type: text - kind: field key: invoiceNumber type: text returns: [] exits: [] 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 prepare.ts
Abschnitt betitelt „Das Skript prepare.ts“Hook: onDocumentArrived · Eingaben: vendorName, invoiceNumber · Rückgaben: keine
import { defineScript } from '@acriva/workflow-sdk';
/** DATEV takes at most 60 characters as the booking text. */const MAX_BOOKING_TEXT = 60;
/** The G/L account (SKR03) per vendor; a vendor matches when its name starts with the entry's name. */const GL_ACCOUNTS: readonly { vendor: string; glAccount: string }[] = [ { vendor: 'Telekom', glAccount: '4920' }, { vendor: 'Deutsche Bahn', glAccount: '4663' }, { vendor: 'Bürobedarf', glAccount: '4930' },];
/** * The vendor and the invoice number in at most 60 characters. A vendor that is too long is cut at a word boundary, so the * invoice number always stays complete. */function bookingText(vendor: string, invoiceNumber: string | null): string { const suffix = invoiceNumber == null ? '' : ` ${invoiceNumber}`; const full = `${vendor}${suffix}`; if (full.length <= MAX_BOOKING_TEXT) return full; const room = MAX_BOOKING_TEXT - suffix.length; if (room <= 0) return suffix.trim().slice(0, MAX_BOOKING_TEXT); // Keep one character more, so a word that ends exactly at the limit stays whole. const head = vendor.slice(0, room + 1); const space = head.lastIndexOf(' '); const shortVendor = (space > 0 ? head.slice(0, space) : vendor.slice(0, room)).trimEnd(); return `${shortVendor}${suffix}`;}
export default defineScript({ hook: 'onDocumentArrived', run(ctx) { const { vendorName, invoiceNumber } = ctx.document.fields; if (vendorName == null) return; ctx.setField('bookingText', bookingText(vendorName.trim(), invoiceNumber?.trim() || null));
const match = GL_ACCOUNTS.find((entry) => vendorName.toLowerCase().startsWith(entry.vendor.toLowerCase()), ); if (match) { ctx.setField('glAccount', match.glAccount); } else { ctx.hint( 'Für diesen Lieferanten ist kein Sachkonto hinterlegt. Bitte ergänzen Sie es von Hand.', ); } },});Was es tut
Abschnitt betitelt „Was es tut“Ein Test führt jeden dieser Fälle in der Sandbox aus und vergleicht das Ergebnis.
Ein bekannter Lieferant
Abschnitt betitelt „Ein bekannter Lieferant“- Eingabe:
vendorNameTelekom Deutschland GmbH,invoiceNumber4711-2026-10 - Ausgang: der Standard-Nachfolger
- Änderungen: Feld
bookingText=Telekom Deutschland GmbH 4711-2026-10; FeldglAccount=4920
Ein langer Lieferantenname
Abschnitt betitelt „Ein langer Lieferantenname“- Eingabe:
vendorNameGebäudereinigung Sauber & Glanz Facility Services Deutschland GmbH,invoiceNumberRE-2026-0815 - Ausgang: der Standard-Nachfolger
- Änderungen: Feld
bookingText=Gebäudereinigung Sauber & Glanz Facility RE-2026-0815; Hinweis an der nächsten Aufgabe: „Für diesen Lieferanten ist kein Sachkonto hinterlegt. Bitte ergänzen Sie es von Hand.“
Eine Rechnung ohne Lieferanten
Abschnitt betitelt „Eine Rechnung ohne Lieferanten“- Eingabe:
vendorNamenull,invoiceNumberRE-2026-0815 - Ausgang: der Standard-Nachfolger
- Änderungen: keine