事实上事实上
思路基本是这个思路,问题就在你写的第5步,如何写存储过程进行分配呢?比如有些工单需要100,发了50,还有50要发,这些情况都得考虑进去
- 数据准备
- 数量分配
- 工单发料——这一步系统标准功能调用,只要准备好数据,数量分配好,再把数据插入进来就行,所以完成第二部基本就完成需求
我把表给你,你可以去测试系统试着做一下,把它做成请求,前台一跑请求,就开始调用处理。类似于报表开发。
既然是需求,用户就会传参进来,他们会传哪张工单到哪张工单需要批量发料,或者直接传项目号,整个项目号的工单进行发料
mtl_onhand_quantities_detail 库存现有量表,里面包含对应仓库,批次,数量
WIP_DISCRETE_JOBS 工单头表,完成的状态 status_type = 4
WIP_REQUIREMENT_OPERATIONS 工单行表,这里面要注意一个物料会有多到工序,就表示一个物料工单会有多行
mtl_system_items_b 物料信息表
org_organization_definitions 组织信息表
下面的游标循环是上面说的第三步,只要你数据准备好,分配完之后,再把数据放入issue_data(自己创建)游标就可以了,这是固定写法,标准功能就要有这些数据,所以你可以根据下面倒推一下,需要的字段信息
Issue.字段 都是需要的,上面提供的表也有
FOR issue IN issue_data LOOP
p_err_msg := NULL;
l_mtl_txn_rec := NULL;
SELECT mtl_material_transactions_s.nextval
INTO l_mtl_txn_rec.transaction_interface_id
FROM dual;
l_mtl_txn_rec.transaction_header_id := l_mtl_txn_rec.transaction_interface_id;
l_mtl_txn_rec.transaction_source_id := issue.wip_entity_id;--工单头id
l_mtl_txn_rec.operation_seq_num := issue.operation_seq_num; --工序
l_mtl_txn_rec.inventory_item_id := issue.item_id;--物料id
l_mtl_txn_rec.organization_id := issue.organization_id;--组织id
l_mtl_txn_rec.subinventory_code := issue.supply_subinventory;--供应子库
l_mtl_txn_rec.transaction_quantity := -issue.check_number;--发料数量
l_mtl_txn_rec.transaction_uom := issue.uom;--单位
l_mtl_txn_rec.transaction_date := to_date(to_char(sysdate,
'YYYY-MM-DD hh24:mi:ss'),
'YYYY-MM-DD hh24:mi:ss'); --fnd_date.canonical_to_date(issue.transaction_date);
l_mtl_txn_rec.transaction_type_id := issue.transaction_type;--物料事物类型 这里你自己写死 数字 35 就行
l_mtl_txn_rec.transaction_source_type_id := 5; --生产管理
l_mtl_txn_rec.source_code := 'XXMFG_WIP_ISSUE_IMP_PKG';
l_mtl_txn_rec.source_line_id := issue.wip_entity_id;
l_mtl_txn_rec.source_header_id := issue.wip_entity_id;
l_mtl_txn_rec.creation_date := SYSDATE;
l_mtl_txn_rec.created_by := fnd_global.user_id;
l_mtl_txn_rec.last_update_date := SYSDATE;
l_mtl_txn_rec.last_updated_by := fnd_global.user_id;
l_mtl_txn_rec.last_update_login := fnd_global.login_id;
/************transaction_mode*********************
* transaction_mode
*2 Concurrent, Process transaction interface不处理,
* 需要程序调用Inventory transaction worker处理
*3 Background, 由Process transaction interface处理
***************************************************/
l_mtl_txn_rec.transaction_mode := 3;
l_mtl_txn_rec.process_flag := 1;
IF issue.lot_number IS NOT NULL THEN
--Lot Number 处理
l_mtl_txn_lot_rec := NULL;
l_mtl_txn_lot_rec.lot_number := issue.lot_number;
l_mtl_txn_lot_rec.transaction_quantity := l_mtl_txn_rec.transaction_quantity;
l_mtl_txn_lot_rec.transaction_interface_id := l_mtl_txn_rec.transaction_interface_id;
l_mtl_txn_lot_rec.creation_date := SYSDATE;
l_mtl_txn_lot_rec.created_by := fnd_global.user_id;
l_mtl_txn_lot_rec.last_update_date := SYSDATE;
l_mtl_txn_lot_rec.last_updated_by := fnd_global.user_id;
l_mtl_txn_lot_rec.last_update_login := fnd_global.login_id;
INSERT INTO mtl_transaction_lots_interface
VALUES l_mtl_txn_lot_rec;
END IF;
INSERT INTO mtl_transactions_interface VALUES l_mtl_txn_rec;
select nvl(max(ITEM_COST), 0)
into l_item_cost
from cst_item_costs cic, mtl_system_items_b msi
where cic.inventory_item_id = issue.item_id
and cic.inventory_item_id = msi.inventory_item_id
and cic.organization_id = msi.organization_id
and msi.costing_enabled_flag = 'Y'
and cic.organization_id = issue.organization_id;
x_err_msg := null;
if l_item_cost = 0 then
l_retval := 1;
x_err_msg := '@物料标准成本为 0,请联系成本科维护标准成本!';
else
l_retval := inv_txn_manager_pub.process_transactions(p_api_version => 1,
p_init_msg_list => fnd_api.g_false,
p_commit => fnd_api.g_false,
--not commit
p_validation_level => fnd_api.g_valid_level_full,
x_return_status => p_code,
x_msg_count => l_msg_count,
x_msg_data => p_err_msg,
x_trans_count => l_trans_count,
p_table => 1,
p_header_id => l_mtl_txn_rec.transaction_header_id);
end if;
IF l_retval <> 0 THEN
IF x_err_msg is not null THEN
update XXMFG_AUTO_ISSUE_TMP2 xai
set xai.err_msg = '发料失败!' || x_err_msg
where xai.wip_entity_id = issue.wip_entity_id
and xai.item_id = issue.item_id
and xai.operation_seq_num = issue.operation_seq_num;
else
FOR r_err IN c_errs(l_mtl_txn_rec.transaction_interface_id) LOOP
p_err_msg := p_err_msg || r_err.error_code || ':' ||
r_err.error_explanation;
END LOOP;
ROLLBACK;
update XXMFG_AUTO_ISSUE_TMP2 xai
set xai.err_msg = p_err_msg
where xai.wip_entity_id = issue.wip_entity_id
and xai.item_id = issue.item_id
and xai.operation_seq_num = issue.operation_seq_num;
END IF;
ELSE
update XXMFG_AUTO_ISSUE_TMP2 xai
set xai.err_msg = '发料成功!'
where xai.wip_entity_id = issue.wip_entity_id
and xai.item_id = issue.item_id
and xai.operation_seq_num = issue.operation_seq_num;
END IF;
DELETE FROM mtl_transactions_interface mti
WHERE mti.transaction_header_id =
l_mtl_txn_rec.transaction_header_id;
DELETE FROM mtl_transaction_lots_interface mtli
WHERE mtli.transaction_interface_id =
l_mtl_txn_rec.transaction_interface_id;
COMMIT;
END LOOP;
3、下面的思考题
这三个功能的逻辑需要对接,不然后续出现问题无法进行排查
今天的思考题:工单分配物料
需求描述:
现在有一个项目号生成的多张工单,由于数据量大,期初很多工单都是欠料完工(订单紧急,料未到货,之后走系统账务)。后面需要补足这些工单的欠料情况,需要系统自动识别发料。
要求优先使用本项目物料批次(减少挪用其它项目物料料的情况发生),实在没有本项目物料批次后再使用其它项目批次,且所有物料批次都要先进先出发料,如果使用系统标准功能发料,就得一个个人为校验,效率很低。
特点:
- 目前由于多次需求完善,已经限定特定线边仓仓库物料
- 只针对已完工的工单进行发料
- 每个批次可以给多张同项目工单使用,多张工单也可以用同一个批次号,就是一个蛋糕如何分配的问题
- 系统标准批次为xxx-[项目号]-xxx,只要不符合标准批次的,都为非本项目批次。因此工单的项目号就可以跟批次号做绑定