# 按日期取得 ARR 业务数据 2026-09-18。字段接口连接已实现,输入一个到店日期,输出完整预订的 15 个业务字段及关联资料。 自动入口不取 Trace,不生成 XML,不提前执行白名单、去重、定价或入库。 当前8接口的实际路径、参数、来源与条件见[传参确认单](../../ARR_OHIP_REQUEST_PARAMETERS.md),供用户逐项确认。 本次按用户要求跳过实际沙箱订单验证。41 项新增本机检查及相关回归共 150 项通过, 其中包括真实的本机 HTTP 通信;没有读取平台凭据、查询沙箱订单、修改应用权限或运行实例。 6 笔模拟订单直接交给既有定价函数,结果符合原有预期,总额为 18200。这不是酒店营收或真实接口验收。 ## 提供了什么 - 按用户明确选择的日期,分页取得到店预订,逐笔补齐需要的资料,完成后再次核对预订列表。 - 公司、客人、房价、团队、套餐和房间历史按预订或档案身份关联,原始响应单独保存。 - 备注保留原文、内部备注、多条内容及顺序;套餐保留每一项及其适用日期等资料。 - 正常为空、资料缺失、存在多个候选和查询失败分别记录。 - 相同任务编号完成后直接复用原结果;查询失败后,同编号重试会建立新的取数尝试并保留之前的记录。 - 不读取凭据或访问网络直到调用方明确发起一次尚未完成的取数。 ## 可调用入口 实现:[arr_data.py](arr_data.py) 的 `ARRDataSource.fetch(report_date, request_id)`。 查询封装:[data_client.py](data_client.py)。对外地址仍固定为既有 OHIP 平台,酒店参数只用于核对服务端已配置的酒店。 ```python from pathlib import Path from integrations.ohip.arr_data import ARRDataSource source = ARRDataSource( root=Path("/absolute/private/arr-data"), hotel_id="OHIPSB02", credential_file=Path("/absolute/private/application-credential.json"), ) result = source.fetch(report_date="2026-09-15", request_id="0123456789abcdef0123456789abcdef") ``` 也可从项目根目录调用(以下为使用示例,本次没有执行): ```sh .venv/bin/python -m integrations.ohip.arr_data \ --report-date 2026-09-15 \ --request-id 0123456789abcdef0123456789abcdef \ --hotel-id OHIPSB02 \ --credential-file /absolute/private/application-credential.json \ --output-root /absolute/private/arr-data ``` 输出目录位于仓库外,父目录须已经存在,目录权限 0700、文件 0600。 沿用现有应用凭据格式和身份检查。不同日期或取数范围不能复用同一个任务编号。 需要重新获取已完成任务的最新数据时,使用新编号;缺字段的已完成快照也不会被静默覆盖。 命令只打印状态、数量和文件位置,不打印客人、订单、备注、房号或金额。 ## 已连接的查询 | 用途 | 平台操作 | 调用时机 | |---|---|---| | 当日预订列表 | `searchHotelReservations` | 分页查询,取完后再次核对 | | 预订详情 | `getReservation` | 每笔预订;明确排除 Traces 请求 | | 指定日有效价 | `searchRateInfo` | 每笔预订、用户所选日期 | | 主客完整姓名 | `getProfiles` | GET 精确档案编号,`summaryInfo=true&limit=1&offset=0`,重复档案复用 | | 档案详情 | `getProfile` | 关联公司名称或主客姓名组成资料未嵌入预订时补查 | | 团队代码 | `getBlock` | 已有关联团队编号,但未返回代码时补查 | | 房号及换房资料 | `getRoomCalendar` | 预订资料不能确定房号时,分页查找同一笔预订 | | 套餐资料 | `getPackage` | 预订已提供套餐代码,但未提供完整适用资料时补查 | 上述均为只读操作。已有预订和档案授权覆盖多数查询;团队详情查询另需 `blocks.read`。 本次未修改现有应用授权;若该补查无权限,结果保留为查询失败,不伪装成没有团队。 现有 `integration.json` 的历史授权记录没有被自动扩大。 查询依据是平台 0.11.0 接口目录和完整接口说明;`getProfile` 返回的 `profileIdList/profileDetails`, 以及 `getBlock` 返回的 `blocks.blockInfo[].block`,另按 Oracle 固定版本接口说明核对, 没有从模拟服务反推实际接口结构。 2026-10-08 生产兼容修正:2026-10-07 到店日的只读捕获证明,带可选 `orderBy=ConfirmationNo/sortOrder=Asc` 的查询被拒绝;省略这两个参数后查询成功。 结构化数据入口只发送到店起止日期、`limit`、`offset`,保留每页原始顺序及 `source_sequence`,不自行重排。生产默认排序规则尚未获得证明;完整分页后仍逐项比较 首尾两次列表(含顺序),并验证预订身份、重复 ID、分页总数与末页完整性。 这能检出已观察到的批次变化,但不构成原子快照,也不证明未来分页中的默认顺序固定。 旧的候选捕获/探针入口保留原请求,未静默改变历史证据的含义。 同日生产核对中 `searchProfiles` POST 不可用,`getProfiles` GET 按已关联主客的唯一档案 ID 读取成功。结构化入口使用 GET 并严格核对返回的 `operation_id=getProfiles`、酒店、 Oracle 请求编号、唯一档案 ID、结果数量和姓名组成,不按名称搜索或拼接完整姓名。 这些生产捕获只用于核对请求兼容性,不代表完整日报已验收。 原生可选字段省略仍保留为待确认:`reservationBlock`、`reservationPackages`、 `reservationProfiles` 未返回时不自动视为空,套餐金额为零也不能证明没有套餐。 `roomCalendar={}` 不能证明所选日期没有房号,继续保留房号缺口; Cancelled/NoShow 等状态不会在取数阶段导致预订被丢弃。 ## 返回的数据 `result` 包含 `status`、`collection_complete`、`input_complete`、记录数、各字段状态数量、 `data_path` 和摘要。对应的私有 `arr-data.json` 使用 `arr-ohip-data/v1`,每笔记录包含: - 原始顺序、预订身份。 - 字段名到 `{state, value, reason?}` 的对应关系,恰好包含字段清单中除 Trace 外的 15 项。 - 各关联公司及角色、币种、套餐资料、必要时的房间历史。 - 此记录所用原始响应的文件引用。 `state` 为 `available`(有值)、`empty`(明确为空)、`missing`(未取得)、 `ambiguous`(多个候选)、`failed`(查询失败)。金额保留精确十进制文字,人数和房间数为整数; 备注是有序文字列表,套餐是有序资料列表,不在取数时拼成一个显示字符串。 `source_kind` 区分固定平台连接和注入的测试连接,并固定到任务身份;本机样本不能按同一任务编号改称平台数据。 `collected` 表示本入口已取得完整字段;`collected_with_gaps` 表示预订列表已取完,但存在空必填字段、 缺资料或多个候选;`failed` 表示查询或完整性检查失败。命令退出码分别为 0、2、1。 这些状态均不是日报生成或财务入库成功;`finance_ready` 固定为 false。 公司/旅行社有多个不同名称时保留候选,不擅自定优先级;Group 或 Source 不自动当作公司。 房号只有在既有来源一致,或所选日期的已完整取得历史中只有一个明确房号时才提供单值。 换房存在冲突、历史日期不完整、房间历史只返回页数信息时保留问题。 隐藏价格、缺失价格、错误币种不会转成零或以基础价替换。 ## 与页面及后续处理的关系 已新增 `DirectARRExecutor` / `DirectARRSource`,直接消费本页的数据并衔接固定处理、独立核对、 缺价复核、Finance原子提交和既有月报。原始数据以 `source_data/ohip_json/source.json` 保存, 结果为5.0;原XML结果仍为4.0。`CapturedARRExecutor`继续保留给历史XML模式。 页面及启用说明见[直接数据入口](../../arr_web/DIRECT_DATA_ENTRY.md)。 开发与本机模拟检查已完成,本轮未查询实际沙箱订单、未读取平台凭据、未扩大权限或启用正式环境。