"""Privacy-safe five-company acceptance facts for the downstream processor.""" from __future__ import annotations from datetime import date from decimal import Decimal from typing import Dict, List from company_reports.contracts import ( BatchSnapshot, BookingRoomItem, DailyVersionPin, FinanceFact, ) REPORT_YEAR = 2026 REPORT_MONTH = 7 AS_OF_DATE = date(2026, 7, 31) def _fact( record_id: int, *, business_date: date, daily_version_id: int, company_key: str, channel_key: str, group_code: str, block_code: str, arrival: date, departure: date, room_label: str, total_price: str, ) -> FinanceFact: return FinanceFact( daily_record_id=record_id, daily_version_id=daily_version_id, business_date=business_date, channel_key=channel_key, company_key=company_key, company_name=f"SYN-COMPANY-{company_key}", block_code=block_code, group_code_key=group_code, res_comment=group_code, room_category_label=room_label, arrival=arrival, departure=departure, nights=(departure - arrival).days, total_price=Decimal(total_price), booking_source_match_status="matched", ) def _room_item( item_no: int, *, group_code: str, parse_version_id: int, segment_no: int, arrival: date, departure: date, room_type: str, quantity: int, ) -> BookingRoomItem: return BookingRoomItem( group_code_key=group_code, parse_version_id=parse_version_id, segment_no=segment_no, arrival=arrival, departure=departure, nights=(departure - arrival).days, item_no=item_no, room_type_raw=room_type, quantity=quantity, ) def acceptance_snapshot() -> BatchSnapshot: """Return one synthetic month-end snapshot covering every accepted rule.""" facts: List[FinanceFact] = [] room_items: List[BookingRoomItem] = [] lt_arrival = date(2026, 7, 7) lt_departure = date(2026, 7, 10) for record_id, room_label, price, block_code in ( (101, "SYN-RM2", "900", "SYN-BLOCK-LT-A"), (102, "SYN-RM2", "900", "SYN-BLOCK-LT-A"), (103, "SYN-RM3", "3400", "SYN-BLOCK-LT-B"), ): facts.append( _fact( record_id, business_date=date(2026, 7, 8), daily_version_id=1008, company_key="LIAN TAI", channel_key="SYN-CHANNEL-LT", group_code="SYN-LT-0710", block_code=block_code, arrival=lt_arrival, departure=lt_departure, room_label=room_label, total_price=price, ) ) room_items.extend( ( _room_item( 1, group_code="SYN-LT-0710", parse_version_id=7101, segment_no=1, arrival=lt_arrival, departure=lt_departure, room_type="SYN-SUP-TWN-BF", quantity=2, ), _room_item( 2, group_code="SYN-LT-0710", parse_version_id=7101, segment_no=1, arrival=lt_arrival, departure=lt_departure, room_type="SYN-SUP-TRP-BF", quantity=1, ), ) ) qbd_first_arrival = date(2026, 7, 7) qbd_first_departure = date(2026, 7, 10) for record_id, price in ((201, "900"), (202, "1800")): facts.append( _fact( record_id, business_date=date(2026, 7, 8), daily_version_id=1008, company_key="QBD", channel_key="SYN-CHANNEL-QBD", group_code="SYN-QBD-REPEAT", block_code="SYN-BLOCK-QBD-A", arrival=qbd_first_arrival, departure=qbd_first_departure, room_label="SYN-RM2", total_price=price, ) ) qbd_second_arrival = date(2026, 7, 17) qbd_second_departure = date(2026, 7, 20) for record_id in (203, 204, 205): facts.append( _fact( record_id, business_date=date(2026, 7, 18), daily_version_id=1018, company_key="QBD", channel_key="SYN-CHANNEL-QBD", group_code="SYN-QBD-REPEAT", block_code="SYN-BLOCK-QBD-B", arrival=qbd_second_arrival, departure=qbd_second_departure, room_label="SYN-RM2", total_price="900", ) ) room_items.extend( ( _room_item( 1, group_code="SYN-QBD-REPEAT", parse_version_id=7201, segment_no=1, arrival=qbd_first_arrival, departure=qbd_first_departure, room_type="SYN-SUP-TWN-BF", quantity=2, ), _room_item( 1, group_code="SYN-QBD-REPEAT", parse_version_id=7201, segment_no=2, arrival=qbd_second_arrival, departure=qbd_second_departure, room_type="SYN-SUP-TWN-BF", quantity=3, ), ) ) dy_arrival = date(2026, 7, 18) dy_departure = date(2026, 7, 20) for record_id in (301, 302): facts.append( _fact( record_id, business_date=date(2026, 7, 18), daily_version_id=1018, company_key="SYN-UNMAPPED", channel_key="DY-AI-EASY-KB", group_code="SYN-DY-0720", block_code="SYN-BLOCK-DY-A", arrival=dy_arrival, departure=dy_departure, room_label="SYN-KB-RM", total_price="800", ) ) room_items.append( _room_item( 1, group_code="SYN-DY-0720", parse_version_id=7301, segment_no=1, arrival=dy_arrival, departure=dy_departure, room_type="SYN-AI-EASY-TWN", quantity=2, ) ) fr_arrival = date(2026, 7, 27) fr_departure = date(2026, 7, 31) facts.append( _fact( 401, business_date=date(2026, 7, 28), daily_version_id=1028, company_key="FENGRUN", channel_key="SYN-CHANNEL-FR", group_code="SYN-FR-0731", block_code="SYN-BLOCK-FR-A", arrival=fr_arrival, departure=fr_departure, room_label="SYN-RM3", total_price="3200", ) ) room_items.append( _room_item( 1, group_code="SYN-FR-0731", parse_version_id=7401, segment_no=1, arrival=fr_arrival, departure=fr_departure, room_type="SYN-SUP-TRP-BF", quantity=1, ) ) ht_arrival = date(2026, 7, 29) ht_departure = date(2026, 7, 31) for record_id in (501, 502): facts.append( _fact( record_id, business_date=date(2026, 7, 29), daily_version_id=1029, company_key="HANA TOUR", channel_key="SYN-CHANNEL-HT", group_code="SYN-HT-0731", block_code="SYN-BLOCK-HT-A", arrival=ht_arrival, departure=ht_departure, room_label="SYN-RM2", total_price="1200", ) ) room_items.append( _room_item( 1, group_code="SYN-HT-0731", parse_version_id=7501, segment_no=1, arrival=ht_arrival, departure=ht_departure, room_type="SYN-SUP-TWN-BF", quantity=2, ) ) versions_by_date: Dict[date, int] = {} for fact in facts: existing = versions_by_date.get(fact.business_date) if existing is not None and existing != fact.daily_version_id: raise AssertionError("synthetic date has conflicting daily versions") versions_by_date[fact.business_date] = fact.daily_version_id return BatchSnapshot( facts=tuple(facts), room_items=tuple(room_items), daily_versions=tuple( DailyVersionPin(business_date, version_id) for business_date, version_id in sorted(versions_by_date.items()) ), group_parse_versions={ "SYN-LT-0710": 7101, "SYN-QBD-REPEAT": 7201, "SYN-DY-0720": 7301, "SYN-FR-0731": 7401, "SYN-HT-0731": 7501, }, )