Functional Weave
Code in TypeScript

finance.invoice.calculate@1.0.0

vectors.json

5,838 bytes · view raw

[
  {
    "name": "mixed standard, zero and discounted lines",
    "args": [
      [
        { "description": "Consultancy, 3 days", "unitPrice": { "minor": 50000, "currency": "GBP" }, "quantity": 3, "discountBasisPoints": 0, "taxCategory": "STANDARD" },
        { "description": "Printed report", "unitPrice": { "minor": 1250, "currency": "GBP" }, "quantity": 2, "discountBasisPoints": 0, "taxCategory": "ZERO" },
        { "description": "Software licence", "unitPrice": { "minor": 9999, "currency": "GBP" }, "quantity": 1, "discountBasisPoints": 1000, "taxCategory": "STANDARD" }
      ],
      "GB",
      "2026-09-16"
    ],
    "expect": {
      "currency": "GBP",
      "lines": [
        { "description": "Consultancy, 3 days", "net": { "minor": 150000, "currency": "GBP" }, "tax": { "minor": 30000, "currency": "GBP" }, "gross": { "minor": 180000, "currency": "GBP" }, "basisPoints": 2000 },
        { "description": "Printed report", "net": { "minor": 2500, "currency": "GBP" }, "tax": { "minor": 0, "currency": "GBP" }, "gross": { "minor": 2500, "currency": "GBP" }, "basisPoints": 0 },
        { "description": "Software licence", "net": { "minor": 8999, "currency": "GBP" }, "tax": { "minor": 1800, "currency": "GBP" }, "gross": { "minor": 10799, "currency": "GBP" }, "basisPoints": 2000 }
      ],
      "subtotal": { "minor": 161499, "currency": "GBP" },
      "taxTotal": { "minor": 31800, "currency": "GBP" },
      "total": { "minor": 193299, "currency": "GBP" },
      "taxBreakdown": [
        { "basisPoints": 0, "taxable": { "minor": 2500, "currency": "GBP" }, "tax": { "minor": 0, "currency": "GBP" } },
        { "basisPoints": 2000, "taxable": { "minor": 158999, "currency": "GBP" }, "tax": { "minor": 31800, "currency": "GBP" } }
      ]
    }
  },
  {
    "name": "hospitality invoice during the covid rate cut",
    "args": [
      [{ "description": "Dinner, 4 covers", "unitPrice": { "minor": 5000, "currency": "GBP" }, "quantity": 4, "discountBasisPoints": 0, "taxCategory": "HOSPITALITY" }],
      "GB",
      "2020-12-25"
    ],
    "expect": {
      "currency": "GBP",
      "lines": [{ "description": "Dinner, 4 covers", "net": { "minor": 20000, "currency": "GBP" }, "tax": { "minor": 1000, "currency": "GBP" }, "gross": { "minor": 21000, "currency": "GBP" }, "basisPoints": 500 }],
      "subtotal": { "minor": 20000, "currency": "GBP" },
      "taxTotal": { "minor": 1000, "currency": "GBP" },
      "total": { "minor": 21000, "currency": "GBP" },
      "taxBreakdown": [{ "basisPoints": 500, "taxable": { "minor": 20000, "currency": "GBP" }, "tax": { "minor": 1000, "currency": "GBP" } }]
    }
  },
  {
    "name": "the same goods invoiced in 2009 use the 2009 rate",
    "args": [
      [{ "description": "Widget", "unitPrice": { "minor": 10000, "currency": "GBP" }, "quantity": 1, "discountBasisPoints": 0, "taxCategory": "STANDARD" }],
      "GB",
      "2009-06-01"
    ],
    "expect": {
      "currency": "GBP",
      "lines": [{ "description": "Widget", "net": { "minor": 10000, "currency": "GBP" }, "tax": { "minor": 1500, "currency": "GBP" }, "gross": { "minor": 11500, "currency": "GBP" }, "basisPoints": 1500 }],
      "subtotal": { "minor": 10000, "currency": "GBP" },
      "taxTotal": { "minor": 1500, "currency": "GBP" },
      "total": { "minor": 11500, "currency": "GBP" },
      "taxBreakdown": [{ "basisPoints": 1500, "taxable": { "minor": 10000, "currency": "GBP" }, "tax": { "minor": 1500, "currency": "GBP" } }]
    }
  },
  {
    "name": "a credit note is an invoice with negative quantities",
    "args": [
      [{ "description": "Returned widget", "unitPrice": { "minor": 10000, "currency": "GBP" }, "quantity": -1, "discountBasisPoints": 0, "taxCategory": "STANDARD" }],
      "GB",
      "2026-09-16"
    ],
    "expect": {
      "currency": "GBP",
      "lines": [{ "description": "Returned widget", "net": { "minor": -10000, "currency": "GBP" }, "tax": { "minor": -2000, "currency": "GBP" }, "gross": { "minor": -12000, "currency": "GBP" }, "basisPoints": 2000 }],
      "subtotal": { "minor": -10000, "currency": "GBP" },
      "taxTotal": { "minor": -2000, "currency": "GBP" },
      "total": { "minor": -12000, "currency": "GBP" },
      "taxBreakdown": [{ "basisPoints": 2000, "taxable": { "minor": -10000, "currency": "GBP" }, "tax": { "minor": -2000, "currency": "GBP" } }]
    }
  },
  {
    "name": "an Irish invoice uses Irish rates",
    "args": [
      [{ "description": "Consultancy", "unitPrice": { "minor": 100000, "currency": "EUR" }, "quantity": 1, "discountBasisPoints": 0, "taxCategory": "STANDARD" }],
      "IE",
      "2026-09-16"
    ],
    "expect": {
      "currency": "EUR",
      "lines": [{ "description": "Consultancy", "net": { "minor": 100000, "currency": "EUR" }, "tax": { "minor": 23000, "currency": "EUR" }, "gross": { "minor": 123000, "currency": "EUR" }, "basisPoints": 2300 }],
      "subtotal": { "minor": 100000, "currency": "EUR" },
      "taxTotal": { "minor": 23000, "currency": "EUR" },
      "total": { "minor": 123000, "currency": "EUR" },
      "taxBreakdown": [{ "basisPoints": 2300, "taxable": { "minor": 100000, "currency": "EUR" }, "tax": { "minor": 23000, "currency": "EUR" } }]
    }
  },
  {
    "name": "an invoice with no lines is an error",
    "args": [[], "GB", "2026-09-16"],
    "expectError": "at least one line"
  },
  {
    "name": "mixing currencies across lines is an error",
    "args": [
      [
        { "description": "In pounds", "unitPrice": { "minor": 1000, "currency": "GBP" }, "quantity": 1, "discountBasisPoints": 0, "taxCategory": "STANDARD" },
        { "description": "In euros", "unitPrice": { "minor": 1000, "currency": "EUR" }, "quantity": 1, "discountBasisPoints": 0, "taxCategory": "STANDARD" }
      ],
      "GB",
      "2026-09-16"
    ],
    "expectError": "currency mismatch"
  }
]