SwimdraftPricingSign inStart free

Quote approval BPMN example

Quote approval is the control that stops discounting from eating your margin. Most organisations have one, but it usually lives in email threads: a rep asks for 20 percent off, someone in finance replies days later, and the deal cools while everyone waits. Mapping the process exposes exactly which discounts need sign off and who gives it, which is the first step to speeding it up.

The model here uses a single pool with Sales, Deal desk, and Finance lanes. A business rule task applies the pricing policy automatically, so the first gateway is decided by rules rather than opinion; only out of policy discounts reach a human in Finance. The rework loop from a refused discount back to the pricing check is the modelling choice worth noticing: refusal does not kill the quote, it sends it back for revision.

Quote approval: BPMN 2.0 diagram
Quote approval 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
Quote requested
Ends with
Quote issued
Lanes
Sales · Deal desk · Finance
Decisions
Discount within limits? · Discount approved?

How to read this diagram

A request from the field opens the process at the "Quote requested" start event in the Sales lane. The rep drafts the quote, then the Deal desk lane applies pricing rules through a business rule task. At the gateway "Discount within limits?", the Yes branch skips straight to sending the quote, while the No branch (the default) escalates to the Finance lane for a discount review.

Finance answers the second gateway, "Discount approved?". Yes joins the happy path at the send task; the default No branch returns the quote to Sales for revision, and the revised quote loops back through the pricing rules until it either passes or wins approval. Once the quote is sent, recording it in the CRM closes the process at the single "Quote issued" end event: every quote that enters this process eventually goes out the door in an approved form.

BPMN elements used

ElementCountIn this diagram
Start event1Quote requested
End event1Quote issued
Task3Draft quote, Revise quote, Record quote in CRM
User task1Review discount request
Send task1Send quote to customer
Business rule task1Apply pricing rules
Exclusive gateway2Discount within limits?, Discount 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_qa" name="Quote approval" processRef="Process_pool_qa" />
  </bpmn2:collaboration>
  <bpmn2:process id="Process_pool_qa" isExecutable="false">
    <bpmn2:laneSet id="LaneSet_pool_qa">
      <bpmn2:lane id="lane_qa_sales" name="Sales">
        <bpmn2:flowNodeRef>start_qa</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_qa_draft</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_qa_revise</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_qa_send</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_qa_record</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>end_qa_issued</bpmn2:flowNodeRef>
      </bpmn2:lane>
      <bpmn2:lane id="lane_qa_desk" name="Deal desk">
        <bpmn2:flowNodeRef>t_qa_price</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>g_qa_limits</bpmn2:flowNodeRef>
      </bpmn2:lane>
      <bpmn2:lane id="lane_qa_fin" name="Finance">
        <bpmn2:flowNodeRef>t_qa_review</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>g_qa_approve</bpmn2:flowNodeRef>
      </bpmn2:lane>
    </bpmn2:laneSet>
    <bpmn2:startEvent id="start_qa" name="Quote requested">
      <bpmn2:outgoing>fqa1</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:task id="t_qa_draft" name="Draft quote">
      <bpmn2:incoming>fqa1</bpmn2:incoming>
      <bpmn2:outgoing>fqa2</bpmn2:outgoing>
    </bpmn2:task>
    <bpmn2:businessRuleTask id="t_qa_price" name="Apply pricing rules">
      <bpmn2:incoming>fqa2</bpmn2:incoming>
      <bpmn2:incoming>fqa9</bpmn2:incoming>
      <bpmn2:outgoing>fqa3</bpmn2:outgoing>
    </bpmn2:businessRuleTask>
    <bpmn2:exclusiveGateway id="g_qa_limits" name="Discount within limits?" default="fqa5">
      <bpmn2:incoming>fqa3</bpmn2:incoming>
      <bpmn2:outgoing>fqa4</bpmn2:outgoing>
      <bpmn2:outgoing>fqa5</bpmn2:outgoing>
    </bpmn2:exclusiveGateway>
    <bpmn2:userTask id="t_qa_review" name="Review discount request">
      <bpmn2:incoming>fqa5</bpmn2:incoming>
      <bpmn2:outgoing>fqa6</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:exclusiveGateway id="g_qa_approve" name="Discount approved?" default="fqa8">
      <bpmn2:incoming>fqa6</bpmn2:incoming>
      <bpmn2:outgoing>fqa7</bpmn2:outgoing>
      <bpmn2:outgoing>fqa8</bpmn2:outgoing>
    </bpmn2:exclusiveGateway>
    <bpmn2:task id="t_qa_revise" name="Revise quote">
      <bpmn2:incoming>fqa8</bpmn2:incoming>
      <bpmn2:outgoing>fqa9</bpmn2:outgoing>
    </bpmn2:task>
    <bpmn2:sendTask id="t_qa_send" name="Send quote to customer">
      <bpmn2:incoming>fqa4</bpmn2:incoming>
      <bpmn2:incoming>fqa7</bpmn2:incoming>
      <bpmn2:outgoing>fqa10</bpmn2:outgoing>
    </bpmn2:sendTask>
    <bpmn2:task id="t_qa_record" name="Record quote in CRM">
      <bpmn2:incoming>fqa10</bpmn2:incoming>
      <bpmn2:outgoing>fqa11</bpmn2:outgoing>
    </bpmn2:task>
    <bpmn2:endEvent id="end_qa_issued" name="Quote issued">
      <bpmn2:incoming>fqa11</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:sequenceFlow id="fqa1" sourceRef="start_qa" targetRef="t_qa_draft" />
    <bpmn2:sequenceFlow id="fqa2" sourceRef="t_qa_draft" targetRef="t_qa_price" />
    <bpmn2:sequenceFlow id="fqa3" sourceRef="t_qa_price" targetRef="g_qa_limits" />
    <bpmn2:sequenceFlow id="fqa4" name="Yes" sourceRef="g_qa_limits" targetRef="t_qa_send">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:sequenceFlow id="fqa5" name="No" sourceRef="g_qa_limits" targetRef="t_qa_review" />
    <bpmn2:sequenceFlow id="fqa6" sourceRef="t_qa_review" targetRef="g_qa_approve" />
    <bpmn2:sequenceFlow id="fqa7" name="Yes" sourceRef="g_qa_approve" targetRef="t_qa_send">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:sequenceFlow id="fqa8" name="No" sourceRef="g_qa_approve" targetRef="t_qa_revise" />
    <bpmn2:sequenceFlow id="fqa9" sourceRef="t_qa_revise" targetRef="t_qa_price" />
    <bpmn2:sequenceFlow id="fqa10" sourceRef="t_qa_send" targetRef="t_qa_record" />
    <bpmn2:sequenceFlow id="fqa11" sourceRef="t_qa_record" targetRef="end_qa_issued" />
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
      <bpmndi:BPMNShape id="pool_qa_di" bpmnElement="pool_qa" isHorizontal="true">
        <dc:Bounds x="20" y="20" width="1420" height="500" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_qa_sales_di" bpmnElement="lane_qa_sales" isHorizontal="true">
        <dc:Bounds x="50" y="20" width="1390" height="240" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_qa_desk_di" bpmnElement="lane_qa_desk" isHorizontal="true">
        <dc:Bounds x="50" y="260" width="1390" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_qa_fin_di" bpmnElement="lane_qa_fin" isHorizontal="true">
        <dc:Bounds x="50" y="390" width="1390" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="start_qa_di" bpmnElement="start_qa">
        <dc:Bounds x="112" y="59" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="88" y="101" width="84" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_qa_draft_di" bpmnElement="t_qa_draft">
        <dc:Bounds x="230" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_qa_price_di" bpmnElement="t_qa_price">
        <dc:Bounds x="380" y="277" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="g_qa_limits_di" bpmnElement="g_qa_limits">
        <dc:Bounds x="555" y="292" width="50" height="50" />
        <bpmndi:BPMNLabel><dc:Bounds x="525" y="272" width="111" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_qa_review_di" bpmnElement="t_qa_review">
        <dc:Bounds x="680" y="407" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="g_qa_approve_di" bpmnElement="g_qa_approve">
        <dc:Bounds x="855" y="422" width="50" height="50" />
        <bpmndi:BPMNLabel><dc:Bounds x="830" y="402" width="100" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_qa_revise_di" bpmnElement="t_qa_revise">
        <dc:Bounds x="980" y="147" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_qa_send_di" bpmnElement="t_qa_send">
        <dc:Bounds x="980" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_qa_record_di" bpmnElement="t_qa_record">
        <dc:Bounds x="1130" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="end_qa_issued_di" bpmnElement="end_qa_issued">
        <dc:Bounds x="1312" y="59" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="1297" y="101" width="67" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="fqa1_di" bpmnElement="fqa1">
        <di:waypoint x="148" y="77" />
        <di:waypoint x="230" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa2_di" bpmnElement="fqa2">
        <di:waypoint x="330" y="77" />
        <di:waypoint x="360" y="77" />
        <di:waypoint x="360" y="317" />
        <di:waypoint x="380" y="317" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa3_di" bpmnElement="fqa3">
        <di:waypoint x="480" y="317" />
        <di:waypoint x="555" y="317" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa4_di" bpmnElement="fqa4">
        <di:waypoint x="605" y="317" />
        <di:waypoint x="960" y="317" />
        <di:waypoint x="960" y="77" />
        <di:waypoint x="980" y="77" />
        <bpmndi:BPMNLabel><dc:Bounds x="611" y="297" width="21" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa5_di" bpmnElement="fqa5">
        <di:waypoint x="605" y="317" />
        <di:waypoint x="660" y="317" />
        <di:waypoint x="660" y="447" />
        <di:waypoint x="680" y="447" />
        <bpmndi:BPMNLabel><dc:Bounds x="611" y="323" width="17" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa6_di" bpmnElement="fqa6">
        <di:waypoint x="780" y="447" />
        <di:waypoint x="855" y="447" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa7_di" bpmnElement="fqa7">
        <di:waypoint x="905" y="447" />
        <di:waypoint x="960" y="447" />
        <di:waypoint x="960" y="77" />
        <di:waypoint x="980" y="77" />
        <bpmndi:BPMNLabel><dc:Bounds x="911" y="427" width="21" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa8_di" bpmnElement="fqa8">
        <di:waypoint x="905" y="447" />
        <di:waypoint x="960" y="447" />
        <di:waypoint x="960" y="187" />
        <di:waypoint x="980" y="187" />
        <bpmndi:BPMNLabel><dc:Bounds x="911" y="453" width="17" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa9_di" bpmnElement="fqa9">
        <di:waypoint x="1080" y="187" />
        <di:waypoint x="1110" y="187" />
        <di:waypoint x="1110" y="242" />
        <di:waypoint x="360" y="242" />
        <di:waypoint x="360" y="317" />
        <di:waypoint x="380" y="317" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa10_di" bpmnElement="fqa10">
        <di:waypoint x="1080" y="77" />
        <di:waypoint x="1130" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fqa11_di" bpmnElement="fqa11">
        <di:waypoint x="1230" y="77" />
        <di:waypoint x="1312" y="77" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>

Frequently asked questions

Why use a business rule task for the pricing check?

The pricing policy is a decision table, not human judgement: discount bands, floor prices, and product rules that a decision engine can evaluate. BPMN provides the business rule task type for exactly this, and pairing it with a gateway keeps the automated decision separate from the exception handling that follows it.

Is a rework loop back to an earlier task allowed in BPMN?

Yes, sequence flows may return to an upstream activity, and loops like this are the standard way to model revision cycles. The important discipline is that the loop must rejoin the normal flow so the token can still reach an end event. Here the revised quote re-enters at the pricing rules task and takes the same gateways again.

Why does this model have only one end event?

Because the process has only one meaningful outcome: an approved quote reaches the customer. A refused discount does not terminate anything, it triggers revision, so it is a loop rather than an end state. If your organisation allows quotes to be abandoned, add a second end event such as "Quote withdrawn" on a labelled branch.

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