SwimdraftPricingSign inStart free

Leave request BPMN example

Leave requests are small, frequent, and irritating when they go wrong: an employee books flights before approval, a manager approves leave the balance does not cover, or two people in a two person team end up off in the same week. Teams map the process to fix the ordering, because most of the pain comes from checks happening after decisions instead of before them.

The model is a single pool with Employee, Line manager, and HR lanes. Two exclusive gateways structure the flow: a balance check that runs before the manager ever sees the request, and the approval decision itself. The choice worth noticing is the business rule task for the balance check, signalling that this step is a lookup against policy, not a judgement call, and is a strong candidate for automation.

Leave request: BPMN 2.0 diagram
Leave request process modelled as a BPMN 2.0 diagram

Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.

The process at a glance

Starts when
Leave dates chosen
Ends with
Request declined · Leave booked
Lanes
Employee · Line manager · HR
Decisions
Balance sufficient? · Request approved?

How to read this diagram

An employee opens the flow by choosing dates, marked by the "Leave dates chosen" start event, and submitting the request. HR checks the leave balance with a business rule task, feeding the gateway "Balance sufficient?". Its No branch, the default, routes to "Notify employee of refusal" and the "Request declined" end event, so requests that cannot possibly be granted never reach the manager.

Requests that survive the balance check land with the Line manager, who reviews cover and workload before the "Request approved?" gateway. A No answer joins the same refusal notification, keeping decline communication in one place. On Yes, HR records the leave in the system and confirms the booking to the employee, ending at "Leave booked". Every request therefore ends in exactly one of two clearly named states.

BPMN elements used

ElementCountIn this diagram
Start event1Leave dates chosen
End event2Request declined, Leave booked
User task2Submit leave request, Review leave request
Service task1Record leave in system
Send task2Notify employee of refusal, Confirm booking
Business rule task1Check leave balance
Exclusive gateway2Balance sufficient?, Request 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_lv" name="Leave request" processRef="Process_pool_lv" />
  </bpmn2:collaboration>
  <bpmn2:process id="Process_pool_lv" isExecutable="false">
    <bpmn2:laneSet id="LaneSet_pool_lv">
      <bpmn2:lane id="lane_lv_emp" name="Employee">
        <bpmn2:flowNodeRef>start_lv</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_lv_submit</bpmn2:flowNodeRef>
      </bpmn2:lane>
      <bpmn2:lane id="lane_lv_mgr" name="Line manager">
        <bpmn2:flowNodeRef>t_lv_review</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>g_lv_appr</bpmn2:flowNodeRef>
      </bpmn2:lane>
      <bpmn2:lane id="lane_lv_hr" name="HR">
        <bpmn2:flowNodeRef>t_lv_balance</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>g_lv_balance</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_lv_decline</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>end_lv_declined</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_lv_record</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_lv_confirm</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>end_lv_booked</bpmn2:flowNodeRef>
      </bpmn2:lane>
    </bpmn2:laneSet>
    <bpmn2:startEvent id="start_lv" name="Leave dates chosen">
      <bpmn2:outgoing>flv1</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:userTask id="t_lv_submit" name="Submit leave request">
      <bpmn2:incoming>flv1</bpmn2:incoming>
      <bpmn2:outgoing>flv2</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:businessRuleTask id="t_lv_balance" name="Check leave balance">
      <bpmn2:incoming>flv2</bpmn2:incoming>
      <bpmn2:outgoing>flv3</bpmn2:outgoing>
    </bpmn2:businessRuleTask>
    <bpmn2:exclusiveGateway id="g_lv_balance" name="Balance sufficient?" default="flv5">
      <bpmn2:incoming>flv3</bpmn2:incoming>
      <bpmn2:outgoing>flv4</bpmn2:outgoing>
      <bpmn2:outgoing>flv5</bpmn2:outgoing>
    </bpmn2:exclusiveGateway>
    <bpmn2:sendTask id="t_lv_decline" name="Notify employee of refusal">
      <bpmn2:incoming>flv5</bpmn2:incoming>
      <bpmn2:incoming>flv9</bpmn2:incoming>
      <bpmn2:outgoing>flv6</bpmn2:outgoing>
    </bpmn2:sendTask>
    <bpmn2:endEvent id="end_lv_declined" name="Request declined">
      <bpmn2:incoming>flv6</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:userTask id="t_lv_review" name="Review leave request">
      <bpmn2:incoming>flv4</bpmn2:incoming>
      <bpmn2:outgoing>flv7</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:exclusiveGateway id="g_lv_appr" name="Request approved?" default="flv9">
      <bpmn2:incoming>flv7</bpmn2:incoming>
      <bpmn2:outgoing>flv8</bpmn2:outgoing>
      <bpmn2:outgoing>flv9</bpmn2:outgoing>
    </bpmn2:exclusiveGateway>
    <bpmn2:serviceTask id="t_lv_record" name="Record leave in system">
      <bpmn2:incoming>flv8</bpmn2:incoming>
      <bpmn2:outgoing>flv10</bpmn2:outgoing>
    </bpmn2:serviceTask>
    <bpmn2:sendTask id="t_lv_confirm" name="Confirm booking">
      <bpmn2:incoming>flv10</bpmn2:incoming>
      <bpmn2:outgoing>flv11</bpmn2:outgoing>
    </bpmn2:sendTask>
    <bpmn2:endEvent id="end_lv_booked" name="Leave booked">
      <bpmn2:incoming>flv11</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:sequenceFlow id="flv1" sourceRef="start_lv" targetRef="t_lv_submit" />
    <bpmn2:sequenceFlow id="flv2" sourceRef="t_lv_submit" targetRef="t_lv_balance" />
    <bpmn2:sequenceFlow id="flv3" sourceRef="t_lv_balance" targetRef="g_lv_balance" />
    <bpmn2:sequenceFlow id="flv4" name="Yes" sourceRef="g_lv_balance" targetRef="t_lv_review">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:sequenceFlow id="flv5" name="No" sourceRef="g_lv_balance" targetRef="t_lv_decline" />
    <bpmn2:sequenceFlow id="flv6" sourceRef="t_lv_decline" targetRef="end_lv_declined" />
    <bpmn2:sequenceFlow id="flv7" sourceRef="t_lv_review" targetRef="g_lv_appr" />
    <bpmn2:sequenceFlow id="flv8" name="Yes" sourceRef="g_lv_appr" targetRef="t_lv_record">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:sequenceFlow id="flv9" name="No" sourceRef="g_lv_appr" targetRef="t_lv_decline" />
    <bpmn2:sequenceFlow id="flv10" sourceRef="t_lv_record" targetRef="t_lv_confirm" />
    <bpmn2:sequenceFlow id="flv11" sourceRef="t_lv_confirm" targetRef="end_lv_booked" />
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
      <bpmndi:BPMNShape id="pool_lv_di" bpmnElement="pool_lv" isHorizontal="true">
        <dc:Bounds x="20" y="20" width="1420" height="500" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_lv_emp_di" bpmnElement="lane_lv_emp" isHorizontal="true">
        <dc:Bounds x="50" y="20" width="1390" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_lv_mgr_di" bpmnElement="lane_lv_mgr" isHorizontal="true">
        <dc:Bounds x="50" y="150" width="1390" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_lv_hr_di" bpmnElement="lane_lv_hr" isHorizontal="true">
        <dc:Bounds x="50" y="280" width="1390" height="240" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="start_lv_di" bpmnElement="start_lv">
        <dc:Bounds x="112" y="59" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="80" y="101" width="101" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_lv_submit_di" bpmnElement="t_lv_submit">
        <dc:Bounds x="230" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_lv_balance_di" bpmnElement="t_lv_balance">
        <dc:Bounds x="380" y="297" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="g_lv_balance_di" bpmnElement="g_lv_balance">
        <dc:Bounds x="555" y="312" width="50" height="50" />
        <bpmndi:BPMNLabel><dc:Bounds x="533" y="292" width="95" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_lv_decline_di" bpmnElement="t_lv_decline">
        <dc:Bounds x="980" y="407" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="end_lv_declined_di" bpmnElement="end_lv_declined">
        <dc:Bounds x="1162" y="429" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="1137" y="471" width="87" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_lv_review_di" bpmnElement="t_lv_review">
        <dc:Bounds x="680" y="167" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="g_lv_appr_di" bpmnElement="g_lv_appr">
        <dc:Bounds x="855" y="182" width="50" height="50" />
        <bpmndi:BPMNLabel><dc:Bounds x="831" y="162" width="98" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_lv_record_di" bpmnElement="t_lv_record">
        <dc:Bounds x="980" y="297" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_lv_confirm_di" bpmnElement="t_lv_confirm">
        <dc:Bounds x="1130" y="297" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="end_lv_booked_di" bpmnElement="end_lv_booked">
        <dc:Bounds x="1312" y="319" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="1294" y="361" width="72" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="flv1_di" bpmnElement="flv1">
        <di:waypoint x="148" y="77" />
        <di:waypoint x="230" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv2_di" bpmnElement="flv2">
        <di:waypoint x="330" y="77" />
        <di:waypoint x="360" y="77" />
        <di:waypoint x="360" y="337" />
        <di:waypoint x="380" y="337" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv3_di" bpmnElement="flv3">
        <di:waypoint x="480" y="337" />
        <di:waypoint x="555" y="337" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv4_di" bpmnElement="flv4">
        <di:waypoint x="605" y="337" />
        <di:waypoint x="660" y="337" />
        <di:waypoint x="660" y="207" />
        <di:waypoint x="680" y="207" />
        <bpmndi:BPMNLabel><dc:Bounds x="611" y="317" width="21" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv5_di" bpmnElement="flv5">
        <di:waypoint x="605" y="337" />
        <di:waypoint x="960" y="337" />
        <di:waypoint x="960" y="447" />
        <di:waypoint x="980" y="447" />
        <bpmndi:BPMNLabel><dc:Bounds x="611" y="343" width="17" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv6_di" bpmnElement="flv6">
        <di:waypoint x="1080" y="447" />
        <di:waypoint x="1162" y="447" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv7_di" bpmnElement="flv7">
        <di:waypoint x="780" y="207" />
        <di:waypoint x="855" y="207" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv8_di" bpmnElement="flv8">
        <di:waypoint x="905" y="207" />
        <di:waypoint x="960" y="207" />
        <di:waypoint x="960" y="337" />
        <di:waypoint x="980" y="337" />
        <bpmndi:BPMNLabel><dc:Bounds x="911" y="187" width="21" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv9_di" bpmnElement="flv9">
        <di:waypoint x="905" y="207" />
        <di:waypoint x="960" y="207" />
        <di:waypoint x="960" y="447" />
        <di:waypoint x="980" y="447" />
        <bpmndi:BPMNLabel><dc:Bounds x="911" y="213" width="17" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv10_di" bpmnElement="flv10">
        <di:waypoint x="1080" y="337" />
        <di:waypoint x="1130" y="337" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="flv11_di" bpmnElement="flv11">
        <di:waypoint x="1230" y="337" />
        <di:waypoint x="1312" y="337" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>

Frequently asked questions

Why check the balance before the manager reviews the request?

Ordering is the main design decision in this process. Putting the automated balance check first means managers only spend time on requests that are actually grantable, and employees get instant refusals for impossible requests. If your policy lets managers approve negative balances, swap the order and make the balance check advisory instead.

What makes "Check leave balance" a business rule task rather than a user task?

The step applies a fixed policy (accrued days minus days taken and requested) with no human discretion, which is exactly what the business rule task type is for. Marking it this way tells readers the step is deterministic, and tells any future automation project where the quick win is.

How would I add a rule for overlapping absences in the same team?

Add a second condition to the manager stage: either broaden the existing "Request approved?" gateway so cover problems are one reason for a No, or insert a dedicated gateway such as "Team cover adequate?" before it. Keep each gateway to a single question; two small decisions read better than one overloaded one.

Related BPMN examples

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 free

No credit card required