Preis gegen die Preisliste prüfen
Für Verbrauchsmaterial haben Sie mit Ihren Lieferanten feste Preise vereinbart. Die Preisliste steht in einer Datentabelle preisliste mit der Artikelnummer als Schlüsselspalte, hochgeladen aus Excel oder CSV. Bei der sachlichen Prüfung trägt der Einkauf Artikelnummer und Einzelpreis der Rechnung ein, zwei Felder, die der Workflow selbst deklariert. Danach vergleicht das Skript den Einzelpreis mit dem Listenpreis: Liegt er höchstens 2 % darüber, geht die Rechnung zur normalen Freigabe; liegt er höher oder fehlt der Artikel in der Liste, gibt die Geschäftsführung frei, mit einem Hinweis auf die Abweichung.
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: price-list-checkname: Preis gegen die Preisliste prüfentemplate: customtrigger: documentType: incoming-invoicefields: - key: itemNumber kind: text labelDe: Artikelnummer labelEn: Item number documentTypes: - incoming-invoice - key: unitPrice kind: money labelDe: Einzelpreis labelEn: Unit price documentTypes: - incoming-invoicestart: reviewsteps: - kind: humanTask name: review label: Sachliche Prüfung taskKind: review assignees: - when: null assignee: kind: member member: einkauf@example.com fallback: kind: role role: Buchhaltung options: excludeRequester: false excludeActorsOfSteps: [] pickFile: false next: checkPrice onRejected: rejected - kind: script name: checkPrice label: Preis prüfen script: check-price.ts hook: onApproved inputs: - kind: field key: itemNumber type: text - kind: field key: unitPrice type: money - kind: table key: preisliste returns: - key: price type: enumeration values: - listPrice - deviation branch: price exits: - value: listPrice next: approve - value: deviation next: managementApproval 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: humanTask name: managementApproval label: Freigabe Geschäftsführung taskKind: approve assignees: - when: null assignee: kind: role role: Geschäftsführung 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 check-price.ts
Abschnitt betitelt „Das Skript check-price.ts“Hook: onApproved · Eingaben: itemNumber, unitPrice, Datentabelle preisliste · Rückgaben: price (listPrice, deviation)
import { defineScript, money } from '@acriva/workflow-sdk';
/** How far a unit price may lie above the list price, as a share of it. */const TOLERANCE = 0.02;
export default defineScript({ hook: 'onApproved', outputs: { price: ['listPrice', 'deviation'] }, async run(ctx) { const { itemNumber, unitPrice } = ctx.document.fields; const number = itemNumber?.trim(); if (!number || unitPrice == null) { ctx.hint('Artikelnummer oder Einzelpreis fehlt, der Preis ist nicht geprüft.'); return ctx.branch('deviation'); } const item = await ctx.tables.lookup('preisliste', number); if (item === null || item.preis === null) { ctx.hint(`Der Artikel ${number} steht nicht in der Preisliste.`); return ctx.branch('deviation'); } if (unitPrice > item.preis * (1 + TOLERANCE)) { ctx.hint( `${item.bezeichnung ?? number}: berechnet ${money.format(unitPrice)}, laut Preisliste ${money.format(item.preis)}.`, ); return ctx.branch('deviation'); } return ctx.branch('listPrice'); },});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 Preis über der Preisliste
Abschnitt betitelt „Ein Preis über der Preisliste“- Eingabe:
itemNumberTON-305A,unitPrice99.5, Ergebnis der letzten AufgabeApproved - Datentabelle
preisliste: 2 ZeilenartikelnummerPAP-A4-80,bezeichnungKopierpapier A4, 80 g, 500 Blatt,preis4.95artikelnummerTON-305A,bezeichnungToner 305A schwarz,preis89.9
- Ausgang:
deviation - Änderungen: Hinweis an der nächsten Aufgabe: „Toner 305A schwarz: berechnet 99,50 €, laut Preisliste 89,90 €.“
Ein Preis aus der Preisliste
Abschnitt betitelt „Ein Preis aus der Preisliste“- Eingabe:
itemNumberPAP-A4-80,unitPrice4.95, Ergebnis der letzten AufgabeApproved - Datentabelle
preisliste: 2 ZeilenartikelnummerPAP-A4-80,bezeichnungKopierpapier A4, 80 g, 500 Blatt,preis4.95artikelnummerTON-305A,bezeichnungToner 305A schwarz,preis89.9
- Ausgang:
listPrice - Änderungen: keine
Ein Artikel, der nicht in der Preisliste steht
Abschnitt betitelt „Ein Artikel, der nicht in der Preisliste steht“- Eingabe:
itemNumberTON-410X,unitPrice129, Ergebnis der letzten AufgabeApproved - Datentabelle
preisliste: 2 ZeilenartikelnummerPAP-A4-80,bezeichnungKopierpapier A4, 80 g, 500 Blatt,preis4.95artikelnummerTON-305A,bezeichnungToner 305A schwarz,preis89.9
- Ausgang:
deviation - Änderungen: Hinweis an der nächsten Aufgabe: „Der Artikel TON-410X steht nicht in der Preisliste.“