{
  "name": "Weekly count-and-order list for inventory lines",
  "page": "https://otherworldlabs.com/how-much-stock-to-reorder/",
  "endpoint": "https://otherworldlabs.com/how-much-stock-to-reorder/api.json",
  "question": "Given two counts of the same inventory lines taken a week apart, and anything received between them, how much of each line should be ordered this week?",
  "answers": "Per line: the units used last week, derived from the two counts rather than typed; the weeks on hand now; this week's order in units and in whole packs; the units the pack rounding adds; the units a supplier minimum adds, kept apart from the rounding; the weeks on hand once the order arrives; a verdict naming which of five states the line is in; and, where something other than the cover shortfall decided the order, which of three things it was. For the week: the lines to order, the total units and the total packs, withheld while any line has no usage figure.",
  "version": "1.0",
  "licence": "Use the arithmetic freely. The figures are the caller's own counts; this endpoint stores nothing and this page sends nothing anywhere.",
  "method": "This is a static description of the calculation, not a service: there is no POST. The page's own engine computes it in the reader's browser, the formula below is the whole of it, and the worked example is this page's shipped sheet so a caller can check an implementation against it line by line. The example carries the seven week fields and the ten fields of each of the eight lines that sheet has, which is 87 of the 307 names; example.note says why the other 220, the fields of lines 9 to 30 and every one of them null, are left out of it, and apiOutputs itself always returns all 307. Each line's ten fields are described once in per_line.fields and every outputs[].formula for a line points there, so the flat list cannot drift from the description it points at - which it had, on baselineCause, until round 3 (B4).",
  "currency": "none. This calculation holds no price, cost or money figure of any kind, so nothing here is in any currency and nothing here is financial, tax or investment advice.",
  "rounding": {
    "counts": "whole. A typed fraction is rounded to the nearest whole before anything is worked from it, and the page prints both figures: what was typed and what the working used. A figure below the range's floor reads as the floor and one above its ceiling reads as the ceiling, printed the same way.",
    "targetCoverWeeks": "half-weeks. A typed figure is snapped to the nearest 0.5 and clamped into 0.5 to 12, and the page prints what was typed beside what it used.",
    "cover": "the cover a line wants is worked exactly, printed to two decimals, and then taken up to the NEXT WHOLE UNIT by Math.ceil, because part of a unit is not a unit a shelf can hold. The product is read to six decimals first, by Math.round(x * 1e6) / 1e6: the true figure is always a whole number of fourteenths of a unit, so a residue smaller than that is binary floating point and not a part of a unit, and taking a ceiling on it would add a unit nobody needs. Both printed figures are the two-decimal one and the whole one.",
    "order": "taken up to the next whole pack by Math.ceil(need / packSize), and then, where a supplier minimum is above that, up to the next whole pack at or above the minimum, Math.ceil(supplierMin / packSize) packs. The order is always a whole number of packs, and the two amounts above the week's need - what the pack rounding adds and what the supplier minimum adds - are returned as two fields and are never summed into one.",
    "weeks": "weeks on hand, before and after the order, are rounded to one decimal by Math.round(x * 10) / 10 on the double, which puts a half toward positive infinity. Both figures are non-negative wherever they are a number at all, so the sign behaviour of that rounding at a negative half is not reachable here: a count and a usage figure are both counts of units and neither can be negative, and the one subtraction that could go negative - last week's count plus receipts less the count now - is not printed at all when it does, which is verdict class 5.",
    "percentages": "none. This calculation prints and returns no percentage, so there is no percentage precision rule to state."
  },
  "required_means": "`required` on an input of this endpoint means ADMISSIBILITY and nothing else: a request that omits a field marked false is accepted and has the answer the field's own note states. No input on this endpoint is required, because every one of the ten has a defined reading when it is blank or absent, so a caller can post a bare list of lines with nothing but the counts and get a complete answer. Review round 2, m2, is why this key exists: three fields - targetCoverWeeks, leadTimeDays and packSize - were marked required while their own notes said what a blank is read as, so a caller validating a request against this schema would have rejected a request the page accepts and answers, which is claim 8c (an agent reading the endpoint beside the page can reproduce the page) failing on admissibility rather than on arithmetic. The reading under which those three were right - that a blank on them is not a STATE, only a default, so the field always carries a value into the calculation - is a true statement about the calculation and not a statement about what a request must carry, which is what this flag is for; it is stated instead in the two groups below. The two groups are: the three fields where a blank is a STATE OF ITS OWN and the line returns no usage figure and no order - countedNow, lastCount and received - and the five where a blank is read as a FIGURE, named in each note - targetCoverWeeks 0.5, leadTimeDays 0, packSize 1, parFloor 0 and supplierMin 0. Each note says which of the two it is; nothing is distinguished by `required`.",
  "inputs": [
    {
      "name": "lineCount",
      "type": "integer",
      "unit": "lines",
      "required": false,
      "min": 1,
      "max": 30,
      "step": 1,
      "note": "How many lines of the count sheet to read. Leave it out and every line the request carries is read, up to thirty: a caller who sends a sheet does not have to say twice how long it is. The form offers a list of 1 to 30 and nothing else; a value outside the range is clamped into it and a fraction is rounded first. Only the first lineCount entries of lines[] are read, so every total below is a total over those lines and not over every entry a request carries. The wound's artefact is a sheet of 5 to 30 lines; 1 is accepted so that a single line with no previous count is still answerable."
    },
    {
      "name": "lines[].name",
      "type": "string",
      "unit": "none",
      "required": false,
      "max_length": 40,
      "note": "The SKU or item name, as it is written on the caller's own count sheet. Blank is allowed: the line is then called by its number, as 'Line 3', and its figures are unaffected. Leading and trailing space is trimmed, runs of space are collapsed, and anything past 40 characters is dropped."
    },
    {
      "name": "lines[].countedNow",
      "type": "integer",
      "unit": "units",
      "required": false,
      "min": 0,
      "max": 100000,
      "step": 1,
      "note": "The count taken now: units of this line on hand today, counted by the caller. BLANK IS A STATE OF ITS OWN and is not the figure 0: a blank here is a line nobody counted this week, so the line returns usedLastWeek null, baselineCause 'not-counted', no order at all, a marker, and the week's totals are withheld. 0 means the line was counted and found empty, which is a count and does give a usage figure. This is the ordinary state of every line on a return visit, because the page writes the kept counts into lastCount and leaves the count boxes empty for the new week; filling a zero in would print an order worked from a count nobody took, and the usage figure is the one figure this calculation exists not to guess."
    },
    {
      "name": "lines[].lastCount",
      "type": "integer",
      "unit": "units",
      "required": false,
      "min": 0,
      "max": 100000,
      "step": 1,
      "note": "The count taken a week ago, off the caller's own paper sheet or kept by the page in that one browser from the previous visit. BLANK IS A STATE OF ITS OWN and is not the figure 0: with no previous count there is nothing to derive the usage from, so the line returns usedLastWeek null, baselineCause 'no-last-count', no order at all, and the week's totals are withheld. A line counted for the first time is the ordinary case of this."
    },
    {
      "name": "lines[].received",
      "type": "integer",
      "unit": "units",
      "required": false,
      "min": 0,
      "max": 100000,
      "step": 1,
      "note": "Units of this line received since that previous count, off the caller's delivery notes where those notes are itemised per line. BLANK MEANS NOT KNOWN and is not the figure 0: a caller whose only record of the delivery is one shipment total for mixed lines leaves this blank on the lines they cannot read off the packing slip, and the line returns usedLastWeek null, baselineCause 'received-unknown', no order, and a marker. This calculation never splits a shipment total across lines, because a total discards which units were which and any split of it would be a guess returned as working."
    },
    {
      "name": "lines[].targetCoverWeeks",
      "type": "number",
      "unit": "weeks",
      "required": false,
      "min": 0.5,
      "max": 12,
      "step": 0.5,
      "note": "How many weeks of inventory the caller wants to hold on this line, their own decision. The supplier's lead time is added to it below; this figure is the cover wanted on top of the wait. A blank or absent value reads as 0.5, the smallest the form offers, and the page says so in a note that names the line, printed above the working in section C rather than beside the input itself: it is not a state of its own, because a target cover of nothing is not a target anybody holds. See required_means: this field was declared required until review round 2 and the declaration was wrong, because a request that omits it is admissible and has this defined answer."
    },
    {
      "name": "lines[].parFloor",
      "type": "integer",
      "unit": "units",
      "required": false,
      "min": 0,
      "max": 100000,
      "step": 1,
      "note": "The on-hand floor for this line: a number of units it should not go below, the caller's own decision. 0 means the line has no floor, and a blank reads as 0 for the same reason - no floor - which is why no note is printed for it. It is the only basis for an order on a line that used nothing last week, and where it sets the order above the cover arithmetic it is named as the reason. A whole pack or that line's supplierMin can still enlarge the order the floor is the basis for, and each of those is named too."
    },
    {
      "name": "lines[].leadTimeDays",
      "type": "integer",
      "unit": "days",
      "required": false,
      "min": 0,
      "max": 60,
      "step": 1,
      "note": "The supplier's lead time on this line, in days, converted at seven days to the week and added to the target cover. 0 means an order that is on the shelf the same day. A blank or absent value reads as 0, the smallest the form offers, and no note is printed for it: unlike a line nobody has counted, a lead time of nothing is not a state of its own, it is the ordinary reading of 'on the shelf the same day' - the same reason parFloor and supplierMin print no note on a blank either. See required_means: this field was declared required until review round 2 and the declaration was wrong, because a request that omits it is admissible and has this defined answer."
    },
    {
      "name": "lines[].packSize",
      "type": "integer",
      "unit": "units per pack",
      "required": false,
      "min": 1,
      "max": 1000,
      "step": 1,
      "note": "Units in one pack or case, off the supplier's own list. Every order is a whole number of these. A blank or absent value reads as 1 and the page says so in a note that names the line, printed above the working in section C rather than beside the input itself: one unit to the pack is the smallest the form offers and it leaves the order equal to the week's need, which is the reading that adds nothing of its own. See required_means: this field was declared required until review round 2 and the declaration was wrong, because a request that omits it is admissible and has this defined answer."
    },
    {
      "name": "lines[].supplierMin",
      "type": "integer",
      "unit": "units",
      "required": false,
      "min": 0,
      "max": 5000,
      "step": 1,
      "note": "The smallest order this supplier accepts on this line, in units. 0 means there is none. A blank reads as 0, which is the same as none, so no note is printed for it."
    }
  ],
  "outputs": [
    {
      "name": "sheetLines",
      "unit": "lines",
      "formula": "the number of lines read, which is lineCount clamped into 1 to 30"
    },
    {
      "name": "usableLines",
      "unit": "lines",
      "formula": "sheetLines - waitingLines"
    },
    {
      "name": "waitingLines",
      "unit": "lines",
      "formula": "the count of lines whose verdict is no-baseline"
    },
    {
      "name": "incomplete",
      "unit": "true or false",
      "formula": "waitingLines > 0"
    },
    {
      "name": "linesToOrder",
      "unit": "lines",
      "formula": "the count of lines with an order, and null while incomplete is true"
    },
    {
      "name": "totalUnits",
      "unit": "units",
      "formula": "the sum of orderUnits, and null while incomplete is true"
    },
    {
      "name": "totalPacks",
      "unit": "packs",
      "formula": "the sum of orderPacks, and null while incomplete is true"
    },
    {
      "name": "l01_usedLastWeek",
      "unit": "units a week",
      "formula": "line 1, per_line.fields.usedLastWeek"
    },
    {
      "name": "l01_weeksOfCover",
      "unit": "weeks",
      "formula": "line 1, per_line.fields.weeksOfCover"
    },
    {
      "name": "l01_orderUnits",
      "unit": "units",
      "formula": "line 1, per_line.fields.orderUnits"
    },
    {
      "name": "l01_orderPacks",
      "unit": "packs",
      "formula": "line 1, per_line.fields.orderPacks"
    },
    {
      "name": "l01_roundingExtraUnits",
      "unit": "units",
      "formula": "line 1, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l01_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 1, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l01_coverAfter",
      "unit": "weeks",
      "formula": "line 1, per_line.fields.coverAfter"
    },
    {
      "name": "l01_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 1, per_line.fields.verdict"
    },
    {
      "name": "l01_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 1, per_line.fields.forcedBy"
    },
    {
      "name": "l01_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 1, per_line.fields.baselineCause"
    },
    {
      "name": "l02_usedLastWeek",
      "unit": "units a week",
      "formula": "line 2, per_line.fields.usedLastWeek"
    },
    {
      "name": "l02_weeksOfCover",
      "unit": "weeks",
      "formula": "line 2, per_line.fields.weeksOfCover"
    },
    {
      "name": "l02_orderUnits",
      "unit": "units",
      "formula": "line 2, per_line.fields.orderUnits"
    },
    {
      "name": "l02_orderPacks",
      "unit": "packs",
      "formula": "line 2, per_line.fields.orderPacks"
    },
    {
      "name": "l02_roundingExtraUnits",
      "unit": "units",
      "formula": "line 2, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l02_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 2, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l02_coverAfter",
      "unit": "weeks",
      "formula": "line 2, per_line.fields.coverAfter"
    },
    {
      "name": "l02_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 2, per_line.fields.verdict"
    },
    {
      "name": "l02_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 2, per_line.fields.forcedBy"
    },
    {
      "name": "l02_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 2, per_line.fields.baselineCause"
    },
    {
      "name": "l03_usedLastWeek",
      "unit": "units a week",
      "formula": "line 3, per_line.fields.usedLastWeek"
    },
    {
      "name": "l03_weeksOfCover",
      "unit": "weeks",
      "formula": "line 3, per_line.fields.weeksOfCover"
    },
    {
      "name": "l03_orderUnits",
      "unit": "units",
      "formula": "line 3, per_line.fields.orderUnits"
    },
    {
      "name": "l03_orderPacks",
      "unit": "packs",
      "formula": "line 3, per_line.fields.orderPacks"
    },
    {
      "name": "l03_roundingExtraUnits",
      "unit": "units",
      "formula": "line 3, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l03_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 3, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l03_coverAfter",
      "unit": "weeks",
      "formula": "line 3, per_line.fields.coverAfter"
    },
    {
      "name": "l03_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 3, per_line.fields.verdict"
    },
    {
      "name": "l03_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 3, per_line.fields.forcedBy"
    },
    {
      "name": "l03_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 3, per_line.fields.baselineCause"
    },
    {
      "name": "l04_usedLastWeek",
      "unit": "units a week",
      "formula": "line 4, per_line.fields.usedLastWeek"
    },
    {
      "name": "l04_weeksOfCover",
      "unit": "weeks",
      "formula": "line 4, per_line.fields.weeksOfCover"
    },
    {
      "name": "l04_orderUnits",
      "unit": "units",
      "formula": "line 4, per_line.fields.orderUnits"
    },
    {
      "name": "l04_orderPacks",
      "unit": "packs",
      "formula": "line 4, per_line.fields.orderPacks"
    },
    {
      "name": "l04_roundingExtraUnits",
      "unit": "units",
      "formula": "line 4, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l04_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 4, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l04_coverAfter",
      "unit": "weeks",
      "formula": "line 4, per_line.fields.coverAfter"
    },
    {
      "name": "l04_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 4, per_line.fields.verdict"
    },
    {
      "name": "l04_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 4, per_line.fields.forcedBy"
    },
    {
      "name": "l04_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 4, per_line.fields.baselineCause"
    },
    {
      "name": "l05_usedLastWeek",
      "unit": "units a week",
      "formula": "line 5, per_line.fields.usedLastWeek"
    },
    {
      "name": "l05_weeksOfCover",
      "unit": "weeks",
      "formula": "line 5, per_line.fields.weeksOfCover"
    },
    {
      "name": "l05_orderUnits",
      "unit": "units",
      "formula": "line 5, per_line.fields.orderUnits"
    },
    {
      "name": "l05_orderPacks",
      "unit": "packs",
      "formula": "line 5, per_line.fields.orderPacks"
    },
    {
      "name": "l05_roundingExtraUnits",
      "unit": "units",
      "formula": "line 5, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l05_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 5, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l05_coverAfter",
      "unit": "weeks",
      "formula": "line 5, per_line.fields.coverAfter"
    },
    {
      "name": "l05_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 5, per_line.fields.verdict"
    },
    {
      "name": "l05_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 5, per_line.fields.forcedBy"
    },
    {
      "name": "l05_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 5, per_line.fields.baselineCause"
    },
    {
      "name": "l06_usedLastWeek",
      "unit": "units a week",
      "formula": "line 6, per_line.fields.usedLastWeek"
    },
    {
      "name": "l06_weeksOfCover",
      "unit": "weeks",
      "formula": "line 6, per_line.fields.weeksOfCover"
    },
    {
      "name": "l06_orderUnits",
      "unit": "units",
      "formula": "line 6, per_line.fields.orderUnits"
    },
    {
      "name": "l06_orderPacks",
      "unit": "packs",
      "formula": "line 6, per_line.fields.orderPacks"
    },
    {
      "name": "l06_roundingExtraUnits",
      "unit": "units",
      "formula": "line 6, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l06_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 6, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l06_coverAfter",
      "unit": "weeks",
      "formula": "line 6, per_line.fields.coverAfter"
    },
    {
      "name": "l06_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 6, per_line.fields.verdict"
    },
    {
      "name": "l06_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 6, per_line.fields.forcedBy"
    },
    {
      "name": "l06_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 6, per_line.fields.baselineCause"
    },
    {
      "name": "l07_usedLastWeek",
      "unit": "units a week",
      "formula": "line 7, per_line.fields.usedLastWeek"
    },
    {
      "name": "l07_weeksOfCover",
      "unit": "weeks",
      "formula": "line 7, per_line.fields.weeksOfCover"
    },
    {
      "name": "l07_orderUnits",
      "unit": "units",
      "formula": "line 7, per_line.fields.orderUnits"
    },
    {
      "name": "l07_orderPacks",
      "unit": "packs",
      "formula": "line 7, per_line.fields.orderPacks"
    },
    {
      "name": "l07_roundingExtraUnits",
      "unit": "units",
      "formula": "line 7, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l07_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 7, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l07_coverAfter",
      "unit": "weeks",
      "formula": "line 7, per_line.fields.coverAfter"
    },
    {
      "name": "l07_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 7, per_line.fields.verdict"
    },
    {
      "name": "l07_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 7, per_line.fields.forcedBy"
    },
    {
      "name": "l07_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 7, per_line.fields.baselineCause"
    },
    {
      "name": "l08_usedLastWeek",
      "unit": "units a week",
      "formula": "line 8, per_line.fields.usedLastWeek"
    },
    {
      "name": "l08_weeksOfCover",
      "unit": "weeks",
      "formula": "line 8, per_line.fields.weeksOfCover"
    },
    {
      "name": "l08_orderUnits",
      "unit": "units",
      "formula": "line 8, per_line.fields.orderUnits"
    },
    {
      "name": "l08_orderPacks",
      "unit": "packs",
      "formula": "line 8, per_line.fields.orderPacks"
    },
    {
      "name": "l08_roundingExtraUnits",
      "unit": "units",
      "formula": "line 8, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l08_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 8, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l08_coverAfter",
      "unit": "weeks",
      "formula": "line 8, per_line.fields.coverAfter"
    },
    {
      "name": "l08_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 8, per_line.fields.verdict"
    },
    {
      "name": "l08_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 8, per_line.fields.forcedBy"
    },
    {
      "name": "l08_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 8, per_line.fields.baselineCause"
    },
    {
      "name": "l09_usedLastWeek",
      "unit": "units a week",
      "formula": "line 9, per_line.fields.usedLastWeek"
    },
    {
      "name": "l09_weeksOfCover",
      "unit": "weeks",
      "formula": "line 9, per_line.fields.weeksOfCover"
    },
    {
      "name": "l09_orderUnits",
      "unit": "units",
      "formula": "line 9, per_line.fields.orderUnits"
    },
    {
      "name": "l09_orderPacks",
      "unit": "packs",
      "formula": "line 9, per_line.fields.orderPacks"
    },
    {
      "name": "l09_roundingExtraUnits",
      "unit": "units",
      "formula": "line 9, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l09_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 9, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l09_coverAfter",
      "unit": "weeks",
      "formula": "line 9, per_line.fields.coverAfter"
    },
    {
      "name": "l09_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 9, per_line.fields.verdict"
    },
    {
      "name": "l09_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 9, per_line.fields.forcedBy"
    },
    {
      "name": "l09_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 9, per_line.fields.baselineCause"
    },
    {
      "name": "l10_usedLastWeek",
      "unit": "units a week",
      "formula": "line 10, per_line.fields.usedLastWeek"
    },
    {
      "name": "l10_weeksOfCover",
      "unit": "weeks",
      "formula": "line 10, per_line.fields.weeksOfCover"
    },
    {
      "name": "l10_orderUnits",
      "unit": "units",
      "formula": "line 10, per_line.fields.orderUnits"
    },
    {
      "name": "l10_orderPacks",
      "unit": "packs",
      "formula": "line 10, per_line.fields.orderPacks"
    },
    {
      "name": "l10_roundingExtraUnits",
      "unit": "units",
      "formula": "line 10, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l10_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 10, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l10_coverAfter",
      "unit": "weeks",
      "formula": "line 10, per_line.fields.coverAfter"
    },
    {
      "name": "l10_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 10, per_line.fields.verdict"
    },
    {
      "name": "l10_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 10, per_line.fields.forcedBy"
    },
    {
      "name": "l10_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 10, per_line.fields.baselineCause"
    },
    {
      "name": "l11_usedLastWeek",
      "unit": "units a week",
      "formula": "line 11, per_line.fields.usedLastWeek"
    },
    {
      "name": "l11_weeksOfCover",
      "unit": "weeks",
      "formula": "line 11, per_line.fields.weeksOfCover"
    },
    {
      "name": "l11_orderUnits",
      "unit": "units",
      "formula": "line 11, per_line.fields.orderUnits"
    },
    {
      "name": "l11_orderPacks",
      "unit": "packs",
      "formula": "line 11, per_line.fields.orderPacks"
    },
    {
      "name": "l11_roundingExtraUnits",
      "unit": "units",
      "formula": "line 11, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l11_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 11, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l11_coverAfter",
      "unit": "weeks",
      "formula": "line 11, per_line.fields.coverAfter"
    },
    {
      "name": "l11_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 11, per_line.fields.verdict"
    },
    {
      "name": "l11_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 11, per_line.fields.forcedBy"
    },
    {
      "name": "l11_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 11, per_line.fields.baselineCause"
    },
    {
      "name": "l12_usedLastWeek",
      "unit": "units a week",
      "formula": "line 12, per_line.fields.usedLastWeek"
    },
    {
      "name": "l12_weeksOfCover",
      "unit": "weeks",
      "formula": "line 12, per_line.fields.weeksOfCover"
    },
    {
      "name": "l12_orderUnits",
      "unit": "units",
      "formula": "line 12, per_line.fields.orderUnits"
    },
    {
      "name": "l12_orderPacks",
      "unit": "packs",
      "formula": "line 12, per_line.fields.orderPacks"
    },
    {
      "name": "l12_roundingExtraUnits",
      "unit": "units",
      "formula": "line 12, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l12_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 12, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l12_coverAfter",
      "unit": "weeks",
      "formula": "line 12, per_line.fields.coverAfter"
    },
    {
      "name": "l12_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 12, per_line.fields.verdict"
    },
    {
      "name": "l12_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 12, per_line.fields.forcedBy"
    },
    {
      "name": "l12_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 12, per_line.fields.baselineCause"
    },
    {
      "name": "l13_usedLastWeek",
      "unit": "units a week",
      "formula": "line 13, per_line.fields.usedLastWeek"
    },
    {
      "name": "l13_weeksOfCover",
      "unit": "weeks",
      "formula": "line 13, per_line.fields.weeksOfCover"
    },
    {
      "name": "l13_orderUnits",
      "unit": "units",
      "formula": "line 13, per_line.fields.orderUnits"
    },
    {
      "name": "l13_orderPacks",
      "unit": "packs",
      "formula": "line 13, per_line.fields.orderPacks"
    },
    {
      "name": "l13_roundingExtraUnits",
      "unit": "units",
      "formula": "line 13, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l13_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 13, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l13_coverAfter",
      "unit": "weeks",
      "formula": "line 13, per_line.fields.coverAfter"
    },
    {
      "name": "l13_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 13, per_line.fields.verdict"
    },
    {
      "name": "l13_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 13, per_line.fields.forcedBy"
    },
    {
      "name": "l13_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 13, per_line.fields.baselineCause"
    },
    {
      "name": "l14_usedLastWeek",
      "unit": "units a week",
      "formula": "line 14, per_line.fields.usedLastWeek"
    },
    {
      "name": "l14_weeksOfCover",
      "unit": "weeks",
      "formula": "line 14, per_line.fields.weeksOfCover"
    },
    {
      "name": "l14_orderUnits",
      "unit": "units",
      "formula": "line 14, per_line.fields.orderUnits"
    },
    {
      "name": "l14_orderPacks",
      "unit": "packs",
      "formula": "line 14, per_line.fields.orderPacks"
    },
    {
      "name": "l14_roundingExtraUnits",
      "unit": "units",
      "formula": "line 14, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l14_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 14, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l14_coverAfter",
      "unit": "weeks",
      "formula": "line 14, per_line.fields.coverAfter"
    },
    {
      "name": "l14_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 14, per_line.fields.verdict"
    },
    {
      "name": "l14_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 14, per_line.fields.forcedBy"
    },
    {
      "name": "l14_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 14, per_line.fields.baselineCause"
    },
    {
      "name": "l15_usedLastWeek",
      "unit": "units a week",
      "formula": "line 15, per_line.fields.usedLastWeek"
    },
    {
      "name": "l15_weeksOfCover",
      "unit": "weeks",
      "formula": "line 15, per_line.fields.weeksOfCover"
    },
    {
      "name": "l15_orderUnits",
      "unit": "units",
      "formula": "line 15, per_line.fields.orderUnits"
    },
    {
      "name": "l15_orderPacks",
      "unit": "packs",
      "formula": "line 15, per_line.fields.orderPacks"
    },
    {
      "name": "l15_roundingExtraUnits",
      "unit": "units",
      "formula": "line 15, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l15_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 15, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l15_coverAfter",
      "unit": "weeks",
      "formula": "line 15, per_line.fields.coverAfter"
    },
    {
      "name": "l15_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 15, per_line.fields.verdict"
    },
    {
      "name": "l15_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 15, per_line.fields.forcedBy"
    },
    {
      "name": "l15_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 15, per_line.fields.baselineCause"
    },
    {
      "name": "l16_usedLastWeek",
      "unit": "units a week",
      "formula": "line 16, per_line.fields.usedLastWeek"
    },
    {
      "name": "l16_weeksOfCover",
      "unit": "weeks",
      "formula": "line 16, per_line.fields.weeksOfCover"
    },
    {
      "name": "l16_orderUnits",
      "unit": "units",
      "formula": "line 16, per_line.fields.orderUnits"
    },
    {
      "name": "l16_orderPacks",
      "unit": "packs",
      "formula": "line 16, per_line.fields.orderPacks"
    },
    {
      "name": "l16_roundingExtraUnits",
      "unit": "units",
      "formula": "line 16, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l16_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 16, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l16_coverAfter",
      "unit": "weeks",
      "formula": "line 16, per_line.fields.coverAfter"
    },
    {
      "name": "l16_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 16, per_line.fields.verdict"
    },
    {
      "name": "l16_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 16, per_line.fields.forcedBy"
    },
    {
      "name": "l16_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 16, per_line.fields.baselineCause"
    },
    {
      "name": "l17_usedLastWeek",
      "unit": "units a week",
      "formula": "line 17, per_line.fields.usedLastWeek"
    },
    {
      "name": "l17_weeksOfCover",
      "unit": "weeks",
      "formula": "line 17, per_line.fields.weeksOfCover"
    },
    {
      "name": "l17_orderUnits",
      "unit": "units",
      "formula": "line 17, per_line.fields.orderUnits"
    },
    {
      "name": "l17_orderPacks",
      "unit": "packs",
      "formula": "line 17, per_line.fields.orderPacks"
    },
    {
      "name": "l17_roundingExtraUnits",
      "unit": "units",
      "formula": "line 17, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l17_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 17, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l17_coverAfter",
      "unit": "weeks",
      "formula": "line 17, per_line.fields.coverAfter"
    },
    {
      "name": "l17_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 17, per_line.fields.verdict"
    },
    {
      "name": "l17_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 17, per_line.fields.forcedBy"
    },
    {
      "name": "l17_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 17, per_line.fields.baselineCause"
    },
    {
      "name": "l18_usedLastWeek",
      "unit": "units a week",
      "formula": "line 18, per_line.fields.usedLastWeek"
    },
    {
      "name": "l18_weeksOfCover",
      "unit": "weeks",
      "formula": "line 18, per_line.fields.weeksOfCover"
    },
    {
      "name": "l18_orderUnits",
      "unit": "units",
      "formula": "line 18, per_line.fields.orderUnits"
    },
    {
      "name": "l18_orderPacks",
      "unit": "packs",
      "formula": "line 18, per_line.fields.orderPacks"
    },
    {
      "name": "l18_roundingExtraUnits",
      "unit": "units",
      "formula": "line 18, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l18_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 18, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l18_coverAfter",
      "unit": "weeks",
      "formula": "line 18, per_line.fields.coverAfter"
    },
    {
      "name": "l18_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 18, per_line.fields.verdict"
    },
    {
      "name": "l18_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 18, per_line.fields.forcedBy"
    },
    {
      "name": "l18_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 18, per_line.fields.baselineCause"
    },
    {
      "name": "l19_usedLastWeek",
      "unit": "units a week",
      "formula": "line 19, per_line.fields.usedLastWeek"
    },
    {
      "name": "l19_weeksOfCover",
      "unit": "weeks",
      "formula": "line 19, per_line.fields.weeksOfCover"
    },
    {
      "name": "l19_orderUnits",
      "unit": "units",
      "formula": "line 19, per_line.fields.orderUnits"
    },
    {
      "name": "l19_orderPacks",
      "unit": "packs",
      "formula": "line 19, per_line.fields.orderPacks"
    },
    {
      "name": "l19_roundingExtraUnits",
      "unit": "units",
      "formula": "line 19, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l19_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 19, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l19_coverAfter",
      "unit": "weeks",
      "formula": "line 19, per_line.fields.coverAfter"
    },
    {
      "name": "l19_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 19, per_line.fields.verdict"
    },
    {
      "name": "l19_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 19, per_line.fields.forcedBy"
    },
    {
      "name": "l19_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 19, per_line.fields.baselineCause"
    },
    {
      "name": "l20_usedLastWeek",
      "unit": "units a week",
      "formula": "line 20, per_line.fields.usedLastWeek"
    },
    {
      "name": "l20_weeksOfCover",
      "unit": "weeks",
      "formula": "line 20, per_line.fields.weeksOfCover"
    },
    {
      "name": "l20_orderUnits",
      "unit": "units",
      "formula": "line 20, per_line.fields.orderUnits"
    },
    {
      "name": "l20_orderPacks",
      "unit": "packs",
      "formula": "line 20, per_line.fields.orderPacks"
    },
    {
      "name": "l20_roundingExtraUnits",
      "unit": "units",
      "formula": "line 20, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l20_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 20, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l20_coverAfter",
      "unit": "weeks",
      "formula": "line 20, per_line.fields.coverAfter"
    },
    {
      "name": "l20_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 20, per_line.fields.verdict"
    },
    {
      "name": "l20_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 20, per_line.fields.forcedBy"
    },
    {
      "name": "l20_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 20, per_line.fields.baselineCause"
    },
    {
      "name": "l21_usedLastWeek",
      "unit": "units a week",
      "formula": "line 21, per_line.fields.usedLastWeek"
    },
    {
      "name": "l21_weeksOfCover",
      "unit": "weeks",
      "formula": "line 21, per_line.fields.weeksOfCover"
    },
    {
      "name": "l21_orderUnits",
      "unit": "units",
      "formula": "line 21, per_line.fields.orderUnits"
    },
    {
      "name": "l21_orderPacks",
      "unit": "packs",
      "formula": "line 21, per_line.fields.orderPacks"
    },
    {
      "name": "l21_roundingExtraUnits",
      "unit": "units",
      "formula": "line 21, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l21_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 21, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l21_coverAfter",
      "unit": "weeks",
      "formula": "line 21, per_line.fields.coverAfter"
    },
    {
      "name": "l21_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 21, per_line.fields.verdict"
    },
    {
      "name": "l21_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 21, per_line.fields.forcedBy"
    },
    {
      "name": "l21_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 21, per_line.fields.baselineCause"
    },
    {
      "name": "l22_usedLastWeek",
      "unit": "units a week",
      "formula": "line 22, per_line.fields.usedLastWeek"
    },
    {
      "name": "l22_weeksOfCover",
      "unit": "weeks",
      "formula": "line 22, per_line.fields.weeksOfCover"
    },
    {
      "name": "l22_orderUnits",
      "unit": "units",
      "formula": "line 22, per_line.fields.orderUnits"
    },
    {
      "name": "l22_orderPacks",
      "unit": "packs",
      "formula": "line 22, per_line.fields.orderPacks"
    },
    {
      "name": "l22_roundingExtraUnits",
      "unit": "units",
      "formula": "line 22, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l22_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 22, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l22_coverAfter",
      "unit": "weeks",
      "formula": "line 22, per_line.fields.coverAfter"
    },
    {
      "name": "l22_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 22, per_line.fields.verdict"
    },
    {
      "name": "l22_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 22, per_line.fields.forcedBy"
    },
    {
      "name": "l22_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 22, per_line.fields.baselineCause"
    },
    {
      "name": "l23_usedLastWeek",
      "unit": "units a week",
      "formula": "line 23, per_line.fields.usedLastWeek"
    },
    {
      "name": "l23_weeksOfCover",
      "unit": "weeks",
      "formula": "line 23, per_line.fields.weeksOfCover"
    },
    {
      "name": "l23_orderUnits",
      "unit": "units",
      "formula": "line 23, per_line.fields.orderUnits"
    },
    {
      "name": "l23_orderPacks",
      "unit": "packs",
      "formula": "line 23, per_line.fields.orderPacks"
    },
    {
      "name": "l23_roundingExtraUnits",
      "unit": "units",
      "formula": "line 23, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l23_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 23, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l23_coverAfter",
      "unit": "weeks",
      "formula": "line 23, per_line.fields.coverAfter"
    },
    {
      "name": "l23_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 23, per_line.fields.verdict"
    },
    {
      "name": "l23_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 23, per_line.fields.forcedBy"
    },
    {
      "name": "l23_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 23, per_line.fields.baselineCause"
    },
    {
      "name": "l24_usedLastWeek",
      "unit": "units a week",
      "formula": "line 24, per_line.fields.usedLastWeek"
    },
    {
      "name": "l24_weeksOfCover",
      "unit": "weeks",
      "formula": "line 24, per_line.fields.weeksOfCover"
    },
    {
      "name": "l24_orderUnits",
      "unit": "units",
      "formula": "line 24, per_line.fields.orderUnits"
    },
    {
      "name": "l24_orderPacks",
      "unit": "packs",
      "formula": "line 24, per_line.fields.orderPacks"
    },
    {
      "name": "l24_roundingExtraUnits",
      "unit": "units",
      "formula": "line 24, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l24_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 24, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l24_coverAfter",
      "unit": "weeks",
      "formula": "line 24, per_line.fields.coverAfter"
    },
    {
      "name": "l24_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 24, per_line.fields.verdict"
    },
    {
      "name": "l24_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 24, per_line.fields.forcedBy"
    },
    {
      "name": "l24_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 24, per_line.fields.baselineCause"
    },
    {
      "name": "l25_usedLastWeek",
      "unit": "units a week",
      "formula": "line 25, per_line.fields.usedLastWeek"
    },
    {
      "name": "l25_weeksOfCover",
      "unit": "weeks",
      "formula": "line 25, per_line.fields.weeksOfCover"
    },
    {
      "name": "l25_orderUnits",
      "unit": "units",
      "formula": "line 25, per_line.fields.orderUnits"
    },
    {
      "name": "l25_orderPacks",
      "unit": "packs",
      "formula": "line 25, per_line.fields.orderPacks"
    },
    {
      "name": "l25_roundingExtraUnits",
      "unit": "units",
      "formula": "line 25, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l25_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 25, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l25_coverAfter",
      "unit": "weeks",
      "formula": "line 25, per_line.fields.coverAfter"
    },
    {
      "name": "l25_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 25, per_line.fields.verdict"
    },
    {
      "name": "l25_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 25, per_line.fields.forcedBy"
    },
    {
      "name": "l25_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 25, per_line.fields.baselineCause"
    },
    {
      "name": "l26_usedLastWeek",
      "unit": "units a week",
      "formula": "line 26, per_line.fields.usedLastWeek"
    },
    {
      "name": "l26_weeksOfCover",
      "unit": "weeks",
      "formula": "line 26, per_line.fields.weeksOfCover"
    },
    {
      "name": "l26_orderUnits",
      "unit": "units",
      "formula": "line 26, per_line.fields.orderUnits"
    },
    {
      "name": "l26_orderPacks",
      "unit": "packs",
      "formula": "line 26, per_line.fields.orderPacks"
    },
    {
      "name": "l26_roundingExtraUnits",
      "unit": "units",
      "formula": "line 26, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l26_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 26, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l26_coverAfter",
      "unit": "weeks",
      "formula": "line 26, per_line.fields.coverAfter"
    },
    {
      "name": "l26_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 26, per_line.fields.verdict"
    },
    {
      "name": "l26_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 26, per_line.fields.forcedBy"
    },
    {
      "name": "l26_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 26, per_line.fields.baselineCause"
    },
    {
      "name": "l27_usedLastWeek",
      "unit": "units a week",
      "formula": "line 27, per_line.fields.usedLastWeek"
    },
    {
      "name": "l27_weeksOfCover",
      "unit": "weeks",
      "formula": "line 27, per_line.fields.weeksOfCover"
    },
    {
      "name": "l27_orderUnits",
      "unit": "units",
      "formula": "line 27, per_line.fields.orderUnits"
    },
    {
      "name": "l27_orderPacks",
      "unit": "packs",
      "formula": "line 27, per_line.fields.orderPacks"
    },
    {
      "name": "l27_roundingExtraUnits",
      "unit": "units",
      "formula": "line 27, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l27_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 27, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l27_coverAfter",
      "unit": "weeks",
      "formula": "line 27, per_line.fields.coverAfter"
    },
    {
      "name": "l27_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 27, per_line.fields.verdict"
    },
    {
      "name": "l27_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 27, per_line.fields.forcedBy"
    },
    {
      "name": "l27_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 27, per_line.fields.baselineCause"
    },
    {
      "name": "l28_usedLastWeek",
      "unit": "units a week",
      "formula": "line 28, per_line.fields.usedLastWeek"
    },
    {
      "name": "l28_weeksOfCover",
      "unit": "weeks",
      "formula": "line 28, per_line.fields.weeksOfCover"
    },
    {
      "name": "l28_orderUnits",
      "unit": "units",
      "formula": "line 28, per_line.fields.orderUnits"
    },
    {
      "name": "l28_orderPacks",
      "unit": "packs",
      "formula": "line 28, per_line.fields.orderPacks"
    },
    {
      "name": "l28_roundingExtraUnits",
      "unit": "units",
      "formula": "line 28, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l28_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 28, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l28_coverAfter",
      "unit": "weeks",
      "formula": "line 28, per_line.fields.coverAfter"
    },
    {
      "name": "l28_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 28, per_line.fields.verdict"
    },
    {
      "name": "l28_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 28, per_line.fields.forcedBy"
    },
    {
      "name": "l28_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 28, per_line.fields.baselineCause"
    },
    {
      "name": "l29_usedLastWeek",
      "unit": "units a week",
      "formula": "line 29, per_line.fields.usedLastWeek"
    },
    {
      "name": "l29_weeksOfCover",
      "unit": "weeks",
      "formula": "line 29, per_line.fields.weeksOfCover"
    },
    {
      "name": "l29_orderUnits",
      "unit": "units",
      "formula": "line 29, per_line.fields.orderUnits"
    },
    {
      "name": "l29_orderPacks",
      "unit": "packs",
      "formula": "line 29, per_line.fields.orderPacks"
    },
    {
      "name": "l29_roundingExtraUnits",
      "unit": "units",
      "formula": "line 29, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l29_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 29, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l29_coverAfter",
      "unit": "weeks",
      "formula": "line 29, per_line.fields.coverAfter"
    },
    {
      "name": "l29_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 29, per_line.fields.verdict"
    },
    {
      "name": "l29_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 29, per_line.fields.forcedBy"
    },
    {
      "name": "l29_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 29, per_line.fields.baselineCause"
    },
    {
      "name": "l30_usedLastWeek",
      "unit": "units a week",
      "formula": "line 30, per_line.fields.usedLastWeek"
    },
    {
      "name": "l30_weeksOfCover",
      "unit": "weeks",
      "formula": "line 30, per_line.fields.weeksOfCover"
    },
    {
      "name": "l30_orderUnits",
      "unit": "units",
      "formula": "line 30, per_line.fields.orderUnits"
    },
    {
      "name": "l30_orderPacks",
      "unit": "packs",
      "formula": "line 30, per_line.fields.orderPacks"
    },
    {
      "name": "l30_roundingExtraUnits",
      "unit": "units",
      "formula": "line 30, per_line.fields.roundingExtraUnits"
    },
    {
      "name": "l30_supplierMinExtraUnits",
      "unit": "units",
      "formula": "line 30, per_line.fields.supplierMinExtraUnits"
    },
    {
      "name": "l30_coverAfter",
      "unit": "weeks",
      "formula": "line 30, per_line.fields.coverAfter"
    },
    {
      "name": "l30_verdict",
      "unit": "no-order, order, forced, no-usage or no-baseline",
      "formula": "line 30, per_line.fields.verdict"
    },
    {
      "name": "l30_forcedBy",
      "unit": "null, parFloor, pack, supplierMin, or those joined with +",
      "formula": "line 30, per_line.fields.forcedBy"
    },
    {
      "name": "l30_baselineCause",
      "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
      "formula": "line 30, per_line.fields.baselineCause"
    }
  ],
  "formula": [
    "for each of the first lineCount lines, with every input normalised as the rounding block above says:",
    "usedLastWeek = lastCount + received - countedNow, and it is NOT returned at all unless all three figures are known and the result is not negative. A blank countedNow, a blank lastCount and a blank received are three different ways for one of the three not to be known, and none of them is read as the figure 0",
    "baselineCause = 'not-counted' when countedNow is blank; else 'no-last-count' when lastCount is blank; else 'received-unknown' when received is blank; else 'count-rose' when lastCount + received - countedNow is below nil; else null. The count taken now is tested FIRST because it is the figure the other two are measured against: a line nobody counted this week has nothing to compare, whatever else it carries",
    "weeksOfCover = countedNow / usedLastWeek, to one decimal, and null when usedLastWeek is nil, because a line that used nothing has no weeks on hand",
    "coverWeeksWanted = targetCoverWeeks + leadTimeDays / 7",
    "coverWantedUnits = ceil(round(usedLastWeek x coverWeeksWanted, 6)) - the product is read to SIX DECIMALS before the ceiling is taken, and that rounding is part of the calculation rather than a tidy-up. usedLastWeek x (targetCoverWeeks + leadTimeDays / 7) is a rational whose denominator divides 14, so its true distance from a whole number is either nil or at least one fourteenth: a residue of a millionth is binary floating point in the machine and never a part of a unit, and a ceiling taken on it adds a unit to the order that the arithmetic does not call for. An implementation without this read differs from the page on about one state in thirteen, and on ordinary shop figures - a usage of 1 to 60 units a week against every target cover and lead time the form offers - on 413 of 87,840 combinations: usage 7 a week, target 4 weeks, lead 1 day gives 29 units with the read and 30 without it",
    "coverShortfall = max(0, coverWantedUnits - countedNow)",
    "floorShortfall = max(0, parFloor - countedNow)",
    "needUnits = max(coverShortfall, floorShortfall)",
    "packs = needUnits > 0 ? ceil(needUnits / packSize) : 0, and packUnits = packs x packSize",
    "roundingExtraUnits = packUnits - needUnits",
    "supplierMinUnits = (needUnits > 0 and supplierMin > 0) ? ceil(supplierMin / packSize) x packSize : 0",
    "orderPacks = max(packs, supplierMinUnits / packSize), and orderUnits = orderPacks x packSize",
    "supplierMinExtraUnits = orderUnits - packUnits",
    "coverAfter = (countedNow + orderUnits) / usedLastWeek, to one decimal, and null when usedLastWeek is nil",
    "forcedBy = the reasons the order was decided by something other than the cover shortfall, in this order and joined with '+': 'parFloor' when floorShortfall is above coverShortfall, 'pack' when packSize is above needUnits, 'supplierMin' when supplierMinExtraUnits is above nil; null when none of them applies or when needUnits is nil. A reason being named does NOT mean orderUnits is above needUnits: step 8 makes needUnits the LARGER of the two shortfalls, so where the floor decides the size the floor IS the week's need and a 'parFloor' line can order exactly needUnits (49 line-states of the page's own 4,662-state sweep do, 36 of them on a 'no-usage' line and 13 on a 'forced' one; at a pack size of 1, which is what a blank pack-size box reads as, every floor-decided line does). 'pack' and 'supplierMin' each do put orderUnits above needUnits, by roundingExtraUnits and supplierMinExtraUnits respectively",
    "verdict = 'no-baseline' when usedLastWeek is not known; else 'no-usage' when usedLastWeek is nil; else 'no-order' when orderUnits is nil; else 'forced' when forcedBy is not null; else 'order'",
    "waitingLines = the count of lines whose verdict is 'no-baseline'; usableLines = lineCount - waitingLines; incomplete = waitingLines > 0",
    "linesToOrder, totalUnits and totalPacks are the count of lines with an order, the sum of orderUnits and the sum of orderPacks over the lines that are not 'no-baseline' - and all three are returned as null while incomplete is true, because a total that leaves a line out understates the order"
  ],
  "identities": [
    "orderUnits = orderPacks x packSize on every line, always: an order is a whole number of packs",
    "orderUnits - needUnits = roundingExtraUnits + supplierMinExtraUnits on every line with a need: the two amounts above the week's need account for all of it, and neither is ever folded into the other",
    "roundingExtraUnits is below packSize on every line with a need: rounding up to the next pack cannot add a whole pack",
    "orderUnits is at least supplierMin on every line with a need, and at least needUnits on every line"
  ],
  "example": {
    "note": "The sheet this page ships filled in: eight lines from a small pet-supply shop, one of them with the week's delivery recorded only as a single shipment total, one counted for the first time, and one whose count rose with no delivery recorded. apiOutputs returns all 307 fields for this request; the 220 names for lines 9 to 30 are null on it, because nothing is typed on those lines, and they are left out of the answer below for length rather than being absent from the answer itself. So a caller comparing key sets against this block should expect 87 keys here and 307 from the endpoint.",
    "inputs": {
      "lineCount": 8,
      "lines": [
        {
          "name": "Dog food 15kg bags",
          "countedNow": 42,
          "lastCount": 50,
          "received": null,
          "targetCoverWeeks": 3,
          "parFloor": 0,
          "leadTimeDays": 5,
          "packSize": 10,
          "supplierMin": 0
        },
        {
          "name": "Cat litter 20lb",
          "countedNow": 30,
          "lastCount": 40,
          "received": 15,
          "targetCoverWeeks": 2.5,
          "parFloor": 0,
          "leadTimeDays": 3,
          "packSize": 12,
          "supplierMin": 0
        },
        {
          "name": "Dog treats small bags",
          "countedNow": 15,
          "lastCount": 20,
          "received": 5,
          "targetCoverWeeks": 2,
          "parFloor": 0,
          "leadTimeDays": 7,
          "packSize": 24,
          "supplierMin": 48
        },
        {
          "name": "Cat food cans by the case",
          "countedNow": 15,
          "lastCount": 15,
          "received": 0,
          "targetCoverWeeks": 4,
          "parFloor": 24,
          "leadTimeDays": 10,
          "packSize": 12,
          "supplierMin": 0
        },
        {
          "name": "Puppy pads",
          "countedNow": 100,
          "lastCount": 70,
          "received": 0,
          "targetCoverWeeks": 3,
          "parFloor": 0,
          "leadTimeDays": 7,
          "packSize": 20,
          "supplierMin": 0
        },
        {
          "name": "Bird seed 5kg",
          "countedNow": 5,
          "lastCount": null,
          "received": 0,
          "targetCoverWeeks": 4,
          "parFloor": 0,
          "leadTimeDays": 10,
          "packSize": 6,
          "supplierMin": 0
        },
        {
          "name": "Fish food flakes",
          "countedNow": 18,
          "lastCount": 25,
          "received": 10,
          "targetCoverWeeks": 6,
          "parFloor": 0,
          "leadTimeDays": 10,
          "packSize": 6,
          "supplierMin": 0
        },
        {
          "name": "Aquarium filter cartridges",
          "countedNow": 50,
          "lastCount": 55,
          "received": 0,
          "targetCoverWeeks": 8,
          "parFloor": 0,
          "leadTimeDays": 14,
          "packSize": 1,
          "supplierMin": 0
        }
      ]
    },
    "outputs": {
      "sheetLines": 8,
      "usableLines": 5,
      "waitingLines": 3,
      "incomplete": true,
      "linesToOrder": null,
      "totalUnits": null,
      "totalPacks": null,
      "l01_usedLastWeek": null,
      "l01_weeksOfCover": null,
      "l01_orderUnits": null,
      "l01_orderPacks": null,
      "l01_roundingExtraUnits": null,
      "l01_supplierMinExtraUnits": null,
      "l01_coverAfter": null,
      "l01_verdict": "no-baseline",
      "l01_forcedBy": null,
      "l01_baselineCause": "received-unknown",
      "l02_usedLastWeek": 25,
      "l02_weeksOfCover": 1.2,
      "l02_orderUnits": 48,
      "l02_orderPacks": 4,
      "l02_roundingExtraUnits": 4,
      "l02_supplierMinExtraUnits": 0,
      "l02_coverAfter": 3.1,
      "l02_verdict": "order",
      "l02_forcedBy": null,
      "l02_baselineCause": null,
      "l03_usedLastWeek": 10,
      "l03_weeksOfCover": 1.5,
      "l03_orderUnits": 48,
      "l03_orderPacks": 2,
      "l03_roundingExtraUnits": 9,
      "l03_supplierMinExtraUnits": 24,
      "l03_coverAfter": 6.3,
      "l03_verdict": "forced",
      "l03_forcedBy": "pack+supplierMin",
      "l03_baselineCause": null,
      "l04_usedLastWeek": 0,
      "l04_weeksOfCover": null,
      "l04_orderUnits": 12,
      "l04_orderPacks": 1,
      "l04_roundingExtraUnits": 3,
      "l04_supplierMinExtraUnits": 0,
      "l04_coverAfter": null,
      "l04_verdict": "no-usage",
      "l04_forcedBy": "parFloor+pack",
      "l04_baselineCause": null,
      "l05_usedLastWeek": null,
      "l05_weeksOfCover": null,
      "l05_orderUnits": null,
      "l05_orderPacks": null,
      "l05_roundingExtraUnits": null,
      "l05_supplierMinExtraUnits": null,
      "l05_coverAfter": null,
      "l05_verdict": "no-baseline",
      "l05_forcedBy": null,
      "l05_baselineCause": "count-rose",
      "l06_usedLastWeek": null,
      "l06_weeksOfCover": null,
      "l06_orderUnits": null,
      "l06_orderPacks": null,
      "l06_roundingExtraUnits": null,
      "l06_supplierMinExtraUnits": null,
      "l06_coverAfter": null,
      "l06_verdict": "no-baseline",
      "l06_forcedBy": null,
      "l06_baselineCause": "no-last-count",
      "l07_usedLastWeek": 17,
      "l07_weeksOfCover": 1.1,
      "l07_orderUnits": 114,
      "l07_orderPacks": 19,
      "l07_roundingExtraUnits": 5,
      "l07_supplierMinExtraUnits": 0,
      "l07_coverAfter": 7.8,
      "l07_verdict": "order",
      "l07_forcedBy": null,
      "l07_baselineCause": null,
      "l08_usedLastWeek": 5,
      "l08_weeksOfCover": 10,
      "l08_orderUnits": 0,
      "l08_orderPacks": 0,
      "l08_roundingExtraUnits": 0,
      "l08_supplierMinExtraUnits": 0,
      "l08_coverAfter": 10,
      "l08_verdict": "no-order",
      "l08_forcedBy": null,
      "l08_baselineCause": null
    },
    "reading": "Three of the eight lines have no usage figure, so incomplete is true and all three week totals are null. Over the five lines that do have one: line 2 orders 48 units in 4 packs with 4 units of that being pack rounding; line 3 needs 15 units and orders 48, because one case of 24 is already past the need and the supplier will not take an order below 48, which is two whole cases; line 4 used nothing, so its weeks on hand is null and its floor of 24 is the only basis for its order of 12; line 7 orders 114 units in 19 packs; line 8 holds ten weeks and orders nothing."
  },
  "not_covered": [
    "Prices, costs, the value of the inventory, and anything about cash: this calculation holds no money figure at all.",
    "Demand: the usage figure is one week measured against the week before, and nothing here models seasonality, a promotion, a trend or a line whose sales swing week to week. More weeks than one sheet holds are needed before a usage figure means much.",
    "An economic order quantity. EOQ rests on an ordering cost and a holding cost per unit; this calculation has neither and cannot check the assumptions behind them for the caller, so it does not compute one and does not call any order quantity optimal.",
    "Shelf life, batch and expiry, a supplier who is themselves out of stock, a part order, a back order, and a delivery that arrives after the count was taken but before the order is placed.",
    "Splitting one shipment total across lines. A total discards which units were which; the calculation asks for the figure per line or marks the line as not known."
  ],
  "no_advice": "This is inventory arithmetic over counts the caller took themselves. The word 'stock' here means units on a shelf and never a share or a security: nothing in this calculation touches investments, financial products, tax or any licensed activity, and it gives no business advice. It sets no floor, no target cover and no lead time for anybody; those are figures the caller types.",
  "per_line": {
    "note": "Ten fields are returned for each of the thirty lines the form offers, named l01_ to l30_ with the field name after the underscore. Every one of them is null on a line past lineCount, so the shape of the answer does not change with the size of the sheet. On a line whose usage figure cannot be derived - verdict 'no-baseline', baselineCause not null - SEVEN of the ten are null together: usedLastWeek, weeksOfCover, orderUnits, orderPacks, roundingExtraUnits, supplierMinExtraUnits and coverAfter. Only verdict and baselineCause carry a value, and forcedBy is null because nothing was ordered to force. A line that used nothing (verdict 'no-usage') returns a figure for every field except weeksOfCover and coverAfter, which are null because a count over a usage of nothing is not a number.",
    "fields": {
      "usedLastWeek": {
        "unit": "units a week",
        "formula": "lastCount + received - countedNow; null on every 'no-baseline' line, which is any line where one of those three is blank or where the result would be negative"
      },
      "weeksOfCover": {
        "unit": "weeks",
        "formula": "countedNow / usedLastWeek to one decimal; null where usedLastWeek is nil or not known"
      },
      "orderUnits": {
        "unit": "units",
        "formula": "orderPacks x packSize; null on every 'no-baseline' line"
      },
      "orderPacks": {
        "unit": "packs",
        "formula": "max(packs, supplierMinUnits / packSize); null on every 'no-baseline' line"
      },
      "roundingExtraUnits": {
        "unit": "units",
        "formula": "packUnits - needUnits, never summed with the supplier minimum; null on every 'no-baseline' line"
      },
      "supplierMinExtraUnits": {
        "unit": "units",
        "formula": "orderUnits - packUnits, kept apart from the pack rounding; null on every 'no-baseline' line"
      },
      "coverAfter": {
        "unit": "weeks",
        "formula": "(countedNow + orderUnits) / usedLastWeek to one decimal; null where usedLastWeek is nil or not known"
      },
      "verdict": {
        "unit": "no-order, order, forced, no-usage or no-baseline",
        "formula": "the five states, as the formula block defines them"
      },
      "forcedBy": {
        "unit": "null, parFloor, pack, supplierMin, or those joined with +",
        "formula": "which of the three things decided the order instead of the cover shortfall, joined with '+' where more than one did; a 'parFloor' line can order exactly needUnits, so a named reason does not imply an order above the week's need - see formula step 16"
      },
      "baselineCause": {
        "unit": "null, not-counted, no-last-count, received-unknown or count-rose",
        "formula": "why the usage figure could not be derived, naming which of the three figures is missing or that the two counts disagree; null on a line that has one"
      }
    }
  }
}
