Discount reminder
One day after an incoming invoice is approved, the script checks whether its early-payment discount still applies. While the period runs, it reminds accounting of the last day to pay and the amount saved, and tags the invoice “Skonto”. The discount period and rate are fields the workflow adds itself. With a card it needs no script: Watch the Skonto deadline reads the Skonto terms and gives the approval the Skonto date as its deadline.
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: skonto-remindername: Skonto-Erinnerungtemplate: customtrigger: documentType: incoming-invoicefields: - key: discountDays kind: number labelDe: Skontofrist (Tage) labelEn: Discount period (days) documentTypes: - incoming-invoice - key: discountPercent kind: number labelDe: Skonto (%) labelEn: Discount (%) documentTypes: - incoming-invoicestart: approvesteps: - 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: wait onRejected: rejected - kind: timer name: wait label: Einen Tag warten days: 1 daysBefore: 0 next: remind - kind: script name: remind label: An Skonto erinnern script: remind.ts hook: onTimer inputs: - kind: field key: invoiceNumber type: text - kind: field key: invoiceDate type: date - kind: field key: totalGross type: money - kind: field key: discountDays type: number - kind: field key: discountPercent type: number returns: [] exits: [] next: approved - kind: end name: approved label: Freigegeben outcome: approved - kind: end name: rejected label: Zurückgewiesen outcome: rejectedThe script remind.ts
Section titled “The script remind.ts”Hook: onTimer · Inputs: invoiceNumber, invoiceDate, totalGross, discountDays, discountPercent · Return values: none
import { date, defineScript, money } from '@acriva/workflow-sdk';
export default defineScript({ hook: 'onTimer', run(ctx) { const { invoiceNumber, invoiceDate, totalGross, discountDays, discountPercent } = ctx.document.fields; // Without the invoice date, the discount period or the discount there is nothing to remind of. if (invoiceDate == null || discountDays == null || discountPercent == null) return;
// The discount applies up to and including the last day of its period, counted in whole days. const deadline = date.addDays(invoiceDate, Math.trunc(discountDays)); if (ctx.today() > deadline) { ctx.log('Discount expired on', date.format(deadline)); return; }
const percent = String(discountPercent).replace('.', ','); const saving = totalGross == null ? '' : ` Das sind ${money.format(money.round((totalGross * discountPercent) / 100))}.`; ctx.notify({ to: [{ role: 'Buchhaltung' }], text: `Die Rechnung ${invoiceNumber ?? 'ohne Nummer'} ist freigegeben. ` + `Bei Zahlung bis ${date.format(deadline)} ziehen Sie ${percent} % Skonto ab.${saving}`, }); ctx.addTag('Skonto'); },});What it does
Section titled “What it does”A test runs each of these cases in the sandbox and compares the result.
The discount still applies
Section titled “The discount still applies”- Input:
invoiceNumberRE-2026-0815,invoiceDate2026-10-15,totalGross1190,discountDays14,discountPercent2, last task outcomeApproved, today2026-10-22 - Exit: the default next step
- Changes: notification to the role
Buchhaltung: “Die Rechnung RE-2026-0815 ist freigegeben. Bei Zahlung bis 29.10.2026 ziehen Sie 2 % Skonto ab. Das sind 23,80 €.”; tag “Skonto”
The discount period has ended
Section titled “The discount period has ended”- Input:
invoiceNumberRE-2026-0702,invoiceDate2026-10-01,totalGross499.8,discountDays10,discountPercent3, last task outcomeApproved, today2026-10-22 - Exit: the default next step
- Changes: none
An invoice without a discount
Section titled “An invoice without a discount”- Input:
invoiceNumberRE-2026-0911,invoiceDate2026-10-20,totalGross250,discountDaysnull,discountPercentnull, last task outcomeApproved - Exit: the default next step
- Changes: none