Files
ARR-2.0-0918/arr_web/DIRECT_DATA_ENTRY.md

198 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 按日期获取接口数据并生成 ARR
2026-10-08:本机已连接生产酒店57106。直接数据入口与XML上传共用处理规则;已确认的取消预订及PM房型排除同时适用于两条路径。
已在本机离线重放2026-10-07到店日的真实生产捕获:176次读取、58条预订,字段识别和来源顺序与捕获一致。
10月7日字段及价格核对现已完成,系统保存生成成功的38间房日报结果;实际日报文件及月报尚未逐项完成业务验收,不能宣称所有生产场景已通过。
接口数据沿用共用筛选、去重、定价、独立校验和Finance提交规则,不生成中间XML。
本文描述当前代码;部署与服务状态以[交付说明](../deploy/OHIP_RELEASE_HANDOVER.md)和对应部署记录为准。
## 使用流程
选择报表日期 → 点击“下载并处理” → 完整获取该日数据 → 如有阻塞字段则人工完善并确认 → 原规则处理与独立核对 → 如缺价则沿用价格复核 → Finance日报进入历史,月报自动更新。
点击日期文字或右侧日历图标,再点击日历中的某一天即可选择。任务进行中仍可预选下一日期;
当前任务结束后需再次点击下载,预选不会自动提交或修改原任务。页面进度始终显示原任务的日期。
任务结果待确认时,先检查或继续按钮上标明日期的原任务,避免重复提交。
某一天等待人工完善不阻塞其他日期:另选日期后可点击“下载并处理”,此前字段或价格任务仍保存在“需处理日期”中。
点击需处理日期可返回该日的“人工核对”,刷新后列表仍保留;同一天的未完成任务沿用原编号。
人工核对页面只展示预订编号、字段名、输入和确认操作;价格核对保留公司、费率代码、Opera价、人工价格和保存操作。页面不展示来源/规则解释或取消、PM排除数量,相关原始数据和审计仍保留。字段完善在下载卡片仅保留蓝色主按钮,必填/留空限制、保存校验和生成门槛不变。
切换字段任务保留各自草稿,未保存的价格会阻止切换核对任务;刷新或切换语言前仍应保存输入,已保存决定长期保留。
完整采集中的缺字段、多个候选或不满足原规则的字段先进入“待完善数据”(`needs_data_review`)。
全部阻塞字段通过并确认后,原任务自动继续处理;随后只有缺少pureprice时进入原有价格复核(`needs_review`)。
字段完善和价格复核是前后两步,不会用补零或未经确认的空值跳过前一步。
价格核对允许明确保存0,空白不等于0;原始Oracle价格为0也不代表处理价必定为0。
任务中断后“继续原任务”复用原始数据和结果,同一请求不会重复入库。历史来源显示“接口获取”。
自动下载卡片显示取数状态、进度条及“已获取笔数/总笔数”。预订总数未确定时不显示虚构百分比;
逐笔取得关联资料后更新计数,全部取回仍须核对完整性,通过并保存完成记录后才显示100%和“已完成”。
失败或中断会单独提示;取数完成不表示人工核对或报表生成完成。旧任务如没有自己的取数记录,会明确显示笔数未记录。
备注使用清理表情后的第一条非空预订备注;套餐按原顺序显示套餐代码(逗号分隔,保留重复)。
完整备注、套餐明细和查询出处保留在原始数据中。Trace 不获取,旧报表对应列留空。
这是一套明确的新入口显示规则,不声明与 Oracle 原生报表的文字格式完全一致。
## 日报覆盖、删除与日期概览(2026-10-09)
日报列表按业务日期展示,一天只展示一行。接口取数和XML上传遵循相同的覆盖规则:新版本成功生成并入库后,才替换该日有效日报并更新月报;新版本尚待核对或失败时,原有效日报仍可下载并继续计入月报。
点击列表中的日期,可查看该日概览;上方日期与房数始终对应当前查看日期。待处理新版本会单独提示,尚无有效日报时显示空值,不借用其他日期的成功结果。
顶部概览提供“自动下载 ARR、上传 ARR.XML、ARRIVAL DATE、NO. OF ROOM、本月报表情况”五个区域,顶部不再展示处理耗时。宽屏卡片行宽度约为原来的2/3,上传与日历标题、内容对齐,小屏按可用宽度自动排列。“本月报表情况”默认收起,显示月份和已生成天数;点击带日历图标的月份按钮展开月历,支持切换月份。每一天按是否存在当前有效日报标为“已生成”或“未生成”,已有报表的日期显示为绿色。历史版本、已删除版本和仅待核对的任务不算已生成;已有有效日报、另有待核对新版本时,仍标为已生成。读取中或读取失败会单独显示,不把未知状态当作未生成。
点击日历日期只切换查看日期和日报列表月份,不会获取Oracle数据、生成报表或提交人工核对值。需要下载新数据时,仍须在自动下载入口主动提交;未保存的人工价格继续受切换保护。日历月份与列表分页独立,显示整月状态;生成或删除后的刷新会更新标记。
存在历史版本时显示“历史记录”入口,保留同一天的旧版本和未完成版本;数量为0时不显示该按钮。删除前页面会说明影响:
- 删除当前有效日报:该日从月报中移除,系统自动生成剩余日期的月报;整月已无有效日报时,撤下该月报。旧日报不会自动恢复。
- 删除历史版本或待价格核对版本:保留当前有效日报,月报不变。运行中的版本须等任务停止后再删除。
删除会保留原始数据及操作记录,已删除记录不能继续下载或处理;如需重新纳入,可重新上传或提交新的取数请求。此功能不提供撤销删除按钮。
页面使用`GET /api/daily-reports`按日期分页、`GET /api/daily-reports/{date}`读取所选日期、`GET /api/daily-reports/{date}/history`读取历史;删除使用`DELETE /api/jobs/{job_id}`,正文为`{"business_date":"YYYY-MM-DD"}`,沿用登录及CSRF保护,并记录当前操作者。原`GET /api/jobs`仍供任务记录查询使用。
## 字段完善的保存与继续处理
`DataFieldReviews`只接受`collection_complete=true`的完整采集,以当前冻结处理器的费率白名单和字段验证识别阻塞项。
预订列表仍保留全部取得的记录及原顺序;非白名单记录按原规则处理,不因Cancelled/NoShow等状态在取数阶段被丢弃。处理阶段先排除已取消预订,再排除PM房型,之后识别其余候选的待完善字段;NoShow没有新增排除规则。
费率本身未确定时先完善费率,再重新识别该记录的其余问题。查询失败或采集不完整仍走原重试流程。
人工仅能完善任务列出的异常字段。团队代码、预订备注、套餐和房型允许明确“确认无此项”;
公司、房号及其他必填字段必须填写有效值。团队/套餐的正常省略仅在成功查询、请求内容及关联证据满足明确条件时识别为空,
不要求用户逐项确认正常空值;团队关联单侧省略、套餐缺少有效佐证、读取失败、冲突或格式不明仍需核对,其他字段不采用这一省略规则。
具体条件见[关联空值依据](../.project-docs/50-evidence/topics/20261008-production-review-9e7b__oracle-optional-associations.md)。
套餐金额为零不能证明无套餐,`roomCalendar={}`也不能证明目标日期没有房号。
每次保存核对当前`revision`,记录操作者、原值、新值和事件版本;旧版本提交会返回冲突,须重新查看。
所有阻塞项通过后,确认操作冻结`reviewed-source.json`及审计绑定,并将同一请求重新排队。
后续从已保存来源继续,不重新获取订单、不改写原始捕获。冻结后不能再修改字段,重复确认或恢复不会重复提交日报。
正常完整输入无需人工步骤,直接进入原处理链路。
旧任务若因已核实的来源解释或取消/PM排除而清空整张字段清单,系统会重新验证来源依据,
以系统身份保存处理记录并自动继续同一请求,不再要求对0项字段点击确认。服务重启会恢复这种已滞留的任务,
仍使用已保存的原始数据,不重新取数。清单仍有人工核对项的任务,即使已全部填写,也保留“确认并生成日报”;
后续若缺少处理价,仍进入正常价格核对,系统不代填价格。
字段完善后端接口归属于ARR自身,沿用网页登录权限与POST的CSRF保护;它们不向Oracle写入业务资料:
| 操作 | ARR接口 | 正文 |
|---|---|---|
| 读取待完善清单 | `GET /api/arr-downloads/{request_id}/data-review` | 无 |
| 保存一项字段 | `POST /api/arr-downloads/{request_id}/data-review/items/{item_id}` | `{"revision":0,"value":"<有效值>"}`;套餐值为有序代码数组 |
| 确认并继续生成 | `POST /api/arr-downloads/{request_id}/data-review/finalize` | `{"revision":1}`;使用最近返回版本 |
字段完善期间尚未生成处理job或写入Finance。确认后才执行原筛选、去重、定价、独立校验与处理交付;
如果进入后续价格复核,Finance日报仍等待价格确认。最终提交继续触发原月报更新。
缺少Opera有效房价属于前面的来源字段问题;缺少pureprice属于后面的定价复核,不能相互替代。
## 生产请求兼容与当前验收边界
结构化到店查询只发送`arrivalStartDate`、`arrivalEndDate`、`limit`、`offset`,省略生产拒绝的可选排序。
生产默认排序规则尚未证实,因此保留接口返回顺序,并在完整分页及补查后逐项比较首尾两次完整列表。
每轮验证重复预订ID、总数、页数和末页完整性;首尾一致仍不是原子快照的证明。
姓名摘要使用`GET /api/v1/profiles?profileIds=P&summaryInfo=true&limit=1&offset=0`,只查已关联唯一主客的精确档案ID。
严格核对`operation_id=getProfiles`、酒店、Oracle请求编号、唯一档案结果和姓名组成;不再使用生产不可用的`searchProfiles` POST。
历史候选捕获及POST探针保留原请求,详细参数见[传参确认单](../ARR_OHIP_REQUEST_PARAMETERS.md)。
58条原始采集的首次解析曾列团队代码36项、套餐16项、公司2项、房号1项缺口;原始响应仍完整保留。
后续按有依据的关联空值识别及已批准的取消/PM排除规则重新解释,10月7日不再需要字段补充,并已完成价格核对及生成。
这些历史缺口数不等于当前人工必填项,也不代表接口故障;不据此宣称任意字段省略都可自动留空。
## 历史本机 OHIP 沙箱入口(2026-09-18)
以下保留2026-09-18的沙箱配置与运行方式,不代表当前生产服务状态。
历史[本机地址](http://127.0.0.1:8875/)沿用当时账号密码。酒店OHIPSB02、平台地址、应用凭据路径已配置;
本机数据库和报表单独保存,人工XML上传保留。平台同事已补齐团队资料读取权限`blocks.read`,
2026-09-18 06:00Z核对所需权限齐全,下载按钮已启用;见[补权记录](../integrations/ohip/PLATFORM_ACCESS_REQUEST.md)。
当轮只检查权限和页面就绪状态,没有提交真实下载任务;用户选日期并点击后才会查询。
实例使用`arr_web.local_ohip`,启动只核对本机配置和凭据,不调用酒店接口。
`check-access`只读取平台开发身份、应用列表和密钥状态,不改权限、不签发密钥、不查询订单;
成功后更新本机`access.json`。已运行页面下次加载配置即可识别新权限,无需重启或重新部署。
刷新核对失败会暂停新下载,缺权时服务仍可登录,但创建/重试任务均拒绝,防止半途缺字段。
凭据、原数据、队列及报表都在仓库外的私有目录,具体位置见[本轮记录](../.project-docs/50-evidence/topics/2026-09-18-arr-ohip-activation.md)。
```sh
# 新建本机实例;沿用原登录时可额外传 --login-file /private/old-instance/login.json
.venv/bin/python -m arr_web.local_ohip init \
--parent '/private/arr-instances' --credential-file '/private/ohip-credentials/application.json'
# 仅核对平台权限;不查询订单。需要已授权的开发身份文件。
.venv/bin/python -m arr_web.local_ohip check-access \
--root '/private/arr-instances/ohip-sandbox-INSTANCE' --automation-file '/private/ohip-credentials/automation.json'
LC_ALL=C LANG=C .venv/bin/python -m arr_web.local_ohip serve \
--root '/private/arr-instances/ohip-sandbox-INSTANCE' --port 8875
```
后台运行使用该实例`service.plist`,由用户会话launchd保持,不依赖对话进程;未安装开机启动项。
8873/8874未操作,原8875模拟实例已停止但完整保留,可恢复。
## 已完成的本机模拟验收(历史)
原8875模拟入口已由上述沙箱配置入口替换。历史验收使用6笔虚构订单,日期2026-09-15;
当时页面顶端明确标注“未连接 Oracle”,模拟记录未迁入新的沙箱实例。
登录信息保存在当前实例的 `login.json`,不写入仓库或日志。
本轮实例位置见[验证记录](../.project-docs/50-evidence/topics/2026-09-18-arr-direct-processing.md)。
它与8873/8874实例、原有业务数据库和对象存储完全独立。
可创建新的模拟实例(无需 OHIP 凭据):
```sh
.venv/bin/python -m tests.direct_data_portal init
# 将上一行返回的私有目录填入下面的路径
.venv/bin/python -m tests.direct_data_portal serve --root /absolute/private/instance --port 8875
```
模拟测试使用仓库内明确标记的虚构接口响应,不代表实际沙箱取数验证。
## 正常运行配置
当前处理器4.4.0要求数据库按顺序具备019、020、021迁移。本机已升级至021;目标部署需独立检查和备份。
019支持真实的 `ohip_json` 源制品和5.0结果,020/021分别支持取消与PM排除事实。
启动会先检查迁移,未具备条件时不开放下载服务。原来的月报后台程序仍须正常运行。
```sh
.venv/bin/python -m arr_web.run --enable-processing \
--ohip-hotel-id OHIPSB02 \
--ohip-credential-file /absolute/private/ohip-credentials.json \
--ohip-state-root /absolute/private/arr-data-state
```
以上三个 OHIP 参数必须一起提供;数据库、对象存储、网页登录沿用现有私有配置。
凭据文件仅在实际点击获取数据时读取,不在启动时查询酒店。
私有任务目录须在仓库之外,并绑定酒店、来源类型、查询上限和处理规则;规则更换后通常使用新目录;同环境尚未进入处理且未冻结的待完善任务,可在停服务、备份和逐文件升级收据保护下显式接续,不能悄悄改绑。旧版本未完成的价格复核遵循原有“规则已变更”保护。
也支持 `DirectARRSource` 注入共享运行依赖。原有 `CapturedARRSource` 为历史 XML 模式保留,
它不再是新数据入口的前置条件。不得把模拟传输当成实际平台传输。
取数字段和八项只读操作见[数据入口说明](../integrations/ohip/DATA_SOURCE.md)。
每个运行实例仍须核对其实际环境权限。当前生产捕获已用于字段识别,目标部署后的日报/月报文件仍须完成实际业务验收。
`getBlock` 等补查如无权限会明确失败,不补造空值。
## 检查
```sh
ARR_TEST_LOCAL_POSTGRES=1 .venv/bin/python -m unittest tests.test_arr_direct_data tests.test_arr_data_review -v
```
检查覆盖6笔正常订单总额18200、字段完善后继续处理、既有缺价复核、必填及可空字段验证、去重、原始数据保留、独立报表核对、
字段修订冲突与冻结恢复、页面请求、月报公式、提交后断线恢复、来源版本隔离,以及019至021迁移检查和回退保护。
浏览器检查:`tests/browser/arr_direct_data.cjs`,只接受明确指定的本机模拟实例。
历史8875沙箱曾交给用户会话后台服务运行,避免对话结束后登录页无法连接。仅在用户会话运行;
该历史OHIP沙箱的停止命令为 `launchctl bootout gui/$(id -u)/com.arr.local-ohip.8875`。服务配置位于私有实例的
`service.plist`;重新加载使用 `launchctl bootstrap gui/$(id -u) /absolute/private/instance/service.plist`。
后台环境已设 `LC_ALL=C`、`LANG=C`。先停后台服务再使用前台serve命令,不同时启动两份。
## 已取消预订(2026-10-08确认)
日报排除已取消预订,无论是否已有房号。取消单不要求补房号或其他报表字段,不参与去重、定价及月报;完整原始数据和排除原因保留。
接口使用已核对一致的查询与详情预订状态;旧待完善任务可由内部维护操作从原始完整捕获补充状态,不重新查询Oracle,不修改原始数据或人工决定。XML使用明确的取消状态值CXL/CANCELLED/CANCELED;CA等未确认缩写不猜测。
取消排除由4.3.0/迁移020引入;当前4.4.0还需迁移021。旧已发布结果不重新处理。
## PM房型(2026-10-08确认)
XML和接口数据均在取消排除后、必填校验/去重/定价前排除PM。按共用文本规范化后的房型代码匹配PM,
不凭房号前缀、价格0、计价房型或空房型推断;其他房型不自动排除。原始数据、排除原因及此前人工决定仍可追溯。
Finance需应用`database/021_daily_pm_exclusion.sql`,Web和4.4.0处理器一起更新;旧已发布结果不自动重跑。