Skip to content

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 starts for every document of the type incoming-invoice. Its file workflow.yaml:

$schema: 'https://docs.acriva.de/schemas/workflow.schema.json'
format: 1
schemaVersion: 4
sdk: '1.0.0'
key: route-by-cost-center
name: Nach Kostenstelle weiterleiten
template: custom
trigger:
documentType: incoming-invoice
fields:
- key: costCenter
kind: text
labelDe: Kostenstelle
labelEn: Cost center
documentTypes:
- incoming-invoice
start: route
steps:
- 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: rejected

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);
},
});

A test runs each of these cases in the sandbox and compares the result.

  • Input: costCenter null
  • Exit: accounting
  • Changes: none
  • Input: costCenter 4200
  • Exit: accounting
  • Changes: none
  • Input: costCenter 4100
  • Exit: purchasing
  • Changes: none
  • Input: costCenter 4300
  • Exit: sales
  • Changes: none