# Python reporting lab

Original synthetic orders, deliberately different from the line-grain spreadsheet
and Power BI fixtures. One accepted row is one OrderID. Customer IDs are four-digit
text strings; amount_inr is canonical nonnegative decimal text with two places.
Amounts are INR major units, not paise. Dates are normalized YYYY-MM-DD. Paid and
Pending are the only accepted statuses for this exercise.

Python standard library only. From this directory:

```powershell
python -m unittest -v test_report.py
python report.py --input raw_orders.csv --output example-output --month 2026-01
```

The supplied raw fixture intentionally gives CLI exit code **2** because three
records are rejected. The report is a labelled partial output, not a fully accepted
production report. Exit 0 means no rejected records; exit 1 means a fatal input,
schema, conflicting-key or filesystem error. A real scheduler must implement the
business policy for partial outputs instead of ignoring nonzero exit status.

Expected January paid result: four unique orders, two customers, INR 47.50.
February paid: two orders, two customers, INR 17.00. Input has eleven records:
seven accepted unique orders, three rejects, one identical replay of R3.
R8 has N/A amount, R9 missing customer, R10 a comma-formatted amount outside the
canonical contract. The script does not guess that amount's intended locale.

The source is read once for this small lab; its SHA-256 and Python version are
recorded in summary.json. Accepted and rejected CSVs preserve traceability.
Conflicting payloads under one OrderID fail the batch. Raw input is never rewritten.
Output files with the same names are replaced inside the explicitly selected output
directory; use a new directory for a new immutable report snapshot when needed.

This is a teaching CLI, not a complete production scheduler or atomic multi-file
publication protocol. It has no network access, secrets or external services.
Original fixture/code may be used, modified and redistributed for learning with
attribution to NeuraPath Academy.
