# Field Contracts ## XML structure Root: `/RES_DETAIL` Reservations: `/RES_DETAIL/LIST_G_GROUP_BY1/G_GROUP_BY1/LIST_G_RESERVATION/G_RESERVATION` | XML source | Output field | |---|---| | `ADULTS` | `ADULTS` | | `BLOCK_CODE` | `BLOCK_CODE` | | `CF_CHILDREN` | `CHILDREN` | | `COMPANY_NAME` | `COMPANY_NAME` | | `CONFIRMATION_NO` | `CONFIRMATION_NO` | | `DISP_ROOM_NO` | `DISP_ROOM_NO` | | `EFFECTIVE_RATE_AMOUNT` | `EFFECTIVE_RATE_AMOUNT` | | `FULL_NAME` | `FULL_NAME` | | first non-empty `LIST_G_COMMENT_RESV_NAME_ID/.../RES_COMMENT` | `RES_COMMENT` | | first non-empty `LIST_G_DEPT_ID/.../TRACE_TEXT` | `TRACE_TEXT` | | `NO_OF_ROOMS` | `NO_OF_ROOMS` | | `PRODUCTS` | `PRODUCTS` | | `RATE_CODE` | `RATE_CODE` | | `ROOM_CATEGORY_LABEL` | `ROOM_CATEGORY_LABEL` | | `TRUNC_BEGIN` | `ARRIVAL` | | `TRUNC_END` | `DEPARTURE` | | computed | `NIGHTS` | | price rule | `REAL PRICE` | | computed | `TOTAL PRICE` | Group date candidates are `GROUPBY1_SORT_COL` (`YYYYMMDD`) and `GROUPBY1_COL` (`DD-MM-YY`). Both must agree when both exist. Every whitelist candidate `ARRIVAL` must equal the single group business date. ## Daily XLSX: exactly 19 columns 1. `BLOCK_CODE` 2. `ADULTS` 3. `CHILDREN` 4. `COMPANY_NAME` 5. `CONFIRMATION_NO` 6. `DISP_ROOM_NO` 7. `EFFECTIVE_RATE_AMOUNT` 8. `FULL_NAME` 9. `RES_COMMENT` 10. `TRACE_TEXT` 11. `NO_OF_ROOMS` 12. `PRODUCTS` 13. `RATE_CODE` 14. `ROOM_CATEGORY_LABEL` 15. `ARRIVAL` 16. `DEPARTURE` 17. `NIGHTS` 18. `REAL PRICE` 19. `TOTAL PRICE` `TOTAL PRICE = REAL PRICE * NO_OF_ROOMS * NIGHTS`. All derived values are static numbers. ## Direct XML lineage - `source_sequence`: one-based XML reservation order. - `source_location`: `reservation[N]`. - `source_worksheet`: null. - `source_row_no`: null. - `channel_key`: deterministic downstream channel fact; it is not an XML source worksheet. ## Derived keys ```text normalized_rate_code = upper(trim(rate_code)) group_code_key = upper(trim(res_comment)) company_key = deterministic company keyword normalization ``` When trimmed `RES_COMMENT` is empty, `group_code_key` is null and `booking_source_match_status` is `missing_group_code`. Never substitute `BLOCK_CODE`, confirmation number, or another value. ## Required whitelist-candidate values `RATE_CODE`, `COMPANY_NAME`, `CONFIRMATION_NO`, `DISP_ROOM_NO`, `EFFECTIVE_RATE_AMOUNT`, `FULL_NAME`, `ADULTS`, `CF_CHILDREN`, `NO_OF_ROOMS`, `ARRIVAL`, and `DEPARTURE` must be present and valid. `BLOCK_CODE`, `PRODUCTS`, `ROOM_CATEGORY_LABEL`, `RES_COMMENT`, and `TRACE_TEXT` may be blank. The complete record field list and conditional nullability rules are authoritative in [structured-result.schema.json](structured-result.schema.json).