ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

EBS INV 标准API实战:现有量、保留量、可用量计算(一)配 TaoToken 统一 Key 通道

EBS INV 标准API实战:现有量、保留量、可用量计算(一)配 TaoToken 统一 Key 通道 1. EBS INV 库存三量计算到底难在哪EBS INV 模块里现有量、保留量、可用量这三个数字看着简单实际写接口时经常对不上账。现有量On-hand Quantity是物理上躺在子库里的数量保留量Reserved Quantity是被订单、工单、调拨单等需求占住的数量可用量Available Quantity才是真正能拿来分配的部分。三者关系一句话现有量 可用量 保留量。但落到 Oracle EBS 的标准 API 上这个等式会因为批次、子库、货位、序列号、成本组等维度拆得七零八落。面向 Oracle EBS 开发与集成场景这篇聚焦一件事用标准 API 把这三个量查准并且把调用链路接到 TaoToken 统一 Key 通道上让本地脚本、CI 环境、Agent 工具都能用同一套凭证访问模型能力做联调辅助。适合正在做 INV 接口联调的 EBS 开发、集成工程师以及需要把库存查询封装成服务对外输出的团队。我试过直接拼 SQL 查 mtl_onhand_quantities结果和界面数字差一截原因是没走 inv_quantity_tree_pub 的树形汇总逻辑。标准 API 的价值就在这里它把批次、货位、子库的层级关系算好了再返回。下面从环境准备开始一步步把可复制的配置和验证动作给出来。2. TaoToken 前置统一 Key 通道准备在写 PL/SQL 调用之前先把模型侧的访问通道理清楚。做 EBS 接口联调时经常需要让脚本或 Agent 帮忙解释报错、生成测试数据、比对返回结构这时候一个统一的 Key 通道能省掉到处配环境变量的麻烦。TaoToken 的定位是统一模型接入通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。你需要先在控制台创建 API Key控制台地址 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。拿到 Key 之后不管是本地 VS Code 里的 Claude Code 插件还是自己写的 Python 联调脚本都指向同一个 base_url不用为每个工具单独申请。这里要区分两个概念EBS 的 INV API 是 Oracle 数据库层的 PL/SQL 包TaoToken 是模型访问通道两者不在一层。TaoToken 的作用是让你在写 INV 接口时有个稳定的模型侧入口来辅助生成代码、排查 ORA 报错、解释 API 返回结构。别把 TaoToken 当成 EBS 的数据库连接代理它不是干这个的。如果你用的是 Claude Code 做 EBS 开发辅助可以参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 的接入说明。需要长期跑编码任务或 Agent 流程的看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。只是想验证模型返回是否符合预期的用模型对话 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 快速试。3. 可复制配置settings.json 与 API 调用骨架3.1 settings.json 统一 Key 配置把 Key 写进项目级 settings.json避免每次手动 export。下面这份配置可以直接复制把sk-你的Key替换成控制台生成的值{ env: { TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_MODEL: claude-sonnet-4-20250514 }, permissions: { allow: [ Bash(sqlplus:*), Read(//eBS/**) ] } }这份配置放在项目根目录的.claude/settings.json或对应工具的配置路径下。TAOTOKEN_BASE_URL固定指向 https://taotoken.net/api 不要加 UTM 参数那是给网页跳转用的。Key 只放环境变量别硬编码进 PL/SQL 或提交到 Git。3.2 INV 现有量查询骨架现有量走inv_quantity_tree_pub.query_quantities核心是把批次维度传对。下面这段是可直接在 SQL*Plus 或 PL/SQL Developer 里跑的匿名块骨架DECLARE l_return_status VARCHAR2(1); l_msg_count NUMBER; l_msg_data VARCHAR2(2000); l_qoh NUMBER; l_rqoh NUMBER; l_qr NUMBER; l_qs NUMBER; l_att NUMBER; l_atr NUMBER; l_onhand NUMBER : 0; p_organization_id NUMBER : 207; p_inventory_item_id NUMBER : 10001; p_subinventory_code VARCHAR2(30) : FG-STORE; BEGIN FOR rec_loc IN ( SELECT mln.lot_number, mln.expiration_date FROM mtl_lot_numbers mln WHERE mln.inventory_item_id p_inventory_item_id AND mln.organization_id p_organization_id ) LOOP inv_quantity_tree_pub.query_quantities( p_api_version_number 1.0, p_init_msg_lst NULL, x_return_status l_return_status, x_msg_count l_msg_count, x_msg_data l_msg_data, p_organization_id p_organization_id, p_inventory_item_id p_inventory_item_id, p_tree_mode 3, p_is_revision_control FALSE, p_is_lot_control TRUE, p_is_serial_control FALSE, p_revision NULL, p_lot_number rec_loc.lot_number, p_lot_expiration_date rec_loc.expiration_date, p_subinventory_code p_subinventory_code, p_locator_id NULL, p_cost_group_id NULL, p_onhand_source inv_quantity_tree_pvt.g_all_subs, x_qoh l_qoh, x_rqoh l_rqoh, x_qr l_qr, x_qs l_qs, x_att l_att, x_atr l_atr ); IF l_return_status fnd_api.g_ret_sts_success THEN l_onhand : l_onhand NVL(l_qoh, 0); ELSE DBMS_OUTPUT.PUT_LINE(Error: || l_msg_data); END IF; END LOOP; DBMS_OUTPUT.PUT_LINE(On-hand total: || l_onhand); END; /几个参数要盯紧p_tree_mode 3表示按批次汇总p_is_lot_control TRUE必须和物料是否启用批次控制一致否则返回 0p_onhand_source inv_quantity_tree_pvt.g_all_subs表示包含所有子库来源。x_qoh是现有量x_rqoh是可保留量x_qr是保留量x_qs是可用量后三个别搞混。3.3 保留量查询骨架保留量在标准 API 里没有单一函数直接给全通常要拼mtl_reservations和mtl_material_transactions_temp两张表。下面这段是常见写法SELECT NVL(SUM(qty), 0) INTO l_reserv FROM ( SELECT mr.reservation_quantity qty FROM mtl_reservations mr, mtl_system_items_b msi WHERE mr.demand_source_type_id 2 AND mr.inventory_item_id msi.inventory_item_id AND mr.organization_id msi.organization_id AND mr.subinventory_code p_subinventory_code AND msi.inventory_item_id p_inventory_item_id AND msi.organization_id p_organization_id UNION SELECT mmt.transaction_quantity qty FROM mtl_material_transactions_temp mmt, mtl_system_items_b msi WHERE mmt.transaction_source_type_id 2 AND mmt.subinventory_code p_subinventory_code AND mmt.inventory_item_id msi.inventory_item_id AND mmt.organization_id msi.organization_id AND msi.inventory_item_id p_inventory_item_id AND msi.organization_id p_organization_id );demand_source_type_id 2是排除销售订单来源因为 SO 的保留逻辑在 OM 模块单独算。如果你的场景要包含 SO 保留把这个条件去掉但要注意和 OM 的接口对账。3.4 可用量计算可用量 现有量 - 保留量。但 EBS 里可用量还受 ATP 规则、子库净需求影响严格场景要用inv_quantity_tree_pub返回的x_qs。简单场景直接减l_available : NVL(l_onhand, 0) - NVL(l_reserv, 0);如果x_qs和这个减法结果对不上说明有 ATP 规则或子库属性在起作用要去查mtl_parameters和mtl_item_sub_inventories的availability_type。4. 验证请求与成功结果配置写完先做最小验证。第一步确认 TaoToken 通道通curl -s https://taotoken.net/api/v1/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ | head -c 300返回 JSON 里能看到模型列表说明 Key 和 base_url 都对。这一步不通后面 PL/SQL 报错时你分不清是 EBS 问题还是通道问题。第二步跑 3.2 的匿名块把p_organization_id、p_inventory_item_id、p_subinventory_code换成你环境里的真实值。成功时DBMS_OUTPUT会打印On-hand total: 数字l_return_status为S。如果返回E看l_msg_data里的具体错误。第三步拿界面数字对账。在 EBS 的「物料现有量查询」界面输入同样的组织、物料、子库把界面显示的现有量、保留量、可用量和 API 返回值逐项比对。差异在 0.001 以内算正常差得多说明维度没对齐。第四步用模型对话快速解释返回结构。把 API 返回的x_qoh、x_rqoh、x_qr、x_qs贴到 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 让它帮你确认每个字段的业务含义比自己翻文档快。5. 本篇常见错排查5.1 现有量返回 0 但界面有数最常见原因是p_is_lot_control传错。物料启用了批次控制你传FALSEAPI 就按无批次维度查结果自然是 0。反过来物料没启用批次你传TRUE并传了p_lot_number也会查不到。去mtl_system_items_b看lot_control_flag1是启用2是不启用。5.2 保留量偏大检查demand_source_type_id的排除条件。如果你的业务要排除 SO 保留但漏了 2SO 的保留会被重复计入。另外mtl_material_transactions_temp里可能有未处理的事务临时记录这些也会被算进保留量联调阶段可以先加AND mmt.transaction_status 3过滤掉已取消的。5.3 ORA-06502 或字符集报错l_msg_data长度不够或者p_lot_number传了超出字段长度的值。把l_msg_data声明成VARCHAR2(2000)以上p_lot_number做SUBSTR截断。EBS 的mtl_lot_numbers.lot_number一般是VARCHAR2(80)别超。5.4 TaoToken 返回 401Key 没读到或过期。检查settings.json里的TAOTOKEN_API_KEY是否被 shell 环境覆盖echo $TAOTOKEN_API_KEY看实际值。Key 管理页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 可以重新生成。注意 base_url 不要带末尾斜杠https://taotoken.net/api后面直接接/v1/models。5.5 可用量和现有量减保留量对不上这是 ATP 规则在起作用。查mtl_item_sub_inventories.availability_type如果是2ATP 可用可用量要按 ATP 规则算不能简单相减。这种场景直接用x_qs返回值别自己减。6. 后续联调与通道选择现有量、保留量、可用量三个数查准之后下一步是把这套逻辑封装成可复用的存储过程或 REST 服务。封装时建议把组织、物料、子库、批次作为入参返回结构里同时带上x_qoh、x_qr、x_qs让调用方自己决定用哪个。联调过程中如果遇到 ORA 报错或返回结构看不懂用模型对话 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 快速问。需要把 INV 接口接入文档整理成规范格式的看接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。长期做 EBS 接口开发和 Agent 自动化的Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 能省掉反复配 Key 的功夫。最后提醒一句inv_quantity_tree_pub.query_quantities在批次多的时候循环调用会慢生产环境建议先批量取批次列表再一次性传数组或者直接用inv_quantity_tree_pvt的批量接口。这个坑我在数据量大的组织里踩过单批次循环查 2000 个批次能跑几分钟改成批量后降到秒级。
返回列表