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.
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.
| # | 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 | Process | 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 rep |
| 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 |
#,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,Process,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 rep
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 repHow it works
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.
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.
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.
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.
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.
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.