Skip to content

Escalate overdue approvals

When an invoice’s approval lies idle, Acriva reminds the cost center’s responsible person after 2 working days and hands the task to the management after 5; you set this on the approval itself, because no step runs while a task is open. After the approval, a timer waits until 3 days before the due date, and the script tells the management when the invoice is due or since when it is overdue.

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: escalate-overdue
name: Überfällige Freigaben eskalieren
template: custom
trigger:
documentType: incoming-invoice
fields: []
start: approve
steps:
- kind: humanTask
name: approve
label: Freigabe Kostenstelle
taskKind: approve
assignees:
- when: null
assignee:
kind: costCenterResponsible
fallback:
kind: role
role: Buchhaltung
options:
remindAfterWorkingDays: 2
escalateAfterWorkingDays: 5
escalationTarget:
kind: role
role: Geschäftsführung
excludeRequester: true
excludeActorsOfSteps: []
pickFile: false
next: untilDue
onRejected: rejected
- kind: timer
name: untilDue
label: Bis 3 Tage vor Fälligkeit
days: null
dateField: dueDate
daysBefore: 3
next: escalate
- kind: script
name: escalate
label: Fälligkeit melden
script: escalate.ts
hook: onTimer
inputs:
- kind: field
key: dueDate
type: date
- kind: field
key: invoiceNumber
type: text
- kind: field
key: vendorName
type: text
returns: []
exits: []
next: approved
- kind: end
name: approved
label: Freigegeben
outcome: approved
- kind: end
name: rejected
label: Zurückgewiesen
outcome: rejected

Hook: onTimer · Inputs: dueDate, invoiceNumber, vendorName · Return values: none

import { date, defineScript } from '@acriva/workflow-sdk';
export default defineScript({
hook: 'onTimer',
run(ctx) {
// The timer follows the approval's approving exit. The check keeps the script right if the workflow is redrawn.
if (ctx.instance.lastTaskOutcome !== 'Approved') return;
const { dueDate, invoiceNumber, vendorName } = ctx.document.fields;
// Without a due date the timer doesn't wait, and there is nothing to report.
if (dueDate == null) return;
const invoice = `Die Rechnung ${invoiceNumber ?? 'ohne Nummer'} von ${vendorName ?? 'unbekanntem Lieferanten'}`;
const daysLeft = date.daysBetween(ctx.today(), dueDate);
const days = (n: number) => (n === 1 ? '1 Tag' : `${n} Tagen`);
const when =
daysLeft < 0
? `ist seit ${days(-daysLeft)} überfällig (fällig am ${date.format(dueDate)})`
: daysLeft === 0
? 'ist heute fällig'
: `ist am ${date.format(dueDate)} fällig, in ${days(daysLeft)}`;
const text = `${invoice} ${when}. Bitte veranlassen Sie die Zahlung.`;
ctx.notify({ to: [{ role: 'Geschäftsführung' }], text });
},
});

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

  • Input: dueDate 2026-10-25, invoiceNumber RE-2026-0815, vendorName Bürobedarf Schmidt KG, last task outcome Approved, today 2026-10-22
  • Exit: the default next step
  • Changes: notification to the role Geschäftsführung: “Die Rechnung RE-2026-0815 von Bürobedarf Schmidt KG ist am 25.10.2026 fällig, in 3 Tagen. Bitte veranlassen Sie die Zahlung.”
  • Input: dueDate 2026-10-22, invoiceNumber RE-2026-0815, vendorName Bürobedarf Schmidt KG, last task outcome Approved, today 2026-10-22
  • Exit: the default next step
  • Changes: notification to the role Geschäftsführung: “Die Rechnung RE-2026-0815 von Bürobedarf Schmidt KG ist heute fällig. Bitte veranlassen Sie die Zahlung.”
  • Input: dueDate null, invoiceNumber RE-2026-0815, vendorName Bürobedarf Schmidt KG, last task outcome Approved, today 2026-10-22
  • Exit: the default next step
  • Changes: none
  • Input: dueDate 2026-10-21, invoiceNumber RE-2026-0815, vendorName Bürobedarf Schmidt KG, last task outcome Approved, today 2026-10-22
  • Exit: the default next step
  • Changes: notification to the role Geschäftsführung: “Die Rechnung RE-2026-0815 von Bürobedarf Schmidt KG ist seit 1 Tag überfällig (fällig am 21.10.2026). Bitte veranlassen Sie die Zahlung.”

Already overdue: the approval took too long

Section titled “Already overdue: the approval took too long”
  • Input: dueDate 2026-10-15, invoiceNumber RE-2026-0815, vendorName Bürobedarf Schmidt KG, last task outcome Approved, today 2026-10-22
  • Exit: the default next step
  • Changes: notification to the role Geschäftsführung: “Die Rechnung RE-2026-0815 von Bürobedarf Schmidt KG ist seit 7 Tagen überfällig (fällig am 15.10.2026). Bitte veranlassen Sie die Zahlung.”