Functional Weave
Code in TypeScript

construction.day-rate-quote@1.0.0

vectors.json

9,957 bytes · view raw

[
  {
    "name": "3 days at 250.00 and 400.00 of materials marked up 20%, standard-rated: the markup is on materials only",
    "args": [
      300,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 40000,
        "currency": "GBP"
      },
      2000,
      "STANDARD",
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 75000,
        "currency": "GBP"
      },
      "materials": {
        "minor": 48000,
        "currency": "GBP"
      },
      "net": {
        "minor": 123000,
        "currency": "GBP"
      },
      "vat": {
        "minor": 24600,
        "currency": "GBP"
      },
      "gross": {
        "minor": 147600,
        "currency": "GBP"
      },
      "vatBasisPoints": 2000
    }
  },
  {
    "name": "2.5 days at 180.00, no materials, not VAT registered",
    "args": [
      250,
      {
        "minor": 18000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      1500,
      null,
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 45000,
        "currency": "GBP"
      },
      "materials": {
        "minor": 0,
        "currency": "GBP"
      },
      "net": {
        "minor": 45000,
        "currency": "GBP"
      },
      "vat": {
        "minor": 0,
        "currency": "GBP"
      },
      "gross": {
        "minor": 45000,
        "currency": "GBP"
      },
      "vatBasisPoints": 0
    }
  },
  {
    "name": "a third of a day at 199.99 is 65.9967, rounded half up to 66.00; 12.34 of materials at 15% is 14.191, 14.19; VAT 20% of 80.19 is 16.038, 16.04",
    "args": [
      33,
      {
        "minor": 19999,
        "currency": "GBP"
      },
      {
        "minor": 1234,
        "currency": "GBP"
      },
      1500,
      "STANDARD",
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 6600,
        "currency": "GBP"
      },
      "materials": {
        "minor": 1419,
        "currency": "GBP"
      },
      "net": {
        "minor": 8019,
        "currency": "GBP"
      },
      "vat": {
        "minor": 1604,
        "currency": "GBP"
      },
      "gross": {
        "minor": 9623,
        "currency": "GBP"
      },
      "vatBasisPoints": 2000
    }
  },
  {
    "name": "reduced-rated installation at 5%",
    "args": [
      100,
      {
        "minor": 20000,
        "currency": "GBP"
      },
      {
        "minor": 100000,
        "currency": "GBP"
      },
      0,
      "REDUCED",
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 20000,
        "currency": "GBP"
      },
      "materials": {
        "minor": 100000,
        "currency": "GBP"
      },
      "net": {
        "minor": 120000,
        "currency": "GBP"
      },
      "vat": {
        "minor": 6000,
        "currency": "GBP"
      },
      "gross": {
        "minor": 126000,
        "currency": "GBP"
      },
      "vatBasisPoints": 500
    }
  },
  {
    "name": "zero-rated work",
    "args": [
      200,
      {
        "minor": 15000,
        "currency": "GBP"
      },
      {
        "minor": 30000,
        "currency": "GBP"
      },
      1000,
      "ZERO",
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 30000,
        "currency": "GBP"
      },
      "materials": {
        "minor": 33000,
        "currency": "GBP"
      },
      "net": {
        "minor": 63000,
        "currency": "GBP"
      },
      "vat": {
        "minor": 0,
        "currency": "GBP"
      },
      "gross": {
        "minor": 63000,
        "currency": "GBP"
      },
      "vatBasisPoints": 0
    }
  },
  {
    "name": "a quote for a 2010 job uses the 17.5% rate then in force",
    "args": [
      100,
      {
        "minor": 10000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      "STANDARD",
      "2010-06-30"
    ],
    "expect": {
      "labour": {
        "minor": 10000,
        "currency": "GBP"
      },
      "materials": {
        "minor": 0,
        "currency": "GBP"
      },
      "net": {
        "minor": 10000,
        "currency": "GBP"
      },
      "vat": {
        "minor": 1750,
        "currency": "GBP"
      },
      "gross": {
        "minor": 11750,
        "currency": "GBP"
      },
      "vatBasisPoints": 1750
    }
  },
  {
    "name": "materials only: no labour days",
    "args": [
      0,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 5000,
        "currency": "GBP"
      },
      1000,
      "STANDARD",
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 0,
        "currency": "GBP"
      },
      "materials": {
        "minor": 5500,
        "currency": "GBP"
      },
      "net": {
        "minor": 5500,
        "currency": "GBP"
      },
      "vat": {
        "minor": 1100,
        "currency": "GBP"
      },
      "gross": {
        "minor": 6600,
        "currency": "GBP"
      },
      "vatBasisPoints": 2000
    }
  },
  {
    "name": "half a day at 250.00",
    "args": [
      50,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 12500,
        "currency": "GBP"
      },
      "materials": {
        "minor": 0,
        "currency": "GBP"
      },
      "net": {
        "minor": 12500,
        "currency": "GBP"
      },
      "vat": {
        "minor": 0,
        "currency": "GBP"
      },
      "gross": {
        "minor": 12500,
        "currency": "GBP"
      },
      "vatBasisPoints": 0
    }
  },
  {
    "name": "half a day at 250.01 is 125.005, rounded half up to 125.01",
    "args": [
      50,
      {
        "minor": 25001,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 12501,
        "currency": "GBP"
      },
      "materials": {
        "minor": 0,
        "currency": "GBP"
      },
      "net": {
        "minor": 12501,
        "currency": "GBP"
      },
      "vat": {
        "minor": 0,
        "currency": "GBP"
      },
      "gross": {
        "minor": 12501,
        "currency": "GBP"
      },
      "vatBasisPoints": 0
    }
  },
  {
    "name": "materials sold at cost: no markup",
    "args": [
      100,
      {
        "minor": 20000,
        "currency": "GBP"
      },
      {
        "minor": 7777,
        "currency": "GBP"
      },
      0,
      "STANDARD",
      "2026-09-23"
    ],
    "expect": {
      "labour": {
        "minor": 20000,
        "currency": "GBP"
      },
      "materials": {
        "minor": 7777,
        "currency": "GBP"
      },
      "net": {
        "minor": 27777,
        "currency": "GBP"
      },
      "vat": {
        "minor": 5555,
        "currency": "GBP"
      },
      "gross": {
        "minor": 33332,
        "currency": "GBP"
      },
      "vatBasisPoints": 2000
    }
  },
  {
    "name": "negative labour days",
    "args": [
      -50,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expectError": "labourDaysHundredths must be a whole number of hundredths, not negative"
  },
  {
    "name": "fractional hundredths",
    "args": [
      2.5,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expectError": "labourDaysHundredths must be a whole number of hundredths, not negative"
  },
  {
    "name": "a negative day rate",
    "args": [
      100,
      {
        "minor": -1,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expectError": "dayRate must not be negative"
  },
  {
    "name": "negative materials",
    "args": [
      100,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": -1,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expectError": "cost must not be negative"
  },
  {
    "name": "a markup below -100%",
    "args": [
      100,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 100,
        "currency": "GBP"
      },
      -10001,
      null,
      "2026-09-23"
    ],
    "expectError": "a markup of -10001 basis points gives a negative price"
  },
  {
    "name": "a fractional markup",
    "args": [
      100,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 100,
        "currency": "GBP"
      },
      1.5,
      null,
      "2026-09-23"
    ],
    "expectError": "must be an integer"
  },
  {
    "name": "day rate and materials in different currencies",
    "args": [
      100,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 100,
        "currency": "EUR"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expectError": "currency mismatch"
  },
  {
    "name": "an unknown VAT category",
    "args": [
      100,
      {
        "minor": 25000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      "LUXURY",
      "2026-09-23"
    ],
    "expectError": "no VAT rule for GB/LUXURY"
  },
  {
    "name": "a labour product beyond 2^53 - 1",
    "args": [
      10000000,
      {
        "minor": 1000000000000,
        "currency": "GBP"
      },
      {
        "minor": 0,
        "currency": "GBP"
      },
      0,
      null,
      "2026-09-23"
    ],
    "expectError": "exceeds 2^53 - 1"
  }
]