Functional Weave
Code in Python

inventory.abc-classification@1.0.0

vectors.json

9,567 bytes · view raw

[
  {"name": "80/15/5 over ten items: P3 ends exactly on 80% and is A, P4 starts on 80% and is B, P6 starts at 94.5% and is still B; P6 and P7 tie and rank by sku", "args": [[{"sku": "P7", "annualQuantity": 1000, "unitCost": {"minor": 20, "currency": "GBP"}}, {"sku": "P10", "annualQuantity": 15, "unitCost": {"minor": 1000, "currency": "GBP"}}, {"sku": "P3", "annualQuantity": 500, "unitCost": {"minor": 200, "currency": "GBP"}}, {"sku": "P1", "annualQuantity": 1000, "unitCost": {"minor": 500, "currency": "GBP"}}, {"sku": "P9", "annualQuantity": 250, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "P5", "annualQuantity": 300, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "P6", "annualQuantity": 50, "unitCost": {"minor": 400, "currency": "GBP"}}, {"sku": "P2", "annualQuantity": 200, "unitCost": {"minor": 1000, "currency": "GBP"}}, {"sku": "P8", "annualQuantity": 400, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "P4", "annualQuantity": 100, "unitCost": {"minor": 500, "currency": "GBP"}}], [8000, 9500]], "expect": [{"sku": "P1", "annualValue": {"minor": 500000, "currency": "GBP"}, "rank": 1, "cumulativeBasisPoints": 5000, "abcClass": "A"}, {"sku": "P2", "annualValue": {"minor": 200000, "currency": "GBP"}, "rank": 2, "cumulativeBasisPoints": 7000, "abcClass": "A"}, {"sku": "P3", "annualValue": {"minor": 100000, "currency": "GBP"}, "rank": 3, "cumulativeBasisPoints": 8000, "abcClass": "A"}, {"sku": "P4", "annualValue": {"minor": 50000, "currency": "GBP"}, "rank": 4, "cumulativeBasisPoints": 8500, "abcClass": "B"}, {"sku": "P8", "annualValue": {"minor": 40000, "currency": "GBP"}, "rank": 5, "cumulativeBasisPoints": 8900, "abcClass": "B"}, {"sku": "P5", "annualValue": {"minor": 30000, "currency": "GBP"}, "rank": 6, "cumulativeBasisPoints": 9200, "abcClass": "B"}, {"sku": "P9", "annualValue": {"minor": 25000, "currency": "GBP"}, "rank": 7, "cumulativeBasisPoints": 9450, "abcClass": "B"}, {"sku": "P6", "annualValue": {"minor": 20000, "currency": "GBP"}, "rank": 8, "cumulativeBasisPoints": 9650, "abcClass": "B"}, {"sku": "P7", "annualValue": {"minor": 20000, "currency": "GBP"}, "rank": 9, "cumulativeBasisPoints": 9850, "abcClass": "C"}, {"sku": "P10", "annualValue": {"minor": 15000, "currency": "GBP"}, "rank": 10, "cumulativeBasisPoints": 10000, "abcClass": "C"}]},
  {"name": "four classes from three cut-offs: P6 starts at 94.5%, so C, and P7 at 96.5%, so D", "args": [[{"sku": "P7", "annualQuantity": 1000, "unitCost": {"minor": 20, "currency": "GBP"}}, {"sku": "P10", "annualQuantity": 15, "unitCost": {"minor": 1000, "currency": "GBP"}}, {"sku": "P3", "annualQuantity": 500, "unitCost": {"minor": 200, "currency": "GBP"}}, {"sku": "P1", "annualQuantity": 1000, "unitCost": {"minor": 500, "currency": "GBP"}}, {"sku": "P9", "annualQuantity": 250, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "P5", "annualQuantity": 300, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "P6", "annualQuantity": 50, "unitCost": {"minor": 400, "currency": "GBP"}}, {"sku": "P2", "annualQuantity": 200, "unitCost": {"minor": 1000, "currency": "GBP"}}, {"sku": "P8", "annualQuantity": 400, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "P4", "annualQuantity": 100, "unitCost": {"minor": 500, "currency": "GBP"}}], [5000, 8000, 9500]], "expect": [{"sku": "P1", "annualValue": {"minor": 500000, "currency": "GBP"}, "rank": 1, "cumulativeBasisPoints": 5000, "abcClass": "A"}, {"sku": "P2", "annualValue": {"minor": 200000, "currency": "GBP"}, "rank": 2, "cumulativeBasisPoints": 7000, "abcClass": "B"}, {"sku": "P3", "annualValue": {"minor": 100000, "currency": "GBP"}, "rank": 3, "cumulativeBasisPoints": 8000, "abcClass": "B"}, {"sku": "P4", "annualValue": {"minor": 50000, "currency": "GBP"}, "rank": 4, "cumulativeBasisPoints": 8500, "abcClass": "C"}, {"sku": "P8", "annualValue": {"minor": 40000, "currency": "GBP"}, "rank": 5, "cumulativeBasisPoints": 8900, "abcClass": "C"}, {"sku": "P5", "annualValue": {"minor": 30000, "currency": "GBP"}, "rank": 6, "cumulativeBasisPoints": 9200, "abcClass": "C"}, {"sku": "P9", "annualValue": {"minor": 25000, "currency": "GBP"}, "rank": 7, "cumulativeBasisPoints": 9450, "abcClass": "C"}, {"sku": "P6", "annualValue": {"minor": 20000, "currency": "GBP"}, "rank": 8, "cumulativeBasisPoints": 9650, "abcClass": "C"}, {"sku": "P7", "annualValue": {"minor": 20000, "currency": "GBP"}, "rank": 9, "cumulativeBasisPoints": 9850, "abcClass": "D"}, {"sku": "P10", "annualValue": {"minor": 15000, "currency": "GBP"}, "rank": 10, "cumulativeBasisPoints": 10000, "abcClass": "D"}]},
  {"name": "one item holding 90% is A, not B, and the next starts at 90% so it is B", "args": [[{"sku": "SMALL", "annualQuantity": 1, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "BIG", "annualQuantity": 9, "unitCost": {"minor": 100, "currency": "GBP"}}], [8000, 9500]], "expect": [{"sku": "BIG", "annualValue": {"minor": 900, "currency": "GBP"}, "rank": 1, "cumulativeBasisPoints": 9000, "abcClass": "A"}, {"sku": "SMALL", "annualValue": {"minor": 100, "currency": "GBP"}, "rank": 2, "cumulativeBasisPoints": 10000, "abcClass": "B"}]},
  {"name": "a single item is A with the whole value", "args": [[{"sku": "ONLY", "annualQuantity": 3, "unitCost": {"minor": 250, "currency": "EUR"}}], [8000, 9500]], "expect": [{"sku": "ONLY", "annualValue": {"minor": 750, "currency": "EUR"}, "rank": 1, "cumulativeBasisPoints": 10000, "abcClass": "A"}]},
  {"name": "items with no value fall in the last class, ranked by sku", "args": [[{"sku": "B", "annualQuantity": 0, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "A", "annualQuantity": 5, "unitCost": {"minor": 0, "currency": "GBP"}}, {"sku": "C", "annualQuantity": 2, "unitCost": {"minor": 50, "currency": "GBP"}}], [8000, 9500]], "expect": [{"sku": "C", "annualValue": {"minor": 100, "currency": "GBP"}, "rank": 1, "cumulativeBasisPoints": 10000, "abcClass": "A"}, {"sku": "A", "annualValue": {"minor": 0, "currency": "GBP"}, "rank": 2, "cumulativeBasisPoints": 10000, "abcClass": "C"}, {"sku": "B", "annualValue": {"minor": 0, "currency": "GBP"}, "rank": 3, "cumulativeBasisPoints": 10000, "abcClass": "C"}]},
  {"name": "when nothing has value everything is in the last class", "args": [[{"sku": "Y", "annualQuantity": 0, "unitCost": {"minor": 100, "currency": "GBP"}}, {"sku": "X", "annualQuantity": 0, "unitCost": {"minor": 100, "currency": "GBP"}}], [8000, 9500]], "expect": [{"sku": "X", "annualValue": {"minor": 0, "currency": "GBP"}, "rank": 1, "cumulativeBasisPoints": 0, "abcClass": "C"}, {"sku": "Y", "annualValue": {"minor": 0, "currency": "GBP"}, "rank": 2, "cumulativeBasisPoints": 0, "abcClass": "C"}]},
  {"name": "cumulative share rounds half-up for display (3333, 6667); the class uses the exact share, and C starts at 2/3, past 60%", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}, {"sku": "B", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}, {"sku": "C", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}], [6000]], "expect": [{"sku": "A", "annualValue": {"minor": 1, "currency": "GBP"}, "rank": 1, "cumulativeBasisPoints": 3333, "abcClass": "A"}, {"sku": "B", "annualValue": {"minor": 1, "currency": "GBP"}, "rank": 2, "cumulativeBasisPoints": 6667, "abcClass": "A"}, {"sku": "C", "annualValue": {"minor": 1, "currency": "GBP"}, "rank": 3, "cumulativeBasisPoints": 10000, "abcClass": "B"}]},
  {"name": "an empty list is an empty ranking", "args": [[], [8000, 9500]], "expect": []},
  {"name": "a duplicate sku is an error", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}, {"sku": "A", "annualQuantity": 2, "unitCost": {"minor": 1, "currency": "GBP"}}], [8000, 9500]], "expectError": "duplicate sku \"A\""},
  {"name": "cut-offs out of order are an error", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}], [9500, 8000]], "expectError": "cutoffBasisPoints must ascend strictly within 1..9999"},
  {"name": "a cut-off of 100% is an error", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}], [8000, 10000]], "expectError": "cutoffBasisPoints must ascend strictly within 1..9999"},
  {"name": "no cut-offs is an error", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}], []], "expectError": "cutoffBasisPoints needs 1 to 25 cut-offs"},
  {"name": "a negative quantity is an error", "args": [[{"sku": "A", "annualQuantity": -1, "unitCost": {"minor": 1, "currency": "GBP"}}], [8000]], "expectError": "annualQuantity must be a whole number, not negative"},
  {"name": "a fractional quantity is an error", "args": [[{"sku": "A", "annualQuantity": 1.5, "unitCost": {"minor": 1, "currency": "GBP"}}], [8000]], "expectError": "annualQuantity must be a whole number, not negative"},
  {"name": "a negative unit cost is an error", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": -1, "currency": "GBP"}}], [8000]], "expectError": "unitCost must not be negative"},
  {"name": "items in two currencies are an error", "args": [[{"sku": "A", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "GBP"}}, {"sku": "B", "annualQuantity": 1, "unitCost": {"minor": 1, "currency": "EUR"}}], [8000]], "expectError": "currency mismatch"},
  {"name": "a total too large to scale is an error", "args": [[{"sku": "A", "annualQuantity": 1000000, "unitCost": {"minor": 1000000000, "currency": "GBP"}}], [8000]], "expectError": "the total annual value is too large"}
]