Zum Inhalt springen

Fremdwährung in Euro umrechnen

Bei der sachlichen Prüfung trägt die Buchhaltung die Währung und den Betrag in Fremdwährung ein. Danach holt das Skript über die Datenquelle wechselkurse den Referenzkurs zum Rechnungsdatum, etwa von einem Dienst mit den Kursen der Europäischen Zentralbank, und setzt den Wechselkurs und den Betrag in Euro. Die vier Felder deklariert der Workflow selbst. Eine Rechnung in Euro braucht keinen Kurs; gibt es für eine Währung keinen, bekommt die Freigabe einen Hinweis.

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: 1
schemaVersion: 4
sdk: '1.0.0'
key: exchange-rates
name: Fremdwährung umrechnen
template: custom
trigger:
documentType: incoming-invoice
fields:
- key: currency
kind: text
labelDe: Währung
labelEn: Currency
documentTypes:
- incoming-invoice
- key: foreignAmount
kind: number
labelDe: Betrag in Fremdwährung
labelEn: Amount in foreign currency
documentTypes:
- incoming-invoice
- key: exchangeRate
kind: number
labelDe: Wechselkurs
labelEn: Exchange rate
documentTypes:
- incoming-invoice
- key: amountEur
kind: money
labelDe: Betrag in Euro
labelEn: Amount in euros
documentTypes:
- incoming-invoice
start: review
steps:
- kind: humanTask
name: review
label: Sachliche Prüfung
taskKind: review
assignees:
- when: null
assignee:
kind: role
role: Buchhaltung
fallback:
kind: role
role: Buchhaltung
options:
excludeRequester: false
excludeActorsOfSteps: []
pickFile: false
next: convert
onRejected: rejected
- kind: script
name: convert
label: In Euro umrechnen
script: convert.ts
hook: onApproved
inputs:
- kind: field
key: currency
type: text
- kind: field
key: foreignAmount
type: number
- kind: field
key: invoiceDate
type: date
- kind: source
key: wechselkurse
returns: []
exits: []
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: end
name: approved
label: Freigegeben
outcome: approved
- kind: end
name: rejected
label: Zurückgewiesen
outcome: rejected

Hook: onApproved · Eingaben: currency, foreignAmount, invoiceDate, Datenquelle wechselkurse · Rückgaben: keine

import { date, defineScript, money, type PlainDate } from '@acriva/workflow-sdk';
/** What the rate service answers to `GET kurse?waehrung=…&datum=…`: the reference rate (1 EUR = `kurs` units) and its day. */
interface Rate {
kurs: number;
datum: PlainDate;
}
/** A source's answer is JSON of any shape until the script has checked it. */
const isRate = (data: unknown): data is Rate =>
typeof data === 'object' &&
data !== null &&
typeof (data as Rate).kurs === 'number' &&
(data as Rate).kurs > 0 &&
typeof (data as Rate).datum === 'string';
export default defineScript({
hook: 'onApproved',
async run(ctx) {
const { currency, foreignAmount, invoiceDate } = ctx.document.fields;
const code = currency?.trim().toUpperCase();
// A euro invoice, or one without an amount, needs no rate.
if (!code || code === 'EUR' || foreignAmount == null) return;
const result = await ctx.sources.get('wechselkurse', {
path: 'kurse',
query: { waehrung: code, datum: invoiceDate ?? ctx.today() },
});
if (!result.ok || !isRate(result.data)) {
const reason = result.ok ? '' : ` (${result.error})`;
ctx.hint(
`Für ${code} gibt es keinen Wechselkurs${reason}. Bitte rechnen Sie den Betrag von Hand in Euro um.`,
);
return;
}
const { kurs, datum } = result.data;
const amount = money.round(foreignAmount / kurs);
ctx.setField('exchangeRate', kurs);
ctx.setField('amountEur', amount);
ctx.hint(
`Umgerechnet zum Referenzkurs vom ${date.format(datum)} (1 EUR = ${String(kurs).replace('.', ',')} ${code}): ${money.format(amount)}.`,
);
},
});

Ein Test führt jeden dieser Fälle in der Sandbox aus und vergleicht das Ergebnis.

  • Eingabe: currency USD, foreignAmount 1250, invoiceDate 2026-10-20, Ergebnis der letzten Aufgabe Approved
  • Datenquelle wechselkurse: antwortet {"kurs":1.0842,"datum":"2026-10-20"}
  • Ausgang: der Standard-Nachfolger
  • Änderungen: Feld exchangeRate = 1.0842; Feld amountEur = 1152.92; Hinweis an der nächsten Aufgabe: „Umgerechnet zum Referenzkurs vom 20.10.2026 (1 EUR = 1,0842 USD): 1.152,92 €.“
  • Eingabe: currency EUR, foreignAmount null, invoiceDate 2026-10-20, Ergebnis der letzten Aufgabe Approved
  • Ausgang: der Standard-Nachfolger
  • Änderungen: keine
  • Eingabe: currency XAU, foreignAmount 2, invoiceDate 2026-10-20, Ergebnis der letzten Aufgabe Approved
  • Datenquelle wechselkurse: keine Daten: http-error (Status 404)
  • Ausgang: der Standard-Nachfolger
  • Änderungen: Hinweis an der nächsten Aufgabe: „Für XAU gibt es keinen Wechselkurs (http-error). Bitte rechnen Sie den Betrag von Hand in Euro um.“