CSV approval workflow template (discount approval by margin)

A discount approval workflow you can paste in as CSV: three margin bands, four approver lanes, and rework loops whose Line to values point backwards up the file to a row number lower than the row they sit on.

Use this template

What the csv approval workflow template (discount approval by margin) process is

You almost certainly did not write this file. A CSV of quote approval steps comes out of something: a CPQ report, a CRM export, a query somebody ran against the ERP and saved, or a tab from a pricing workbook saved as .csv because that was the only format the other system would take. That is the defining fact about a CSV and the reason it behaves differently from the workbook it came from. It has no formulas, only the values those formulas produced at the moment of export. It has no second sheet, no cell colours, no merged headers and no column widths. It is lines of text, one per row, with the first line naming the columns. Anything a reader needs in order to reconstruct the process has to be in those characters, or it is not there at all.

QueryChart reads a small set of column names. Shape is the box type: Start, Process, Decision, End, Success, Reject and the rest. Box text is the label inside the box. Line to is the row this row connects to, written as a row number. Line text is the label on that connector. Line style, Horizontal lane and Vertical lane carry the connector styling and the two swimlane axes, and Parallel with, Notes and Link are there if you need them. Matching is by header name rather than by column position, so the order of your columns does not matter and any extra columns your export brought along (quote id, account, owner, created date) are carried through and ignored. Drop the .csv onto the spreadsheet area of the editor, or paste the CSV text straight into it.

One row is one box, and a row's position in the file is its number: the first data row is 1, the second is 2, and a Line to of 7 means the seventh data row. This is where an approval workflow parts company with a simple procedure. A procedure runs down the file and every Line to is larger than the row it sits on. An approval chain does not. A quote sent back for revision has to return to a step that has already happened, so its Line to value is smaller than its own row number and the arrow points back up the file. Three edges in the chart below do exactly that: row 16 points to 3, row 17 to 13, and row 20 to 15. Getting one of them wrong is the commonest way a hand-numbered approval CSV imports as a field of boxes with an arrow missing, because nothing complains: a Line to naming a row that does not exist is dropped without a message.

The chart itself is a discount approval run by margin rather than by discount percentage. Five stages across the page, four roles down it, and three thresholds deciding who has to look: at or above 40% the rep approves, 30 to 40 goes to the sales manager, 20 to 30 goes to Finance, and below 20 goes to the commercial director. Two approvers can send a quote back, both to the same revision step, and that step returns to the margin calculation because a changed price is a changed margin and may land in a different band. The loop is capped at the second return. Four endings cover the ways a quote actually stops: booked, refused, dropped on margin grounds, and expired with no answer.

What this flowchart covers

In this template

  • Five stage columns (Quote, Margin check, Approval, Rework and Issue) crossed with four role lanes: Sales rep, Sales manager, Finance and Commercial director. In the file those are the Horizontal lane and Vertical lane columns, one value per row, spelled identically on every row that belongs to a lane.
  • A three-step margin ladder instead of a single approval gate: "Margin at or above 40%?" clears at rep level, "Margin at or above 30%?" wakes the sales manager, "Margin at or above 20%?" wakes Finance, and anything below 20% goes to "Prepare the deal summary for the commercial director".
  • Two send-back routes into one rework step. Both "Sales manager approves?" and "Finance approves?" carry a branch to "Revise the discount, the price or the terms", so the file holds one revision step rather than one per approver, and two separate rows whose Line to value names it.
  • The backward edge this cluster keeps warning about. "Second time back from the same approver?" is row 16, and its first-revision branch has a Line to of 3: pointing back up the file to "Calculate gross margin after discount", because a revised price is a new margin and may fall in a different band.
  • A capped loop rather than an open one. "Second time back from the same approver?" routes a second return out of the cycle to "Hold the discount or walk away?", where the deal either goes up to the director or stops, so nothing can bounce between the rep and one approver indefinitely.
  • A customer-side loop and four separate endings. "Customer accepts before the quote expires?" can send the quote back to be revised, and the process finishes at "Order booked at the approved margin", "Discount refused, quote closed", "Deal dropped on margin grounds" or "Quote expired with no order".

When to use this template

  • Your CRM or CPQ exports quote approvals as a CSV, and somebody has asked you what the approval process actually is.
  • Discounts get approved over chat and email, the thresholds are folklore, and nobody can produce the ladder in writing.
  • You have a table of approval steps in a file, and every attempt to redraw it by hand loses the rejection routes because they run backwards.
  • A CSV you imported drew boxes but not all the arrows, and you suspect the rows that send work back.
  • You are writing the discount policy for an audit or a board pack and need the bands, the approvers and the escalation on one page.

The CSV that produces this diagram

One row per step. The numbers in Line to are row numbers — that is what draws the connectors, and it is the column most files are missing.

#ShapeBox textLine toLine textHorizontal laneVertical lane
1StartReceive a discount request from the customer2QuoteSales rep
2ProcessEnter line items, list price and requested discount3QuoteSales rep
3ProcessCalculate gross margin after discount4QuoteSales rep
4ProcessWrite the reason the discount is being asked for5QuoteSales rep
5DecisionMargin at or above 40%?6, 740% or above, Below 40%Margin checkSales rep
6ApprovalApprove at rep level and stamp the margin19ApprovalSales rep
7DecisionMargin at or above 30%?8, 1030% to 40%, Below 30%Margin checkSales manager
8ProcessSales manager checks the reason and the volume commitment9ApprovalSales manager
9DecisionSales manager approves?19, 15, 22Approved, Send back to be revised, Refuse the discountApprovalSales manager
10DecisionMargin at or above 20%?11, 1320% to 30%, Below 20%Margin checkFinance
11ProcessFinance checks the margin against the account history12ApprovalFinance
12DecisionFinance approves?19, 15, 13Approved, Send back to be revised, Refer up to the directorApprovalFinance
13ProcessPrepare the deal summary for the commercial director14ApprovalCommercial director
14DecisionCommercial director approves?19, 18, 22Approved, Approved with conditions, Refuse the discountApprovalCommercial director
15ProcessRevise the discount, the price or the terms16ReworkSales rep
16DecisionSecond time back from the same approver?3, 17First revision, Second revisionReworkSales manager
17DecisionHold the discount or walk away?13, 23Hold and take it to the director, Walk away on margin groundsReworkCommercial director
18ProcessRecord the director's conditions on the quote19ApprovalCommercial director
19ProcessIssue the approved quote to the customer20IssueSales rep
20DecisionCustomer accepts before the quote expires?21, 15, 24Accepted, Asks for a bigger discount, No answer before expiryIssueSales rep
21SuccessOrder booked at the approved marginIssueSales rep
22RejectDiscount refused, quote closedIssueSales manager
23EndDeal dropped on margin groundsIssueCommercial director
24EndQuote expired with no orderIssueSales rep
#,Shape,Box text,Line to,Line text,Horizontal lane,Vertical lane
1,Start,Receive a discount request from the customer,2,,Quote,Sales rep
2,Process,"Enter line items, list price and requested discount",3,,Quote,Sales rep
3,Process,Calculate gross margin after discount,4,,Quote,Sales rep
4,Process,Write the reason the discount is being asked for,5,,Quote,Sales rep
5,Decision,Margin at or above 40%?,"6, 7","40% or above, Below 40%",Margin check,Sales rep
6,Approval,Approve at rep level and stamp the margin,19,,Approval,Sales rep
7,Decision,Margin at or above 30%?,"8, 10","30% to 40%, Below 30%",Margin check,Sales manager
8,Process,Sales manager checks the reason and the volume commitment,9,,Approval,Sales manager
9,Decision,Sales manager approves?,"19, 15, 22","Approved, Send back to be revised, Refuse the discount",Approval,Sales manager
10,Decision,Margin at or above 20%?,"11, 13","20% to 30%, Below 20%",Margin check,Finance
11,Process,Finance checks the margin against the account history,12,,Approval,Finance
12,Decision,Finance approves?,"19, 15, 13","Approved, Send back to be revised, Refer up to the director",Approval,Finance
13,Process,Prepare the deal summary for the commercial director,14,,Approval,Commercial director
14,Decision,Commercial director approves?,"19, 18, 22","Approved, Approved with conditions, Refuse the discount",Approval,Commercial director
15,Process,"Revise the discount, the price or the terms",16,,Rework,Sales rep
16,Decision,Second time back from the same approver?,"3, 17","First revision, Second revision",Rework,Sales manager
17,Decision,Hold the discount or walk away?,"13, 23","Hold and take it to the director, Walk away on margin grounds",Rework,Commercial director
18,Process,Record the director's conditions on the quote,19,,Approval,Commercial director
19,Process,Issue the approved quote to the customer,20,,Issue,Sales rep
20,Decision,Customer accepts before the quote expires?,"21, 15, 24","Accepted, Asks for a bigger discount, No answer before expiry",Issue,Sales rep
21,Success,Order booked at the approved margin,,,Issue,Sales rep
22,Reject,"Discount refused, quote closed",,,Issue,Sales manager
23,End,Deal dropped on margin grounds,,,Issue,Commercial director
24,End,Quote expired with no order,,,Issue,Sales rep

How it works

  1. Open the file in a text editor before you import it

    Look at the raw characters first. Is the separator a comma or a semicolon? Excel writes semicolons wherever the system list separator is a semicolon, which is most of continental Europe, because the comma is already the decimal separator there. A semicolon file read as a comma file gives you one column with the whole line inside it. Check the accented characters too: if they arrive as mojibake the file is not the encoding it is being read as. And if the first column is the only one that will not line up, the invisible byte order mark that Excel's CSV UTF-8 export writes in front of the first header is the usual reason — retype that header or save as plain CSV.

  2. Give the file the header names the editor reads

    The first line has to name the columns: Shape, Box text, Line to, Line text, Line style, Horizontal lane, Vertical lane. Matching is on the name, so column order is free and every extra column your export produced rides along and is ignored. Delete any title or filter rows sitting above the headers — a CSV has no concept of a header block, so a report title on line 1 makes your real headers into ordinary data. A misspelled header is not an error either; it is simply a column that does nothing, so confirm each one you meant to use has arrived.

  3. Number the rows before you write a single Line to

    A row's number is its position in the data: first data row 1, second 2, and so on. Write the numbers down the side before you connect anything, then write the connections. Inserting a row afterwards renumbers every row below it and re-points every Line to that referred to them, so finish the row list before you start on the arrows.

  4. Write the backward edges last, and read each one out loud

    Every send-back is a Line to smaller than its own row. Here "Second time back from the same approver?" is row 16 and its first-revision Line to is 3; row 17 points to 13; row 20 points to 15. Say each as a sentence — row 16 goes back to row 3, which is "Calculate gross margin after discount" — because a backward number that is off by one still looks entirely reasonable sitting in the file, and it draws an arrow into the wrong box rather than none at all.

  5. Keep commas out of Line to and Line text

    Those two columns are comma-separated lists read in matching order, so row 20's Line to reads 21,15,24 while its Line text reads Accepted,Asks for a bigger discount,No answer before expiry — three targets, three labels, aligned by position. A comma inside a branch label would be read as another branch, which is why no connector label in this chart contains one. Box text is a single value, so a comma is fine there provided the field is quoted: "Enter line items, list price and requested discount" survives the round trip, and the same text unquoted becomes two columns.

  6. Put your own numbers in the bands

    40, 30 and 20 are placeholders. Set them from your own price book so the top band covers most quotes; if the majority of your deals fall below the first threshold then every quote becomes an approval and the queue becomes the process. Define what margin means while you are there — gross margin after discount, measured against which cost — because a threshold is only as reliable as the number it is compared with, and in a CSV that number is a snapshot with no formula behind it.

Frequently asked questions

How do you write a rework loop in a CSV?

With a Line to value smaller than the row it sits on. A CSV contains no arrows; the only thing that makes an edge is a row number in the Line to column, and nothing requires that number to be larger than the current row. A rejection route is written exactly like any other connection, and the only difference is that it points up the file instead of down. In this chart the revision step is row 15 and rows 9, 12 and 20 all name it: the first two are forward references from the approvers, the third is a backward one from the customer step. Row 16 then points back to row 3. Two things to watch. A loop with no exit imports happily and reads as a process that can never finish, so cap it with a decision — here "Second time back from the same approver?". And a Line to naming a row that does not exist is dropped without a message, so an off-by-one on a backward edge shows up as a missing arrow rather than as an error.

What columns does a CSV need to import as a flowchart?

Seven do the work. Shape sets the box type — Start, Process, Decision, End, Success, Reject and the other shapes the editor knows. Box text is the label. Line to holds the row number or numbers this row connects to, comma-separated. Line text holds the connector labels in the same order, which is why the two columns have to be read together. Line style takes a description such as Green dashed. Horizontal lane and Vertical lane place the row on the two swimlane axes. Parallel with, Notes and Link exist as well. Columns are matched by header name rather than by position, and any other column your export produced is carried and ignored — so a CSV straight out of a CRM with fifteen columns imports fine and only the seven that matter are read.

Why did my CSV import with boxes but no arrows?

Four causes, in rough order of frequency. The Line to column holds step names instead of row numbers, and a label is not a reference. The header row is missing, misspelled, or sitting under a report title, so the column was never matched at all. The file is semicolon-delimited and was read as comma-delimited, which puts the entire line in the first column, giving every row a shape and nothing else. Or the numbers are simply wrong, usually because a row was inserted and nothing was renumbered. The last one is the hardest to spot, because an edge naming a row that does not exist is discarded silently: the chart still draws, looks finished, and is missing a route.

What thresholds should a discount approval workflow use?

Bands of margin rather than bands of discount percentage, and few enough that people remember them. Discount percentage is the wrong axis, because the same 15% off is comfortable on one product and below cost on another; margin after discount is comparable across a price book. Three bands and four levels of approver is a common shape and the one drawn here: the rep clears anything at or above 40%, the sales manager takes 30 to 40, Finance takes 20 to 30, and below 20 goes to the commercial director. The numbers are yours to set. The test of a good set is the proportion of quotes that clear at the first level — if most of them need somebody else to look, either the price book or the thresholds are wrong, and the approval process will be blamed for both.

How is a CSV different from an Excel file for this?

A CSV is the output of a system rather than a place you work in. It carries values and not formulas, so a margin column exported at ten in the morning holds the number that formula produced at ten in the morning, and re-exporting after a cost change gives a different file with nothing in it to say anything moved. It has one table and no second sheet, so the lookup your margin formula pointed at did not come with it. It has no formatting at all, which matters here for one reason: an approval level shown as a cell colour in a workbook conveys nothing in a CSV, and if the level matters it needs a column of its own. Against that, a CSV is plain text — you can read it, diff it and see exactly what the system handed you, row numbers in the Line to column included.

Use this template

Guides that use this template

More in CSV flowchart and diagram templates

More in Process flowchart templates

Browse all CSV flowchart and diagram templates