Inventory replenishment BPMN example
Inventory replenishment is the process that fires when stock of an item falls to its reorder point: work out how much to buy, apply the ordering policy, get approval if the spend demands it, and place the order. Teams map it because it is usually half automated and half manual, and the seam between the two is where orders stall. The typical gap is an approval step that exists in someone's head but not in any documented flow.
Because most of the work is system driven, this model uses a single pool with no lanes, a deliberate choice for automated flows where lane assignment would add noise. Two exclusive gateways structure it: one decides whether human approval is needed at all, the other records the approval outcome. A business rule task applies the ordering policy, and a message catch event holds the process until the supplier confirms.
Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.
The process at a glance
How to read this diagram
The trigger here is a stock level crossing its reorder point, captured by the "Reorder point reached" start event. A service task calculates the reorder quantity, and a business rule task applies the order policy rules: batch sizes, supplier selection, price thresholds. The gateway "Approval required?" then splits the flow. Small orders take the default No branch straight to purchase order creation, while orders above the threshold go to a buyer for review.
Approved requisitions rejoin the main path at the "Create purchase order" task, but if the buyer declines, the default branch of "Requisition approved?" ends the process at "Replenishment cancelled". Once the purchase order exists, a send task transmits it to the supplier and the process waits at a message catch event for the order confirmation. Updating the stock records closes the flow at the "Order confirmed" end event.
BPMN elements used
| Element | Count | In this diagram |
|---|---|---|
| Start event | 1 | Reorder point reached |
| End event | 2 | Replenishment cancelled, Order confirmed |
| Intermediate catch event | 1 | Confirmation received |
| User task | 1 | Review purchase requisition |
| Service task | 3 | Calculate reorder quantity, Create purchase order, Update stock records |
| Send task | 1 | Send order to supplier |
| Business rule task | 1 | Apply order policy rules |
| Exclusive gateway | 2 | Approval required?, Requisition approved? |
View the BPMN 2.0 XML for this diagram
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="swimdraft" exporterVersion="1.0">
<bpmn2:collaboration id="Collaboration_1">
<bpmn2:participant id="pool_ir" name="Inventory replenishment" processRef="Process_pool_ir" />
</bpmn2:collaboration>
<bpmn2:process id="Process_pool_ir" isExecutable="false">
<bpmn2:startEvent id="start_ir" name="Reorder point reached">
<bpmn2:outgoing>fir1</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:serviceTask id="t_ir_calc" name="Calculate reorder quantity">
<bpmn2:incoming>fir1</bpmn2:incoming>
<bpmn2:outgoing>fir2</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:businessRuleTask id="t_ir_policy" name="Apply order policy rules">
<bpmn2:incoming>fir2</bpmn2:incoming>
<bpmn2:outgoing>fir3</bpmn2:outgoing>
</bpmn2:businessRuleTask>
<bpmn2:exclusiveGateway id="g_ir_appr" name="Approval required?" default="fir5">
<bpmn2:incoming>fir3</bpmn2:incoming>
<bpmn2:outgoing>fir4</bpmn2:outgoing>
<bpmn2:outgoing>fir5</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:userTask id="t_ir_review" name="Review purchase requisition">
<bpmn2:incoming>fir4</bpmn2:incoming>
<bpmn2:outgoing>fir6</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:exclusiveGateway id="g_ir_ok" name="Requisition approved?" default="fir8">
<bpmn2:incoming>fir6</bpmn2:incoming>
<bpmn2:outgoing>fir7</bpmn2:outgoing>
<bpmn2:outgoing>fir8</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:endEvent id="end_ir_cancel" name="Replenishment cancelled">
<bpmn2:incoming>fir8</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:serviceTask id="t_ir_po" name="Create purchase order">
<bpmn2:incoming>fir5</bpmn2:incoming>
<bpmn2:incoming>fir7</bpmn2:incoming>
<bpmn2:outgoing>fir9</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sendTask id="t_ir_send" name="Send order to supplier">
<bpmn2:incoming>fir9</bpmn2:incoming>
<bpmn2:outgoing>fir10</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:intermediateCatchEvent id="ev_ir_conf" name="Confirmation received">
<bpmn2:incoming>fir10</bpmn2:incoming>
<bpmn2:outgoing>fir11</bpmn2:outgoing>
<bpmn2:messageEventDefinition id="ev_ir_conf_def" />
</bpmn2:intermediateCatchEvent>
<bpmn2:serviceTask id="t_ir_update" name="Update stock records">
<bpmn2:incoming>fir11</bpmn2:incoming>
<bpmn2:outgoing>fir12</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:endEvent id="end_ir_done" name="Order confirmed">
<bpmn2:incoming>fir12</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="fir1" sourceRef="start_ir" targetRef="t_ir_calc" />
<bpmn2:sequenceFlow id="fir2" sourceRef="t_ir_calc" targetRef="t_ir_policy" />
<bpmn2:sequenceFlow id="fir3" sourceRef="t_ir_policy" targetRef="g_ir_appr" />
<bpmn2:sequenceFlow id="fir4" name="Over threshold" sourceRef="g_ir_appr" targetRef="t_ir_review">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Over threshold</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fir5" name="No" sourceRef="g_ir_appr" targetRef="t_ir_po" />
<bpmn2:sequenceFlow id="fir6" sourceRef="t_ir_review" targetRef="g_ir_ok" />
<bpmn2:sequenceFlow id="fir7" name="Yes" sourceRef="g_ir_ok" targetRef="t_ir_po">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fir8" name="No" sourceRef="g_ir_ok" targetRef="end_ir_cancel" />
<bpmn2:sequenceFlow id="fir9" sourceRef="t_ir_po" targetRef="t_ir_send" />
<bpmn2:sequenceFlow id="fir10" sourceRef="t_ir_send" targetRef="ev_ir_conf" />
<bpmn2:sequenceFlow id="fir11" sourceRef="ev_ir_conf" targetRef="t_ir_update" />
<bpmn2:sequenceFlow id="fir12" sourceRef="t_ir_update" targetRef="end_ir_done" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
<bpmndi:BPMNShape id="pool_ir_di" bpmnElement="pool_ir" isHorizontal="true">
<dc:Bounds x="20" y="20" width="1720" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="start_ir_di" bpmnElement="start_ir">
<dc:Bounds x="112" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="74" y="101" width="112" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_ir_calc_di" bpmnElement="t_ir_calc">
<dc:Bounds x="230" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_ir_policy_di" bpmnElement="t_ir_policy">
<dc:Bounds x="380" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_ir_appr_di" bpmnElement="g_ir_appr">
<dc:Bounds x="555" y="52" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="533" y="32" width="95" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_ir_review_di" bpmnElement="t_ir_review">
<dc:Bounds x="680" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_ir_ok_di" bpmnElement="g_ir_ok">
<dc:Bounds x="855" y="52" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="824" y="32" width="112" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_ir_cancel_di" bpmnElement="end_ir_cancel">
<dc:Bounds x="1012" y="169" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="968" y="211" width="125" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_ir_po_di" bpmnElement="t_ir_po">
<dc:Bounds x="980" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_ir_send_di" bpmnElement="t_ir_send">
<dc:Bounds x="1130" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ev_ir_conf_di" bpmnElement="ev_ir_conf">
<dc:Bounds x="1312" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1276" y="101" width="109" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_ir_update_di" bpmnElement="t_ir_update">
<dc:Bounds x="1430" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_ir_done_di" bpmnElement="end_ir_done">
<dc:Bounds x="1612" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1589" y="101" width="82" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="fir1_di" bpmnElement="fir1">
<di:waypoint x="148" y="77" />
<di:waypoint x="230" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir2_di" bpmnElement="fir2">
<di:waypoint x="330" y="77" />
<di:waypoint x="380" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir3_di" bpmnElement="fir3">
<di:waypoint x="480" y="77" />
<di:waypoint x="555" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir4_di" bpmnElement="fir4">
<di:waypoint x="605" y="77" />
<di:waypoint x="680" y="77" />
<bpmndi:BPMNLabel><dc:Bounds x="611" y="83" width="48" height="28" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir5_di" bpmnElement="fir5">
<di:waypoint x="605" y="77" />
<di:waypoint x="660" y="77" />
<di:waypoint x="660" y="132" />
<di:waypoint x="960" y="132" />
<di:waypoint x="960" y="77" />
<di:waypoint x="980" y="77" />
<bpmndi:BPMNLabel><dc:Bounds x="611" y="57" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir6_di" bpmnElement="fir6">
<di:waypoint x="780" y="77" />
<di:waypoint x="855" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir7_di" bpmnElement="fir7">
<di:waypoint x="905" y="77" />
<di:waypoint x="980" y="77" />
<bpmndi:BPMNLabel><dc:Bounds x="911" y="57" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir8_di" bpmnElement="fir8">
<di:waypoint x="905" y="77" />
<di:waypoint x="960" y="77" />
<di:waypoint x="960" y="187" />
<di:waypoint x="1012" y="187" />
<bpmndi:BPMNLabel><dc:Bounds x="911" y="83" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir9_di" bpmnElement="fir9">
<di:waypoint x="1080" y="77" />
<di:waypoint x="1130" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir10_di" bpmnElement="fir10">
<di:waypoint x="1230" y="77" />
<di:waypoint x="1312" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir11_di" bpmnElement="fir11">
<di:waypoint x="1348" y="77" />
<di:waypoint x="1430" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fir12_di" bpmnElement="fir12">
<di:waypoint x="1530" y="77" />
<di:waypoint x="1612" y="77" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>Frequently asked questions
Why does this model have no lanes at all?
Lanes answer the question of who does each step, which matters most when several human teams hand work to each other. Here nearly every step is a system action, and the one human step is clearly a user task. An empty lane set keeps the diagram flat and readable; add lanes only once role boundaries carry real information.
What does the business rule task for the order policy represent?
A business rule task delegates a decision to a rules engine or decision table: minimum order quantities, preferred suppliers, price breaks. Separating that logic from the flow means the policy can change without redrawing the process. If your rules live in a spreadsheet today, the task marks exactly where they would plug in.
How would I add a second approval tier for large orders?
Extend the "Approval required?" gateway into a chain: the first branch tests the routine threshold, and a further exclusive gateway on that path tests the higher limit and routes to a senior approver task. Give every non default branch a value label such as "Over 50k" so each token's route is unambiguous at a glance.
Related BPMN examples
Order fulfilment
An order fulfilment process as a BPMN 2.0 diagram: stock check, backorder loop, picking, and dispatch confirmation. View the swimlanes and download the .bpmn file free.
Goods receipt
A goods receipt process as a BPMN 2.0 diagram: PO matching, condition inspection, discrepancy handling, and GRN posting. See the swimlanes and download the free .bpmn file.
Shipping and dispatch
A shipping and dispatch process as a BPMN 2.0 diagram: parallel packing and paperwork, customs branch, and departure. View the swimlanes and download the .bpmn free.
Quality inspection
A quality inspection process as a BPMN 2.0 diagram: sampling, testing, tolerance decision, and a rework loop back through inspection. Download the .bpmn file free.
Generate your own version of this diagram
Describe how the process works in your organisation: plain English, meeting notes, a transcript, or a spreadsheet. Swimdraft turns it into a spec-validated BPMN 2.0 diagram you can edit in the browser and export as .bpmn, SVG, or PNG.
Start freeNo credit card required