发布时间: 2026-01-21 分类: Oracle EBS / Order Management 标签: #OracleEBS #CreditCheck #Troubleshooting #SQL
🔴 问题现场
最近在支持业务时,遇到了一个非常棘手的信用暂挂(Credit Hold)问题。
场景描述: 销售创建了一个新订单(Order#: 19008719),保存后立即被系统暂挂。
暂挂名称:
Credit Check Failure暂挂原因:
This hold is automatically placed on an order invoiced to a customer who fails credit check系统备注:“客户存在逾期发票!”
奇怪的地方在于: 当我检查该订单“收单方(Bill-To Customer)”的账户情况时,发现:
信用额度充足:可用额度远大于订单金额。
无逾期发票:该账户名下所有发票均在账期内。
疑问: 既然当前下单客户看起来“身家清白”,为什么 EBS 系统一口咬定它有逾期发票,并死死锁住订单?
🔍 排查过程:抽丝剥茧
为了找出真相,我并没有停留在表面的 SQL 查询上,而是进行了深入的“侦探工作”:
1. 第一层:直觉的误区
起初,我通过 ar_payment_schedules_all 关联订单的收单地点(invoice_to_org_id),结果查无数据。这让我一度怀疑是系统缓存问题。
2. 第二层:寻找“案发现场”
我查询了 OE_HOLD_SOURCES_ALL 表,发现了一个关键线索:
暂挂对象(Hold Entity) 是
CUSTOMER(账户级),而非SITE(地点级)。关键点:被锁定的
hold_entity_id竟然与订单上的收单方 ID 不完全一致。
3. 第三层:真相大白(家族连坐)
顺着这个线索,我查询了该客户所在的 Party(组织关系) 下的所有关联账户。真相令人震惊:
虽然下单的子公司(A公司)信用良好,但在同一个集团下的**兄弟公司(关联公司 B,账户 C000XXX)**名下,存在大量的逾期发票。
逾期天数:20 天
逾期总额:高达 870 万 元!
结论: 系统的信用检查规则配置了**“检查客户层级”或“全局检查”。这是典型的“子债父偿”**机制。只要集团内有任意一个账户存在烂账,EBS 信用引擎就会无差别锁住该集团下所有公司的订单。
此外,通过 SQL 确认,该订单类型配置的信用规则对逾期天数采取**“零容忍”**策略(OPEN_AR_DAYS = 0),这意味着只要逾期一天,订单就会立即被锁。
🛠️ 解决方案 & SQL 工具箱
为了避免大家以后再走弯路,我整理了这两段经过实战验证的 SQL 脚本。
脚本 1:一键查询导致暂挂的“真凶”(含关联方检查)
此脚本是本次排查的核心。它会自动跳出“单一收单方”的限制,直接扫描该 Party 下所有关联账户的逾期情况,揪出导致连坐的源头。
SQL
SELECT h.order_number AS 订单号,
-- 下单方信息
p_bill.party_name AS 下单客户名称,
-- 实际欠款方信息 (导致暂挂的真凶)
p_debt.party_name AS 欠款账户名称,
ca_debt.account_number AS 欠款账户账号,
-- 违规详情
aps.trx_number AS 逾期发票号,
aps.due_date AS 到期日,
trunc(SYSDATE) - trunc(aps.due_date) AS 实际逾期天数,
to_char(aps.amount_due_remaining, 'FM999,999,999.00') AS 剩余欠款
FROM oe_order_headers_all h
-- 1. 从订单找到下单方 Party
JOIN hz_cust_site_uses_all su
ON h.invoice_to_org_id = su.site_use_id
JOIN hz_cust_acct_sites_all cas
ON su.cust_acct_site_id = cas.cust_acct_site_id
JOIN hz_cust_accounts ca_bill
ON cas.cust_account_id = ca_bill.cust_account_id
JOIN hz_parties p_bill
ON ca_bill.party_id = p_bill.party_id
-- 2. 核心逻辑:找该 Party 下所有的账户 (兄弟公司/分公司)
JOIN hz_cust_accounts ca_debt
ON ca_debt.party_id = p_bill.party_id
JOIN hz_parties p_debt
ON ca_debt.party_id = p_debt.party_id
-- 3. 查这些账户的 AR 逾期
JOIN ar_payment_schedules_all aps
ON aps.customer_id = ca_debt.cust_account_id
WHERE h.order_number = '&Enter_Order_Number' -- 输入订单号
AND aps.status = 'OP' -- 未结清
AND aps.amount_due_remaining > 0 -- 有欠款
AND aps.class IN ('INV', 'DM') -- 只看发票和借项通知单
AND (trunc(SYSDATE) - trunc(aps.due_date)) > 0 -- 只要逾期就列出来
ORDER BY aps.due_date ASC;
脚本 2:查询当前订单生效的信用规则
很多时候我们不确定系统到底是允许逾期 0 天还是 5 天。这个脚本可以快速查看当前订单类型绑定的规则配置。
SQL
SELECT
h.order_number AS 订单号,
ott_tl.name AS 订单类型,
ccr.name AS 规则名称,
-- 核心配置:允许逾期天数
-- 解释:系统只会看这个数字。如果为空或0,代表“零容忍”(只要有逾期就暂挂)。
NVL(ccr.open_ar_days, 0) AS 最大逾期天数
FROM
oe_order_headers_all h
-- 1. 关联类型翻译表获取名称
JOIN oe_transaction_types_tl ott_tl
ON h.order_type_id = ott_tl.transaction_type_id
AND ott_tl.language = USERENV('LANG')
-- 2. 关联类型定义表获取规则ID
JOIN oe_transaction_types_all ott_all
ON h.order_type_id = ott_all.transaction_type_id
-- 3. 关联信用规则
-- 这里查看的是“预订(Booking)”时的规则
-- 如果是发运暂挂,请改为关联 shipping_credit_check_rule_id
LEFT JOIN oe_credit_check_rules ccr
ON ott_all.entry_credit_check_rule_id = ccr.credit_check_rule_id
WHERE
h.order_number = '&Enter_Order_Number';
💡 经验总结
额度 vs 逾期: 信用检查是双轨制的。额度够不代表不会被锁,只要有逾期发票(触碰逾期红线),订单照样会 Hold。
不要只看表面: 当单一账户查不出问题时,一定要想到 Oracle EBS 强大的**关系网(Relationship)**检查功能。
技术排查思路: 永远先看
OE_HOLD_SOURCES,让系统告诉你它在惩罚谁,而不是自己去数据库大海捞针。
评论区