{
  "run": {
    "built": "2026-09-08 19:13",
    "source": "data/raw-orders.csv",
    "lookup": "data/partners.csv",
    "workbook": "out/apex-orders-2026-q3.xlsx",
    "engine": "python 3.9, openpyxl 3.1.5",
    "subject": "Apex Instruments, quarter ending September 30, 2026",
    "workbookBytes": 71004,
    "workbookSheets": [
      "Read me",
      "Summary",
      "By month",
      "By product",
      "Clean data",
      "Rejected rows"
    ]
  },
  "counts": {
    "linesInFile": 405,
    "preambleLines": 4,
    "headerLine": 5,
    "rowsIn": 400,
    "rowsOut": 381,
    "rowsFixed": 377,
    "rowsUnchanged": 4,
    "rowsRejected": 19,
    "cellsChanged": 657
  },
  "rules": [
    {
      "id": "R01",
      "name": "Header row located",
      "what": "Skips the export preamble and starts at the first line that carries the real column names.",
      "unit": "file",
      "fired": 1,
      "example": {
        "line": 5,
        "column": "file",
        "before": "4 preamble lines above the header",
        "after": "header read from line 5"
      }
    },
    {
      "id": "R02",
      "name": "Date normalised to ISO",
      "what": "Five date shapes appear in the export. Each is parsed and rewritten as a real date value.",
      "unit": "rows",
      "fired": 235,
      "example": {
        "line": 6,
        "column": "order_date",
        "before": "21-Aug-2026",
        "after": "2026-08-21"
      }
    },
    {
      "id": "R03",
      "name": "Currency parsed to a number",
      "what": "Strips the dollar sign, thousands separators and stray spaces so the value is arithmetic, not text.",
      "unit": "cells",
      "fired": 282,
      "example": {
        "line": 6,
        "column": "unit_price",
        "before": "$180",
        "after": "180.00"
      }
    },
    {
      "id": "R04",
      "name": "Whitespace trimmed",
      "what": "Removes leading and trailing spaces and collapses runs of spaces inside a value.",
      "unit": "cells",
      "fired": 304,
      "example": {
        "line": 6,
        "column": "channel",
        "before": "'Partner '",
        "after": "'Partner'"
      }
    },
    {
      "id": "R05",
      "name": "Ship-to city unified",
      "what": "One spelling per location. St Petersburg and ST PETERSBURG both become St. Petersburg.",
      "unit": "rows",
      "fired": 63,
      "example": {
        "line": 25,
        "column": "ship_city",
        "before": "ST PETERSBURG",
        "after": "St. Petersburg"
      }
    },
    {
      "id": "R06",
      "name": "Product matched to the catalog",
      "what": "Case, spacing and short forms are matched to the one catalog name. Field Kit becomes Meridian Field Kit.",
      "unit": "rows",
      "fired": 186,
      "example": {
        "line": 6,
        "column": "product",
        "before": "CALIBRATION SERVICE",
        "after": "Calibration service"
      }
    },
    {
      "id": "R07",
      "name": "Partner id normalised",
      "what": "Upper cased and trimmed, then joined to the partner list for the partner name and region.",
      "unit": "rows",
      "fired": 90,
      "example": {
        "line": 7,
        "column": "partner_id",
        "before": "dir-000",
        "after": "DIR-000"
      }
    },
    {
      "id": "R08",
      "name": "Discount normalised to a fraction",
      "what": "A discount typed as 5% or 5.0% is divided by 100 and stored as 0.05, next to the ones already written as 0.05.",
      "unit": "rows",
      "fired": 171,
      "example": {
        "line": 6,
        "column": "discount",
        "before": "5%",
        "after": "0.0500"
      }
    },
    {
      "id": "R09",
      "name": "Placeholder treated as empty",
      "what": "Tokens that mean no value, such as N/A, TBD and a double hyphen, are read as empty, not as text.",
      "unit": "cells",
      "fired": 71,
      "example": {
        "line": 7,
        "column": "ship_cost",
        "before": "TBD",
        "after": "(empty)"
      }
    },
    {
      "id": "R10",
      "name": "Whole number quantity made an integer",
      "what": "A quantity written as 2.0 is stored as 2 so it counts and sorts as a number.",
      "unit": "rows",
      "fired": 28,
      "example": {
        "line": 32,
        "column": "qty",
        "before": "7.0",
        "after": "7"
      }
    },
    {
      "id": "R11",
      "name": "Missing unit price filled from the catalog",
      "what": "A blank price is filled from the product list price and the fill is recorded on the row.",
      "unit": "rows",
      "fired": 16,
      "example": {
        "line": 9,
        "column": "unit_price",
        "before": "(empty)",
        "after": "180.00 from the catalog"
      }
    },
    {
      "id": "R12",
      "name": "Missing ship-to city filled from the partner",
      "what": "A blank city is filled from the partner record rather than left empty or guessed.",
      "unit": "rows",
      "fired": 13,
      "example": {
        "line": 35,
        "column": "ship_city",
        "before": "(empty)",
        "after": "Tampa from NLG-011"
      }
    },
    {
      "id": "R13",
      "name": "Channel and status matched to the allowed values",
      "what": "PARTNER, partner and Partner all become Partner. Anything outside the allowed set stops the row.",
      "unit": "rows",
      "fired": 103,
      "example": {
        "line": 14,
        "column": "channel/status",
        "before": "PARTNER / Shipped",
        "after": "Partner / Shipped"
      }
    }
  ],
  "rejects": {
    "total": 19,
    "byReason": [
      {
        "code": "X1",
        "reason": "Duplicate order id. The first row with this id was imported, this one was not.",
        "rows": 3,
        "lines": [
          147,
          239,
          324
        ]
      },
      {
        "code": "X2",
        "reason": "A required field is empty: order id, order date, product or quantity.",
        "rows": 5,
        "lines": [
          43,
          102,
          180,
          272,
          355
        ]
      },
      {
        "code": "X3",
        "reason": "Quantity is zero or negative. A return needs a credit note, not an order row.",
        "rows": 2,
        "lines": [
          70,
          294
        ]
      },
      {
        "code": "X4",
        "reason": "The order date could not be read as a date in any known format.",
        "rows": 2,
        "lines": [
          89,
          217
        ]
      },
      {
        "code": "X5",
        "reason": "The product is not in the Apex catalog.",
        "rows": 2,
        "lines": [
          135,
          310
        ]
      },
      {
        "code": "X6",
        "reason": "The partner id is not in the partner list.",
        "rows": 3,
        "lines": [
          51,
          196,
          361
        ]
      },
      {
        "code": "X7",
        "reason": "Quantity or unit price is not a number.",
        "rows": 2,
        "lines": [
          164,
          278
        ]
      },
      {
        "code": "X8",
        "reason": "Channel or status is outside the values this workbook allows.",
        "rows": 0,
        "lines": []
      }
    ],
    "rows": [
      {
        "line": 43,
        "code": "X2",
        "reason": "A required field is empty: order id, order date, product or quantity.",
        "detail": "empty: product",
        "orderId": "AP-30261",
        "orderDate": "07/12/2026",
        "partnerId": "NLG-027",
        "product": "",
        "qty": "2",
        "unitPrice": "$4,850.00"
      },
      {
        "line": 51,
        "code": "X6",
        "reason": "The partner id is not in the partner list.",
        "detail": "id read: NLG-099",
        "orderId": "AP-30317",
        "orderDate": "2026-07-05",
        "partnerId": "NLG-099",
        "product": "Calibration",
        "qty": "5.0",
        "unitPrice": "180.00"
      },
      {
        "line": 70,
        "code": "X3",
        "reason": "Quantity is zero or negative. A return needs a credit note, not an order row.",
        "detail": "quantity read: -2",
        "orderId": "AP-30448",
        "orderDate": "2026-09-22",
        "partnerId": "NLG-031",
        "product": "calibration svc",
        "qty": "-2",
        "unitPrice": "$180.00"
      },
      {
        "line": 89,
        "code": "X4",
        "reason": "The order date could not be read as a date in any known format.",
        "detail": "value read: Q3",
        "orderId": "AP-30584",
        "orderDate": "Q3",
        "partnerId": " NLG-022",
        "product": "atlas care plus",
        "qty": "2",
        "unitPrice": "$1,788.00"
      },
      {
        "line": 102,
        "code": "X2",
        "reason": "A required field is empty: order id, order date, product or quantity.",
        "detail": "empty: product",
        "orderId": "AP-30676",
        "orderDate": "2026-09-22",
        "partnerId": "NLG-011",
        "product": "",
        "qty": "5",
        "unitPrice": "$180.00"
      },
      {
        "line": 135,
        "code": "X5",
        "reason": "The product is not in the Apex catalog.",
        "detail": "name read: Meridian Ultra",
        "orderId": "AP-30906",
        "orderDate": "07/13/2026",
        "partnerId": "NLG-036",
        "product": "Meridian Ultra",
        "qty": "5",
        "unitPrice": "180.00"
      },
      {
        "line": 147,
        "code": "X1",
        "reason": "Duplicate order id. The first row with this id was imported, this one was not.",
        "detail": "first seen on line 18",
        "orderId": "AP-30086",
        "orderDate": "2026-07-11",
        "partnerId": "NLG-031",
        "product": "calibration svc",
        "qty": "2",
        "unitPrice": "180"
      },
      {
        "line": 164,
        "code": "X7",
        "reason": "Quantity or unit price is not a number.",
        "detail": "quantity read: two",
        "orderId": "AP-31108",
        "orderDate": "09/19/2026",
        "partnerId": "DIR-000",
        "product": "Atlas Care Plus",
        "qty": "two",
        "unitPrice": ""
      },
      {
        "line": 180,
        "code": "X2",
        "reason": "A required field is empty: order id, order date, product or quantity.",
        "detail": "empty: qty",
        "orderId": "AP-31219",
        "orderDate": "August 20, 2026",
        "partnerId": "NLG-022",
        "product": "atlas care plus",
        "qty": "",
        "unitPrice": "$1,788.00"
      },
      {
        "line": 196,
        "code": "X6",
        "reason": "The partner id is not in the partner list.",
        "detail": "id read: XX-001",
        "orderId": "AP-31330",
        "orderDate": "8/21/26",
        "partnerId": "XX-001",
        "product": "meridian pro",
        "qty": "1.0",
        "unitPrice": "7,900.00"
      },
      {
        "line": 217,
        "code": "X4",
        "reason": "The order date could not be read as a date in any known format.",
        "detail": "value read: 2026-13-45",
        "orderId": "AP-31480",
        "orderDate": "2026-13-45",
        "partnerId": "NLG-022",
        "product": "Meridian Field Kit",
        "qty": "7",
        "unitPrice": "1240"
      },
      {
        "line": 239,
        "code": "X1",
        "reason": "Duplicate order id. The first row with this id was imported, this one was not.",
        "detail": "first seen on line 64",
        "orderId": "AP-30410",
        "orderDate": "20-Sep-2026",
        "partnerId": "NLG-011",
        "product": "Meridian Bench",
        "qty": "1",
        "unitPrice": "4850.00"
      },
      {
        "line": 272,
        "code": "X2",
        "reason": "A required field is empty: order id, order date, product or quantity.",
        "detail": "empty: order_date",
        "orderId": "AP-31865",
        "orderDate": "",
        "partnerId": "NLG-031",
        "product": "Meridian Field Kit",
        "qty": "5",
        "unitPrice": "$1,240.00"
      },
      {
        "line": 278,
        "code": "X7",
        "reason": "Quantity or unit price is not a number.",
        "detail": "unit price read: call for price",
        "orderId": "AP-31906",
        "orderDate": "09/21/2026",
        "partnerId": "NLG-014",
        "product": "Atlas Care Plus",
        "qty": "5",
        "unitPrice": "call for price"
      },
      {
        "line": 294,
        "code": "X3",
        "reason": "Quantity is zero or negative. A return needs a credit note, not an order row.",
        "detail": "quantity read: -1",
        "orderId": "AP-32019",
        "orderDate": "25-Aug-2026",
        "partnerId": "NLG-044",
        "product": "Atlas Care Plus",
        "qty": "-1",
        "unitPrice": "$1,788"
      },
      {
        "line": 310,
        "code": "X5",
        "reason": "The product is not in the Apex catalog.",
        "detail": "name read: Bench Riser Kit",
        "orderId": "AP-32132",
        "orderDate": "2026-08-22",
        "partnerId": " NLG-014",
        "product": "Bench Riser Kit",
        "qty": "12",
        "unitPrice": ""
      },
      {
        "line": 324,
        "code": "X1",
        "reason": "Duplicate order id. The first row with this id was imported, this one was not.",
        "detail": "first seen on line 106",
        "orderId": "AP-30702",
        "orderDate": "July 4, 2026",
        "partnerId": "NLG-031",
        "product": "calibration svc",
        "qty": "1",
        "unitPrice": "$180"
      },
      {
        "line": 355,
        "code": "X2",
        "reason": "A required field is empty: order id, order date, product or quantity.",
        "detail": "empty: order_id",
        "orderId": "",
        "orderDate": "2026-09-22",
        "partnerId": "NLG-036",
        "product": "Meridian Pro",
        "qty": "1",
        "unitPrice": "7900"
      },
      {
        "line": 361,
        "code": "X6",
        "reason": "The partner id is not in the partner list.",
        "detail": "id read: NLG-052",
        "orderId": "AP-32485",
        "orderDate": "07/22/2026",
        "partnerId": "NLG-052",
        "product": "Calibration",
        "qty": "2",
        "unitPrice": "180"
      }
    ]
  },
  "distributions": {
    "ship_city": {
      "note": "One location was reaching the file under five spellings. After the run there is one.",
      "before": [
        [
          "Tampa",
          95
        ],
        [
          "Sarasota",
          50
        ],
        [
          "Orlando",
          43
        ],
        [
          "Clearwater",
          41
        ],
        [
          "Lakeland",
          33
        ],
        [
          "Brandon",
          31
        ],
        [
          "St. Petersburg",
          25
        ],
        [
          "(empty)",
          15
        ],
        [
          "ST PETERSBURG",
          15
        ],
        [
          "St Petersburg",
          13
        ],
        [
          "st petersburg",
          10
        ],
        [
          "TAMPA",
          6
        ],
        [
          "ORLANDO",
          4
        ],
        [
          "sarasota",
          4
        ],
        [
          "tampa",
          4
        ],
        [
          "SARASOTA",
          3
        ],
        [
          "brandon",
          2
        ],
        [
          "orlando",
          2
        ],
        [
          "BRANDON",
          1
        ],
        [
          "LAKELAND",
          1
        ],
        [
          "lakeland",
          1
        ],
        [
          "st. petersburg",
          1
        ]
      ],
      "after": [
        [
          "Tampa",
          106
        ],
        [
          "St. Petersburg",
          64
        ],
        [
          "Sarasota",
          54
        ],
        [
          "Orlando",
          47
        ],
        [
          "Clearwater",
          41
        ],
        [
          "Lakeland",
          36
        ],
        [
          "Brandon",
          33
        ]
      ],
      "distinctBefore": 22,
      "distinctAfter": 7
    },
    "product": {
      "note": "Six catalog lines were arriving under many spellings, including short forms and case variants.",
      "before": [
        [
          "Meridian Field Kit",
          47
        ],
        [
          "Atlas Care Plus",
          41
        ],
        [
          "Meridian Bench",
          38
        ],
        [
          "Meridian Pro",
          32
        ],
        [
          "calibration svc",
          26
        ],
        [
          "On-site training",
          24
        ],
        [
          "Calibration service",
          23
        ],
        [
          "Calibration",
          19
        ],
        [
          "CALIBRATION SERVICE",
          17
        ],
        [
          "ATLAS CARE PLUS",
          12
        ],
        [
          "Atlas Care+",
          11
        ],
        [
          "Field Kit",
          11
        ],
        [
          "atlas care plus",
          10
        ],
        [
          "Care Plus",
          9
        ],
        [
          "MERIDIAN BENCH",
          8
        ],
        [
          "MERIDIAN FIELD KIT",
          8
        ],
        [
          "On site training",
          8
        ],
        [
          "Onsite training",
          8
        ],
        [
          "meridian pro",
          8
        ],
        [
          "on-site training",
          8
        ],
        [
          "TRAINING",
          6
        ],
        [
          "meridian bench",
          6
        ],
        [
          "meridian field kit",
          6
        ],
        [
          "Meridian Fieldkit",
          4
        ],
        [
          "Bench",
          3
        ],
        [
          "(empty)",
          2
        ],
        [
          "Meridian PRO",
          2
        ],
        [
          "Bench Riser Kit",
          1
        ],
        [
          "Meridian Ultra",
          1
        ],
        [
          "Pro",
          1
        ]
      ],
      "after": [
        [
          "Calibration service",
          80
        ],
        [
          "Atlas Care Plus",
          78
        ],
        [
          "Meridian Field Kit",
          74
        ],
        [
          "Meridian Bench",
          54
        ],
        [
          "On-site training",
          54
        ],
        [
          "Meridian Pro",
          41
        ]
      ],
      "distinctBefore": 30,
      "distinctAfter": 6
    }
  },
  "totals": {
    "orders": 381,
    "units": 1365,
    "gross": 2378436.0,
    "net": 2288695.9,
    "cost": 1130862.0,
    "ship": 17290.23,
    "discount": 89740.1,
    "margin": 1157833.9,
    "marginPct": 0.505892,
    "aov": 6007.08
  },
  "byMonth": [
    {
      "key": "2026-07",
      "label": "July 2026",
      "orders": 114,
      "units": 409,
      "gross": 730086.0,
      "net": 699596.4,
      "cost": 330743.0,
      "margin": 368853.4,
      "marginPct": 0.527237
    },
    {
      "key": "2026-08",
      "label": "August 2026",
      "orders": 141,
      "units": 511,
      "gross": 850034.0,
      "net": 822412.6,
      "cost": 426424.0,
      "margin": 395988.6,
      "marginPct": 0.481496
    },
    {
      "key": "2026-09",
      "label": "September 2026",
      "orders": 126,
      "units": 445,
      "gross": 798316.0,
      "net": 766686.9,
      "cost": 373695.0,
      "margin": 392991.9,
      "marginPct": 0.512585
    }
  ],
  "byProduct": [
    {
      "product": "Meridian Bench",
      "orders": 54,
      "units": 104,
      "gross": 504400.0,
      "net": 486649.0,
      "cost": 302640.0,
      "margin": 184009.0,
      "marginPct": 0.378114,
      "share": 0.212632
    },
    {
      "product": "Meridian Pro",
      "orders": 41,
      "units": 61,
      "gross": 481900.0,
      "net": 456699.0,
      "cost": 265045.0,
      "margin": 191654.0,
      "marginPct": 0.419651,
      "share": 0.199546
    },
    {
      "product": "Meridian Field Kit",
      "orders": 74,
      "units": 343,
      "gross": 425320.0,
      "net": 409733.2,
      "cost": 276458.0,
      "margin": 133275.2,
      "marginPct": 0.325273,
      "share": 0.179025
    },
    {
      "product": "Atlas Care Plus",
      "orders": 78,
      "units": 472,
      "gross": 843936.0,
      "net": 817205.4,
      "cost": 210984.0,
      "margin": 606221.4,
      "marginPct": 0.741823,
      "share": 0.357062
    },
    {
      "product": "Calibration service",
      "orders": 80,
      "units": 271,
      "gross": 48780.0,
      "net": 47188.8,
      "cost": 26829.0,
      "margin": 20359.8,
      "marginPct": 0.431454,
      "share": 0.020618
    },
    {
      "product": "On-site training",
      "orders": 54,
      "units": 114,
      "gross": 74100.0,
      "net": 71220.5,
      "cost": 48906.0,
      "margin": 22314.5,
      "marginPct": 0.313316,
      "share": 0.031118
    }
  ]
}
