华为MetaERP 跨OU的供应商地点与库存组织映射是P2P多OU架构设计的核心难点之一。Oracle EBS原生并未提供直接的“供应商地点→库存组织”映射表,这需要在扩展层自行设计。下面给出经过生产
跨OU的供应商地点与库存组织映射是P2P多OU架构设计的核心难点之一。Oracle EBS原生并未提供直接的“供应商地点→库存组织”映射表,这需要在扩展层自行设计。下面给出经过生产验证的配置表设计方案。
跨OU的供应商地点与库存组织映射是P2P多OU架构设计的核心难点之一。Oracle EBS原生并未提供直接的“供应商地点→库存组织”映射表,这需要在扩展层自行设计。下面给出经过生产验证的配置表设计方案。
一、为什么需要跨OU映射配置表?
在多OU架构下存在两个天然矛盾:
矛盾点 | 说明 |
|---|---|
供应商地点属于单一OU |
|
库存组织可能跨OU | 一个OU可以管理多个库存组织(INV),但不同OU的库存组织不能互用 |
采购单归属OU ≠ 收货库存组织OU | 例如:深圳OU采购,但货物直接发往香港OU的仓库 |
映射配置表的作用: 建立“采购OU + 供应商 + 供应商地点 → 可收货库存组织列表”的灵活管控关系,同时支持默认值自动推导。
二、核心配置表设计
表1:跨OU供应商地点库存组织映射表(核心)
CREATE TABLE xx_po_supplier_site_inv_map ( map_id NUMBER PRIMARY KEY, -- 采购方维度 purchasing_org_id NUMBER NOT NULL, -- HR_OPERATING_UNITS.ORGANIZATION_ID(采购OU) vendor_id NUMBER NOT NULL, -- PO_VENDORS.VENDOR_ID vendor_site_id NUMBER NOT NULL, -- AP_SUPPLIER_SITES_ALL.VENDOR_SITE_ID -- 库存组织维度 inventory_org_id NUMBER NOT NULL, -- MTL_PARAMETERS.ORGANIZATION_ID(可收货库存组织) inventory_org_ou_id NUMBER, -- 库存组织所属OU(冗余,便于快速过滤) -- 控制属性 default_flag VARCHAR2(1) DEFAULT 'N', -- 'Y'=默认收货组织(同一供应商地点下唯一) enable_flag VARCHAR2(1) DEFAULT 'Y', effective_from DATE DEFAULT SYSDATE, effective_to DATE, -- 业务约束 min_order_amount NUMBER, -- 最低采购金额限制 max_order_amount NUMBER, -- 最高采购金额限制 lead_time_days NUMBER, -- 该供应商→该库存组织的提前期 -- 审计字段 creation_date DATE DEFAULT SYSDATE, created_by NUMBER, last_update_date DATE DEFAULT SYSDATE, last_updated_by NUMBER, attribute_category VARCHAR2(30), attribute1~15 VARCHAR2(150), -- DFF扩展 -- 约束 CONSTRAINT xx_po_supp_site_inv_uk1 UNIQUE (purchasing_org_id, vendor_site_id, inventory_org_id), CONSTRAINT xx_po_supp_site_inv_fk1 FOREIGN KEY (purchasing_org_id) REFERENCES hr_operating_units(organization_id), CONSTRAINT xx_po_supp_site_inv_fk2 FOREIGN KEY (vendor_id) REFERENCES po_vendors(vendor_id), CONSTRAINT xx_po_supp_site_inv_fk3 FOREIGN KEY (vendor_site_id) REFERENCES ap_supplier_sites_all(vendor_site_id), CONSTRAINT xx_po_supp_site_inv_fk4 FOREIGN KEY (inventory_org_id) REFERENCES mtl_parameters(organization_id) ); -- 索引 CREATE INDEX xx_po_supp_site_inv_idx1 ON xx_po_supplier_site_inv_map(purchasing_org_id, vendor_id, enable_flag); CREATE INDEX xx_po_supp_site_inv_idx2 ON xx_po_supplier_site_inv_map(vendor_site_id, inventory_org_id);表2:供应商地点跨OU代理表(解决供应商地点OU归属限制)
Oracle EBS不允许供应商地点直接跨OU,因此需要一个“代理地点”机制:
CREATE TABLE xx_po_cross_ou_vendor_site_proxy ( proxy_id NUMBER PRIMARY KEY, -- 原始供应商地点(属于某个OU) source_vendor_id NUMBER NOT NULL, source_vendor_site_id NUMBER NOT NULL, source_org_id NUMBER NOT NULL, -- 原始地点所属OU -- 目标OU的代理地点(同一物理供应商在不同OU的虚拟地点) target_org_id NUMBER NOT NULL, -- 目标OU target_vendor_site_id NUMBER, -- 目标OU下的供应商地点ID(可为空,自动创建) -- 自动创建标记 auto_create_site VARCHAR2(1) DEFAULT 'Y', -- 是否自动在目标OU创建地点 site_override_name VARCHAR2(240), -- 代理地点名称覆盖 -- 同步控制 sync_address VARCHAR2(1) DEFAULT 'Y', -- 是否同步地址信息 sync_contacts VARCHAR2(1) DEFAULT 'Y', -- 是否同步联系人 sync_bank VARCHAR2(1) DEFAULT 'Y', -- 是否同步银行账户 -- 审计字段 creation_date DATE DEFAULT SYSDATE, created_by NUMBER, last_update_date DATE DEFAULT SYSDATE, last_updated_by NUMBER, -- 约束 CONSTRAINT xx_po_cross_ou_site_uk1 UNIQUE (source_vendor_site_id, target_org_id), CONSTRAINT xx_po_cross_ou_site_fk1 FOREIGN KEY (source_vendor_id) REFERENCES po_vendors(vendor_id), CONSTRAINT xx_po_cross_ou_site_fk2 FOREIGN KEY (source_vendor_site_id) REFERENCES ap_supplier_sites_all(vendor_site_id) );表3:库存组织OU归属视图(加速查询)
虽然可以从HR_ORGANIZATION_INFORMATION解析,但建议物化为配置表:
CREATE TABLE xx_inv_org_ou_mapping ( inventory_org_id NUMBER PRIMARY KEY, inventory_org_code VARCHAR2(10) NOT NULL, inventory_org_name VARCHAR2(240) NOT NULL, owning_ou_id NUMBER NOT NULL, -- 归属OU business_group_id NUMBER, -- 业务属性 is_asset_org VARCHAR2(1) DEFAULT 'Y', is_consumable_org VARCHAR2(1) DEFAULT 'N', default_subinventory VARCHAR2(10), -- 默认收货子库 -- 审计 creation_date DATE DEFAULT SYSDATE, created_by NUMBER, last_update_date DATE DEFAULT SYSDATE, last_updated_by NUMBER, CONSTRAINT xx_inv_org_ou_fk1 FOREIGN KEY (owning_ou_id) REFERENCES hr_operating_units(organization_id) ); -- 初始化脚本(从EBS标准表抽取) INSERT INTO xx_inv_org_ou_mapping ( inventory_org_id, inventory_org_code, inventory_org_name, owning_ou_id, business_group_id ) SELECT mp.organization_id, mp.organization_code, haou.name, TO_NUMBER(hoi.org_information2), -- OU_ID haou.business_group_id FROM mtl_parameters mp JOIN hr_all_organization_units haou ON haou.organization_id = mp.organization_id JOIN hr_organization_information hoi ON hoi.organization_id = mp.organization_id AND hoi.org_information_context = 'Accounting Information' WHERE mp.primary_cost_method IS NOT NULL;三、业务规则校验函数
1. 校验供应商地点是否可用于指定库存组织
CREATE OR REPLACE FUNCTION validate_supplier_site_for_inv_org( p_vendor_site_id IN NUMBER, p_inventory_org_id IN NUMBER, p_purchasing_org_id IN NUMBER ) RETURN VARCHAR2 IS l_count NUMBER; l_err_msg VARCHAR2(4000); BEGIN -- 1. 检查映射表是否存在启用记录 SELECT COUNT(*) INTO l_count FROM xx_po_supplier_site_inv_map WHERE vendor_site_id = p_vendor_site_id AND inventory_org_id = p_inventory_org_id AND purchasing_org_id = p_purchasing_org_id AND enable_flag = 'Y' AND NVL(effective_to, SYSDATE + 1) > SYSDATE; IF l_count = 0 THEN -- 2. 如果没有精确映射,检查供应商地点所属OU与库存组织OU是否一致 SELECT COUNT(*) INTO l_count FROM ap_supplier_sites_all ass JOIN xx_inv_org_ou_mapping iom ON iom.inventory_org_id = p_inventory_org_id WHERE ass.vendor_site_id = p_vendor_site_id AND ass.org_id = iom.owning_ou_id; IF l_count = 0 THEN RETURN 'N'; -- 不合法 END IF; END IF; -- 3. 额外校验:库存组织是否激活 SELECT COUNT(*) INTO l_count FROM mtl_parameters mp WHERE mp.organization_id = p_inventory_org_id AND mp.organization_status = 'ACTIVE'; IF l_count = 0 THEN RETURN 'N'; END IF; RETURN 'Y'; EXCEPTION WHEN OTHERS THEN RETURN 'N'; END validate_supplier_site_for_inv_org;2. 获取默认收货库存组织
CREATE OR REPLACE FUNCTION get_default_inv_org( p_vendor_site_id IN NUMBER, p_purchasing_org_id IN NUMBER ) RETURN NUMBER IS l_inv_org_id NUMBER; BEGIN -- 优先取映射表中的默认值 SELECT inventory_org_id INTO l_inv_org_id FROM xx_po_supplier_site_inv_map WHERE vendor_site_id = p_vendor_site_id AND purchasing_org_id = p_purchasing_org_id AND default_flag = 'Y' AND enable_flag = 'Y' AND NVL(effective_to, SYSDATE + 1) > SYSDATE AND ROWNUM = 1; RETURN l_inv_org_id; EXCEPTION WHEN NO_DATA_FOUND THEN -- 降级:取供应商地点所在OU的第一个激活库存组织 BEGIN SELECT iom.inventory_org_id INTO l_inv_org_id FROM ap_supplier_sites_all ass JOIN xx_inv_org_ou_mapping iom ON iom.owning_ou_id = ass.org_id WHERE ass.vendor_site_id = p_vendor_site_id AND ROWNUM = 1; RETURN l_inv_org_id; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NULL; END; END get_default_inv_org;四、PDOI接口填充时的自动推导逻辑
在多OU自动创建PO时,用上述配置表自动填充PO_LINE_LOCATIONS_INTERFACE.SHIP_TO_ORGANIZATION_ID:
-- 在填充Shipment时自动推导库存组织 l_inv_org_id := get_default_inv_org( p_vendor_site_id => l_req_data(i).vendor_site_id, p_purchasing_org_id => ou_rec.organization_id ); IF l_inv_org_id IS NULL THEN -- 无法推导默认值,记录错误并跳过 apps.fnd_file.put_line(FND_FILE.LOG, 'ERROR: No valid inventory org for vendor site ' || l_req_data(i).vendor_site_id); CONTINUE; END IF; -- 校验合法性 IF validate_supplier_site_for_inv_org( p_vendor_site_id => l_req_data(i).vendor_site_id, p_inventory_org_id => l_inv_org_id, p_purchasing_org_id => ou_rec.organization_id ) = 'N' THEN apps.fnd_file.put_line(FND_FILE.LOG, 'ERROR: Invalid mapping vendor site -> inv org'); CONTINUE; END IF;五、配置界面建议(Form/OAF)
功能点 | 实现方式 |
|---|---|
供应商地点→库存组织映射维护 | OAF页面,带Lov选择供应商地点,Grid展示可用的库存组织列表 |
批量导入 | WebADI模板,支持Excel上传批量映射 |
有效性日历 | 支持有效期控制,便于季节性供应商切换 |
冲突检测 | 保存时校验同一供应商地点下default_flag是否唯一 |
自动创建代理地点 | 勾选auto_create_site后,后台自动在目标OU创建供应商地点并同步基础信息 |
六、部署与运维注意事项
注意点 | 说明 |
|---|---|
初始数据加载 | 上线前从现有业务数据中抽取历史映射关系,生成初始配置 |
变更审批 | 映射变更建议走审批流(AME),防止误配导致收货混乱 |
审计追踪 | 使用FND_AUDIT或触发器记录映射表变更历史 |
缓存策略 | 高频调用时可使用Oracle Result Cache或Redis缓存映射结果 |
与ASL协同 | 考虑与Approved Supplier List(ASL)的联动,ASL批准的供应商自动生成默认映射 |
