Tutorial P2P - Causal chain
TL;DR
Goal: Build a causal P2P process structure from the tables created earlier. In doing so, we configure the approval path and a genuine 1:N relationship between order and order line item.
Prerequisites:bestellanforderung,freigabe_a,freigabe_b,bestellungandbestellpositionhave been created.
Result: The Smart Data Forge no longer knows only the table relationships, but also the business sequence, approval logic, time gaps and cardinalities of the process.
In the previous step we defined which objects exist and how they are relationally connected to one another.
That is not yet sufficient for synthetic process mining data. A foreign key states, for example, that a bestellposition belongs to a bestellung. But it does not yet say:
- when the order line item comes into being,
- how many line items an order has,
- which approvals are required beforehand,
- or which process paths a case can traverse.
These rules are defined under 03 Causal Chain.
There, the Smart Data Forge works with slots. A slot represents the position of an object within the causal flow. In addition to the sequence, time gaps and cardinalities can be stored between the slots.
1. Setting bestellanforderung as the starting point
Open 03 Causal Chain and add the first slot via + Add slot.
Choose:
bestellanforderung
The purchase requisition is the entry point of our P2P case.
For the transition after the purchase requisition, we use the same basic time parameters as in the full demo set:
| Setting | Value |
|---|---|
| Gap min | 1 |
| Gap max | 4 |
| Unit | days |
| Outgoing min | 1 |
| Outgoing max | 1 |
| Distribution | skew low |
This means each case starts with exactly one purchase requisition. The subsequent approval process typically begins one to four days later.
The existing P2P model likewise uses a gap of 1–4 days for the purchase requisition.
2. Modeling the approval path
Our process does not have just a single approval step.
In the full example there are two approval objects:
freigabe_a
freigabe_b
In the regular approval path these are executed after the purchase requisition and merged back together again before the order.
For this we need the advanced settings under Branch / Join.
The interface uses Parent slot, Branch tag, XOR-Split as well as Join settings to represent such structures.
Adding freigabe_a
Create a new slot and choose: freigabe_a
Within the slot, open Branch / Join.
Set:
Parent slot: bestellanforderung
Branch tag: DUAL
Enable: XOR-Split
What does this mean in business terms?
In our demo model, the XOR decision distinguishes two fundamental cases:
DUAL: The regular approval path is traversed.
DIRECT: The order can proceed without this approval path.
The full demo model uses a weighting for this:
DUAL: 78
DIRECT: 22
The Smart Data Forge supports weighted XOR decisions. Without weighting, selection would be random with a uniform distribution; the weights let you specify a particular ratio.
Therefore configure the following in the XOR area:
| Branch | Weight |
|---|---|
DUAL | 78 |
DIRECT | 22 |
In this model the DIRECT path has no approval slot of its own. If DIRECT is chosen, the slots of the DUAL approval path are not created, and the process can then continue directly with the order.
This structure later becomes the basis for distinguishing between regular direct procurement and a maverick-buying / bypass scenario. We only configure the actual undesired bypass later, in the article on Special Behaviour.
3. Adding freigabe_b
Add another slot with freigabe_b.
Likewise open Branch / Join and set:
Parent slot: bestellanforderung
Branch tag: DUAL
This makes freigabe_a and freigabe_b part of the same regular approval path.
In the existing P2P model, both approvals have the purchase requisition as their starting point and use the same branch DUAL.
For the time gaps we use the existing values:
freigabe_a Gap: 2–12 hours
freigabe_b Gap: 4–24 hours
4. Merging the approvals before the order
Now the bestellung is created as the next slot.
Add a slot and choose: bestellung
Open Branch / Join.
In the regular DUAL case, the order should only come into being once the required approvals have been completed.
Therefore choose freigabe_a and freigabe_b as join sources and use an: AND Join
In the regular case the join waits for all required branches to have contributed. A true AND join is only continued by the engine when all needed branches are present.
For the Join gap, set:
Min: 0
Max: 30
Unit: minutes
This way the order comes into being immediately, or at the latest roughly 30 minutes after the required approvals are completed.
What happens on the DIRECT path?
If DIRECT was chosen in the earlier XOR decision, the two approval slots deliberately do not belong to this case.
The Smart Data Forge does not treat this case as a faulty, incomplete AND join. When all the relevant branches are intentionally omitted due to the XOR decision, the join is bridged for this case and the process chain can continue with the order.
This allows regular approval processes and business-intended direct orders to coexist within the same data set.
5. Configuring the 1:N relationship to the order line item
Now we model one of the most important structures in our example.
A bestellung can have multiple bestellposition records.
After bestellung, add a slot for: bestellposition.
The cardinality is set on the outgoing transition of the parent slot bestellung.
Configure the following on bestellung:
| Setting | Value |
|---|---|
| Gap min | 0 |
| Gap max | 30 |
| Unit | minutes |
| Outgoing min | 1 |
| Outgoing max | 3 |
| Distribution | skew low |
What does skew low mean?
The cardinality 1–3 initially means:
An order produces at least one and at most three order line items.
With skew low, however, these three possibilities are not equally likely.
The distribution is heavily shifted toward the lower end. As a result, orders with one line item occur more frequently and orders with the maximum number occur more rarely. The engine explicitly implements skew_low as a distribution that strongly favors low values.
This is more realistic than a simple uniform distribution.
Also important: with a 1:N fan-out, the Smart Data Forge produces genuinely separate child rows. Each order line item thus has its own position_id.
Do not confuse cardinality distribution and time distribution
Two different concepts exist within the slot.
Distribution affects the cardinality – that is, for example, whether one, two or three order line items tend to come into being.
The time distribution, by contrast, controls how the time gap between two process steps is drawn within the defined min/max range.
These two distributions serve different purposes. The current engine explicitly separates the cardinality distribution from the process-time distribution.
This becomes relevant later, especially with long cycle times and bottlenecks.
6. Setting the run settings for the tutorial
Below the Causal Chain is Run settings.
For our training, set:
| Setting | Value |
|---|---|
| Number of cases | 500 |
| Start date | 2025-01-01 |
| Span (days) | 90 |
| Seed | 42 |
The cases are distributed across the specified period. Each case then traverses the process structure with the respectively configured time gaps.
The seed ensures that we get reproducible random decisions on repeated runs.
Our process state so far
After this article we have, in simplified form, the following structure:
bestellanforderung
→ Decision DUAL or DIRECT
DUAL:
freigabe_a
+ freigabe_b
→ AND Join
DIRECT:
Approval path omitted
→ bestellung
→ bestellposition 1:N, 1–3, skew low
This means our model already contains three important process mining concepts:
Branching: Not every case has to traverse the same path.
Synchronization: On the regular DUAL path, the required approvals must be completed.
Fan-out: A single order can give rise to multiple independent order line items.
Still no process errors
Important: the variants generated so far are initially part of the regular process model.
A DIRECT path is not automatically maverick buying.
Only later do we deliberately configure cases in which, due to certain business characteristics, a case undesirably bypasses an approval path that was actually intended for it.
This happens under Special Behaviour with the Team Bypass.
This distinction is important:
A process variant means that a particular path is fundamentally part of the model.
A process deviation means that a case deliberately departs from the behavior expected of it.
Common mistakes / things to watch out for
The cardinality is set on the parent.
The 1–3 order line items are configured on the outgoing transition of bestellung – not on bestellposition itself.
skew low here concerns the number of child rows.
It is not automatically a setting for the time distribution.
An AND join is a genuine synchronization.
If a required branch really is missing, the join cannot simply continue with the remaining branch. The engine treats an incomplete true AND join as an abort of the chain.
DIRECT is not yet maverick buying.
The regular process structure and a deliberately generated compliance violation should be considered separately in business terms.
Next step: switching to the full base model
Up to this point we have deliberately built the most important modeling principles ourselves.
For the following business use cases, however, we need the full P2P data set with suppliers, materials, goods receipts, invoices, invoice approvals, payments and further attributes.
In the next step, we therefore load:
p2p-01-basis-config.json
The base config replaces our previous exercise state and contains the full Simple P2P model, but still without Special Behaviours and without Conditional Rules.
From this defined starting point, we then build the business anomalies ourselves, step by step.
[SCREENSHOT: Load config with p2p-01-basis-config.json selected]
Next: Tutorial P2P Loading and understanding the full base model