Route by cost center
An invoice’s cost center decides who approves: purchasing approves cost centers starting with 41, sales those starting with 43, accounting all others. The workflow declares the cost center field itself; when it is empty, accounting approves too.
The workflow
Section titled “The workflow”The workflow starts for every document of the type incoming-invoice. Its file workflow.yaml:
$schema: 'https://docs.acriva.de/schemas/workflow.schema.json'format: 1schemaVersion: 4sdk: '1.0.0'key: route-by-cost-centername: Nach Kostenstelle weiterleitentemplate: customtrigger: documentType: incoming-invoicefields: - key: costCenter kind: text labelDe: Kostenstelle labelEn: Cost center documentTypes: - incoming-invoicestart: routesteps: - kind: script name: route label: Nach Kostenstelle weiterleiten script: route.ts hook: onDocumentArrived inputs: - kind: field key: costCenter type: text returns: - key: group type: enumeration values: - purchasing - sales - accounting branch: group exits: - value: purchasing next: purchasing - value: sales next: sales - value: accounting next: accounting next: accounting - kind: humanTask name: purchasing label: Freigabe Einkauf taskKind: approve assignees: - when: null assignee: kind: member member: einkauf@example.com fallback: kind: role role: Buchhaltung options: excludeRequester: true excludeActorsOfSteps: [] pickFile: false next: approved onRejected: rejected - kind: humanTask name: sales label: Freigabe Vertrieb taskKind: approve assignees: - when: null assignee: kind: role role: approver fallback: kind: role role: Buchhaltung options: excludeRequester: true excludeActorsOfSteps: [] pickFile: false next: approved onRejected: rejected - kind: humanTask name: accounting label: Freigabe Buchhaltung taskKind: approve assignees: [] 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: rejectedThe script route.ts
Section titled “The script route.ts”Hook: onDocumentArrived · Inputs: costCenter · Return values: group (purchasing, sales, accounting)
import { defineScript } from '@acriva/workflow-sdk';
/** Which group approves: the cost centers whose number starts with the prefix. */const GROUPS = [ { prefix: '41', group: 'purchasing' }, { prefix: '43', group: 'sales' },] as const;
export default defineScript({ hook: 'onDocumentArrived', outputs: { group: ['purchasing', 'sales', 'accounting'] }, run(ctx) { const costCenter = ctx.document.fields.costCenter?.trim() ?? ''; const match = GROUPS.find((entry) => costCenter.startsWith(entry.prefix)); // Every other cost center, and an invoice without one, goes to accounting. if (!match) { ctx.log('No group for the cost center', costCenter || '(empty)'); return ctx.branch('accounting'); } return ctx.branch(match.group); },});What it does
Section titled “What it does”A test runs each of these cases in the sandbox and compares the result.
An invoice without a cost center
Section titled “An invoice without a cost center”- Input:
costCenternull - Exit:
accounting - Changes: none
Cost center 4200 (administration)
Section titled “Cost center 4200 (administration)”- Input:
costCenter4200 - Exit:
accounting - Changes: none
Cost center 4100 (purchasing)
Section titled “Cost center 4100 (purchasing)”- Input:
costCenter4100 - Exit:
purchasing - Changes: none
Cost center 4300 (sales)
Section titled “Cost center 4300 (sales)”- Input:
costCenter4300 - Exit:
sales - Changes: none