# Company Reports Downstream Processor `company_reports` is an ordinary deterministic downstream program. It reads ARR-validated Finance facts and current accepted booking room items, then builds one workbook per company. It does not read XML, call an Agent, or recalculate `REAL PRICE`/`TOTAL PRICE`. ## Data contract - Finance source: `finance.v_active_daily_facts`, selected by `DEPARTURE` from month start through the requested as-of date. - Booking source: `booking.v_current_room_items` and `booking.v_group_room_item_summary`, matched by normalized full Group Code only. - Dates/nights come from Finance. Booking data only supplies room type and booked quantity. - A Finance fact with no Group Code remains as its own output row and has blank `RES_COMMENT` and `Booking Room`; it is never merged with another no-code fact. A present Group Code keeps its normal stay-segment row and `RES_COMMENT`, but `Booking Room` is blank when no current accepted Booking room can be resolved. - `Total Booking Price` uses each Finance daily `TOTAL PRICE`; it is not recomputed from booking unit price and is not collapsed across all rows sharing a Group Code. - The program splits matched output by each Finance `(Group Code, ARRIVAL, DEPARTURE)` segment. - Report rows/versions are not persisted in PostgreSQL; a deterministic generation identity and source pins protect generation consistency. Supported companies: `LianTai`, `QBD`, `DY-AI-Easy-KB`, `FengRun`, `HanaTour`. ## Run ```bash python3 -m pip install -r requirements-company-reports.txt export COMPANY_REPORT_DATABASE_URL='postgresql://USER:PASSWORD@HOST:PORT/booking_test' export COMPANY_REPORT_NODE_BINARY='/absolute/path/to/node' export COMPANY_REPORT_ARTIFACT_TOOL_MODULE='/absolute/path/to/artifact_tool.mjs' python3 -m company_reports generate \ --month 2026-07 \ --as-of 2026-07-10 ``` The DSN can fall back to `ARR_DATABASE_URL`; never place a real DSN in source, prompts, output JSON or browser code. Scheduling convention: - 11th: as-of 10th; - 21st: as-of 20th; - 1st of next month: as-of prior natural month end. ## Workbook Each period sheet has seven columns: 1. `ARRIVAL` 2. `DEPARTURE` 3. `NIGHTS` 4. `BLOCK_CODE` 5. `RES_COMMENT` 6. `Booking Room` 7. `Total Booking Price` The builder creates a new formula-free workbook, reopens and validates it, then atomically publishes the file. Same-room-type/multiple-price cases are surfaced as a review warning rather than silently merged. ## Tests ```bash PYTHONPYCACHEPREFIX=/tmp/company_reports_pycache \ python3 -m unittest discover -s tests -p 'test_company_reports*.py' -v ``` All test identifiers are synthetic. The current remote acceptance fixture returns one QBD row, Booking Room `【DBL】1`, from the controlled `:5432/booking_test` database.