lumnik. / scenarios All scenarios · Français

A delivery date each warehouse works out differently

Goal Promise the customer the date their warehouse can keep: one calculation rule, set per warehouse (country, lead time, closed days).

The promised date = order date plus N working days. But each warehouse counts its own way:

The operator writes the rule once; the integrator sets it per warehouse.

manifests/promised-date.kts
// Operator-provided: the delivery date promised to a customer — the order date plus `lead_days` working days.// A working day is Monday to Friday, not a public holiday of the warehouse's `country`, and not one of the// warehouse's own `closed` days. The integrator sets all three in the hook's context.@Suppress("UNCHECKED_CAST")val cells = bindings["cells"] as MutableMap<String, Any?>val context = bindings["context"] as Map<*, *>// The operator's 2026 calendar: fixed days and the Easter-dependent ones (Easter Monday, Ascension, Whit Monday).val holidays = mapOf(    "FR" to setOf("2026-01-01", "2026-04-06", "2026-05-01", "2026-05-08", "2026-05-14", "2026-05-25",                  "2026-07-14", "2026-08-15", "2026-11-01", "2026-11-11", "2026-12-25"),    "BE" to setOf("2026-01-01", "2026-04-06", "2026-05-01", "2026-05-14", "2026-05-25",                  "2026-07-21", "2026-08-15", "2026-11-01", "2026-11-11", "2026-12-25"))val off = holidays.getValue(context["country"] as String) + (context["closed"] as List<*>? ?: emptyList<Any>()).map { it.toString() }var day = java.time.LocalDate.parse(cells["order_date"] as String)var left = (context["lead_days"] as Number).toInt()while (left > 0) {    day = day.plusDays(1)    if (day.dayOfWeek.value <= 5 && day.toString() !in off) left--}cells["promised_date"] = day.toString()cells["warehouse"] = context["warehouse"] as String
orders.csv
order_no;customer;order_date
CMD-3101;Durand;2026-04-30
CMD-3102;Morel;2026-05-12
CMD-3103;Nguyen;2026-07-10
CMD-3104;Faure;2026-08-13
manifests/20-liege.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-promise-liege-b  connector_type: csv-file  scopes: [sales-b]spec:  transport:    kind: local    path: /tmp/lumnik-scenario/delivery-date-two-warehouses/b/orders.csv  parser:    delimiter: ";"  after_process: none  mapping:    cell:      - kotlin:          script: hooks:promised-date-b.kts   # one rule, the operator's          context:                            # this warehouse's part of it            warehouse: LIEGE            country: BE            lead_days: 5
manifests/30-promise.yaml
kind: Entityname: delivery_promise_blabel: Date de livraison promisedescription: "An order's delivery date as each warehouse promises it: one rule, each warehouse's lead time, holidays and closed days."match: [order_no, warehouse]scopes: [sales-b]columns:  order_no: { label: "Commande" }  customer: { label: "Client" }  order_date: { label: "Commandé le" }  warehouse: { label: "Entrepôt" }  promised_date: { label: "Livraison promise" }sources:  - table: t_scenario_promise_lyon_b    map: { order_no: order_no, customer: customer, order_date: order_date, warehouse: warehouse, promised_date: promised_date }  - table: t_scenario_promise_liege_b    map: { order_no: order_no, customer: customer, order_date: order_date, warehouse: warehouse, promised_date: promised_date }

Limits

  • The holiday calendar is the one the operator writes in the script: they keep it up to date each year.
  • The lead time counts working days, not hours: an evening order leaves like a morning one.
  • Synthetic orders.

Customer service · delivery

When will the customer get it?

It depends on the warehouse.

Lyon: 3 days and inventories. Liège: 5 days and other holidays.

Synthetic orders

The problem

One rule, two calendars.

  • 8 May is a holiday in France, not in Belgium.
  • Lyon closes for inventory.
  • Each warehouse has its lead time.

Nothing is changed

The orders stay as they are.

  • The operator writes the rule once.
  • The integrator sets it per warehouse.
  • Each order gets its date.

What it took to write

context:
  country: FR
  lead_days: 3
  closed: ["2026-05-05"]

Lyon's settings, in four lines.

The whole scenario fits in 4 files, 83 lines, including a 23-line script.

The answers

One order, two right dates.

  • CMD-3101: 7 May in Lyon, 8 May in Liège.
  • CMD-3102: 18 May in Lyon, 20 May in Liège.

The limit

The calendar needs upkeep.

  • Holidays live in the operator's script.
  • Days, not hours.

Try it

The scenario replays end to end.

One script, two connectors, one entity: each step is published with its output.

This scenario runs on lumnik Open, free and open source.

Try lumnik Open →