Grievance handling BPMN example
Grievance handling is one of the few HR processes where the map is close to mandatory: employment tribunals and the Acas code both expect a documented, consistently applied procedure with acknowledgement, investigation, a hearing, and a right of appeal. Mapping it protects both sides, because the common failure is not malice but drift, with steps skipped or deadlines missed under workload.
This example is a single pool with Employee, HR, and Investigating manager lanes, keeping the person who investigates visibly separate from the HR function that administers the case. The modelling choice to notice is the appeal window: after the written outcome, an intermediate timer event holds the case open until the window closes, and only then does a gateway ask whether an appeal arrived.
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
Submission of the grievance form by the Employee starts the case. HR logs it and sends an acknowledgement, then hands over to the Investigating manager, who investigates the complaint and holds the grievance hearing. HR issues the written outcome, at which point the process does not simply end: it waits at the "Appeal window closes" timer event, because the employee has a fixed period in which to challenge the decision.
Once the window shuts, the exclusive gateway "Appeal received?" resolves the case. On the No branch, the default flow, the token goes straight to the "Case closed" end event. On Yes, the Investigating manager holds an appeal hearing and HR issues the final decision, which flows into the same end event. One end state, two routes into it: however it gets there, a grievance case always closes formally.
BPMN elements used
| Element | Count | In this diagram |
|---|---|---|
| Start event | 1 | Grievance raised |
| End event | 1 | Case closed |
| Intermediate catch event | 1 | Appeal window closes |
| Task | 2 | Issue written outcome, Issue final decision |
| User task | 5 | Submit grievance form, Log grievance case, Investigate grievance, Hold grievance hearing, Hold appeal hearing |
| Send task | 1 | Acknowledge receipt |
| Exclusive gateway | 1 | Appeal received? |
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_gr" name="Grievance handling" processRef="Process_pool_gr" />
</bpmn2:collaboration>
<bpmn2:process id="Process_pool_gr" isExecutable="false">
<bpmn2:laneSet id="LaneSet_pool_gr">
<bpmn2:lane id="lane_gr_emp" name="Employee">
<bpmn2:flowNodeRef>start_gr</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_gr_submit</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_gr_hr" name="HR">
<bpmn2:flowNodeRef>t_gr_log</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_gr_ack</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_gr_outcome</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>ev_gr_window</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_gr_appeal</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_gr_final</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_gr</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_gr_im" name="Investigating manager">
<bpmn2:flowNodeRef>t_gr_invest</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_gr_hearing</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_gr_appealhear</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="start_gr" name="Grievance raised">
<bpmn2:outgoing>fgr1</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="t_gr_submit" name="Submit grievance form">
<bpmn2:incoming>fgr1</bpmn2:incoming>
<bpmn2:outgoing>fgr2</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="t_gr_log" name="Log grievance case">
<bpmn2:incoming>fgr2</bpmn2:incoming>
<bpmn2:outgoing>fgr3</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sendTask id="t_gr_ack" name="Acknowledge receipt">
<bpmn2:incoming>fgr3</bpmn2:incoming>
<bpmn2:outgoing>fgr4</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:userTask id="t_gr_invest" name="Investigate grievance">
<bpmn2:incoming>fgr4</bpmn2:incoming>
<bpmn2:outgoing>fgr5</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:userTask id="t_gr_hearing" name="Hold grievance hearing">
<bpmn2:incoming>fgr5</bpmn2:incoming>
<bpmn2:outgoing>fgr6</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:task id="t_gr_outcome" name="Issue written outcome">
<bpmn2:incoming>fgr6</bpmn2:incoming>
<bpmn2:outgoing>fgr7</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:intermediateCatchEvent id="ev_gr_window" name="Appeal window closes">
<bpmn2:incoming>fgr7</bpmn2:incoming>
<bpmn2:outgoing>fgr8</bpmn2:outgoing>
<bpmn2:timerEventDefinition id="ev_gr_window_def" />
</bpmn2:intermediateCatchEvent>
<bpmn2:exclusiveGateway id="g_gr_appeal" name="Appeal received?" default="fgr10">
<bpmn2:incoming>fgr8</bpmn2:incoming>
<bpmn2:outgoing>fgr9</bpmn2:outgoing>
<bpmn2:outgoing>fgr10</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:userTask id="t_gr_appealhear" name="Hold appeal hearing">
<bpmn2:incoming>fgr9</bpmn2:incoming>
<bpmn2:outgoing>fgr11</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:task id="t_gr_final" name="Issue final decision">
<bpmn2:incoming>fgr11</bpmn2:incoming>
<bpmn2:outgoing>fgr12</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:endEvent id="end_gr" name="Case closed">
<bpmn2:incoming>fgr10</bpmn2:incoming>
<bpmn2:incoming>fgr12</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="fgr1" sourceRef="start_gr" targetRef="t_gr_submit" />
<bpmn2:sequenceFlow id="fgr2" sourceRef="t_gr_submit" targetRef="t_gr_log" />
<bpmn2:sequenceFlow id="fgr3" sourceRef="t_gr_log" targetRef="t_gr_ack" />
<bpmn2:sequenceFlow id="fgr4" sourceRef="t_gr_ack" targetRef="t_gr_invest" />
<bpmn2:sequenceFlow id="fgr5" sourceRef="t_gr_invest" targetRef="t_gr_hearing" />
<bpmn2:sequenceFlow id="fgr6" sourceRef="t_gr_hearing" targetRef="t_gr_outcome" />
<bpmn2:sequenceFlow id="fgr7" sourceRef="t_gr_outcome" targetRef="ev_gr_window" />
<bpmn2:sequenceFlow id="fgr8" sourceRef="ev_gr_window" targetRef="g_gr_appeal" />
<bpmn2:sequenceFlow id="fgr9" name="Yes" sourceRef="g_gr_appeal" targetRef="t_gr_appealhear">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fgr10" name="No" sourceRef="g_gr_appeal" targetRef="end_gr" />
<bpmn2:sequenceFlow id="fgr11" sourceRef="t_gr_appealhear" targetRef="t_gr_final" />
<bpmn2:sequenceFlow id="fgr12" sourceRef="t_gr_final" targetRef="end_gr" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
<bpmndi:BPMNShape id="pool_gr_di" bpmnElement="pool_gr" isHorizontal="true">
<dc:Bounds x="20" y="20" width="1870" height="390" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_gr_emp_di" bpmnElement="lane_gr_emp" isHorizontal="true">
<dc:Bounds x="50" y="20" width="1840" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_gr_hr_di" bpmnElement="lane_gr_hr" isHorizontal="true">
<dc:Bounds x="50" y="150" width="1840" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_gr_im_di" bpmnElement="lane_gr_im" isHorizontal="true">
<dc:Bounds x="50" y="280" width="1840" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="start_gr_di" bpmnElement="start_gr">
<dc:Bounds x="112" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="87" y="101" width="86" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_submit_di" bpmnElement="t_gr_submit">
<dc:Bounds x="230" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_log_di" bpmnElement="t_gr_log">
<dc:Bounds x="380" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_ack_di" bpmnElement="t_gr_ack">
<dc:Bounds x="530" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_invest_di" bpmnElement="t_gr_invest">
<dc:Bounds x="680" y="297" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_hearing_di" bpmnElement="t_gr_hearing">
<dc:Bounds x="830" y="297" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_outcome_di" bpmnElement="t_gr_outcome">
<dc:Bounds x="980" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ev_gr_window_di" bpmnElement="ev_gr_window">
<dc:Bounds x="1162" y="189" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1125" y="231" width="111" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_gr_appeal_di" bpmnElement="g_gr_appeal">
<dc:Bounds x="1305" y="182" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="1287" y="162" width="87" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_appealhear_di" bpmnElement="t_gr_appealhear">
<dc:Bounds x="1430" y="297" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_gr_final_di" bpmnElement="t_gr_final">
<dc:Bounds x="1580" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_gr_di" bpmnElement="end_gr">
<dc:Bounds x="1762" y="189" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1749" y="231" width="63" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="fgr1_di" bpmnElement="fgr1">
<di:waypoint x="148" y="77" />
<di:waypoint x="230" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr2_di" bpmnElement="fgr2">
<di:waypoint x="330" y="77" />
<di:waypoint x="360" y="77" />
<di:waypoint x="360" y="207" />
<di:waypoint x="380" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr3_di" bpmnElement="fgr3">
<di:waypoint x="480" y="207" />
<di:waypoint x="530" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr4_di" bpmnElement="fgr4">
<di:waypoint x="630" y="207" />
<di:waypoint x="660" y="207" />
<di:waypoint x="660" y="337" />
<di:waypoint x="680" y="337" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr5_di" bpmnElement="fgr5">
<di:waypoint x="780" y="337" />
<di:waypoint x="830" y="337" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr6_di" bpmnElement="fgr6">
<di:waypoint x="930" y="337" />
<di:waypoint x="960" y="337" />
<di:waypoint x="960" y="207" />
<di:waypoint x="980" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr7_di" bpmnElement="fgr7">
<di:waypoint x="1080" y="207" />
<di:waypoint x="1162" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr8_di" bpmnElement="fgr8">
<di:waypoint x="1198" y="207" />
<di:waypoint x="1305" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr9_di" bpmnElement="fgr9">
<di:waypoint x="1355" y="207" />
<di:waypoint x="1410" y="207" />
<di:waypoint x="1410" y="337" />
<di:waypoint x="1430" y="337" />
<bpmndi:BPMNLabel><dc:Bounds x="1361" y="187" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr10_di" bpmnElement="fgr10">
<di:waypoint x="1355" y="207" />
<di:waypoint x="1410" y="207" />
<di:waypoint x="1410" y="262" />
<di:waypoint x="1710" y="262" />
<di:waypoint x="1710" y="207" />
<di:waypoint x="1762" y="207" />
<bpmndi:BPMNLabel><dc:Bounds x="1361" y="213" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr11_di" bpmnElement="fgr11">
<di:waypoint x="1530" y="337" />
<di:waypoint x="1560" y="337" />
<di:waypoint x="1560" y="207" />
<di:waypoint x="1580" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fgr12_di" bpmnElement="fgr12">
<di:waypoint x="1680" y="207" />
<di:waypoint x="1762" y="207" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>Frequently asked questions
Why wait for the appeal window instead of ending after the outcome?
Because the case is not legally finished when the outcome letter goes out. Ending the process there would model a version of the procedure that ignores the right of appeal. The timer event keeps the instance alive for exactly the window your policy defines, and the gateway afterwards records how it resolved.
Should the appeal be heard by the same investigating manager?
In practice, no: the Acas code expects an appeal to be heard by someone not previously involved, ideally more senior. The model keeps one Investigating manager lane for compactness. To be stricter, add a separate "Appeal manager" lane and move the "Hold appeal hearing" task into it, making the independence visible in the diagram.
How would I model deadlines for each stage, not just the appeal?
Attach boundary timer events to the long running tasks, such as the investigation and the hearing, each escalating to HR or a senior manager if the stage overruns. This example keeps a single timer to stay readable, but a compliance grade version would put a clock on every stage the policy gives a deadline.
Related BPMN examples
Employee onboarding
An employee onboarding process diagram in BPMN 2.0: background checks, parallel IT setup, and induction. View the swimlane diagram and download the .bpmn file free.
Employee offboarding
Employee offboarding as a BPMN 2.0 diagram: handover planning, a last day timer, parallel access revocation, and final pay. Download the .bpmn file free.
Recruitment
A recruitment process in BPMN 2.0: screening, interviews, offer, and a candidate pool with message flows. View the diagram and download the .bpmn file free.
Leave request
A leave request process as a BPMN 2.0 diagram: balance check, manager approval, and booking confirmation. View the swimlanes and 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