这篇文章主要讲解了“API怎么实现批次序列号的销售出库”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“API怎么实现批次序列号的销售出库”吧!

随着制造企业对生产销售的控制越来越高,越来越多的制造型企业增加了对物料的批次、序列号的控制。我们可以在库存职责中的:物料–>主组织物料/组织产品->库存TAB页:来这只某个库存组织中是否启用序列或者是批次。

启用物料的批次、序列控制后,该无聊在采购入库、销售出库都需要填写相应有效批次序列。

在Ebs中我们经常会碰到要实现自动化的公司间事务处理,比如自动销售出库,自动的采购入库。本文就将讲解如何实现带序列号、批次控制的销售出库。

在Ebs的界面上手工的进行销售出库,我们是去修改物料搬运单的属性,物料搬运单->处理物料搬运单->处理物料搬运单分配。如果启用序列、批次号控制,“序列/批次”按钮将会亮起来。


既然实在处理物料搬运单时修改的批次、序列,我们首先就会想到物料搬运单的API来实现这个功能:(挑库确认之前)可使用的API有:

ØINV_MOVE_ORDER_PUB.Process_Move_Order

ØINV_MOVE_ORDER_PUB.Process_Move_Order_Line

该API中的p_trolin_tbl(i).lot_number、p_trolin_tbl(i).serial_number_start、p_trolin_tbl(i).serial_number_end是允许设置和修改。但是让人失望的是,虽然修改了但是挑库发运却看不出任何效果,发出去的物料根本就不是我们指定的批次和序列。

这是因为,库存事务处理是根据下面三个表中的数据进行处理的,而不是根据物料搬运单行。

ØMTL_MATERIAL_TRANSACTIONS_TEMP (库存事务处理临时表)

ØMTL_TRANSACTION_LOTS_TEMP(批次临时表)

ØMTL_SERIAL_NUMBERS_TEMP(序列号临时表)

然而这三个表Oracle并没有提供API来修改它们。

那么我们想:既然是临时表,为何不直接UPDATE它们?那么我们就试一试。

处理步骤:

1.创建销售订单

2.挑库发放(非自动确认)

3.使用INV_MOVE_ORDER_PUB.Process_Move_Order_Line修改物料搬运单行

4.更新MMT、MLT、MST表中的相关数据

5.挑库确认

6.发运确认

如果你的版本是12.1以后,那么发运过程中的请求将会报错,ERROR_CODE:Serial Mssing(序列号控制的情况下出现,批次中不会出现,MetaLink补丁解决这个BUG)。

但是不管怎么样,去直接UPDATE一个表总让人觉得不好(而且还有BUG),那么如果办呢?

我们可以使用一个Oracle未公开的API来觉得这个问题:inv_replenish_detail_pub.line_details_pub.

解决方案:

跳出开始的固定思维,既然Oracle没有API(包括未公开的)去修改物料搬运单的序列和批次,为什么我们不直接做出来一个符合我们要求的物料搬运单呢?

下面给出一个销售订单自动事务处理的API方案:

1.oe_order_pub.process_order创建销售订单.

2.wsh_picking_batches_pub.Create_Batch创建批次号(自动确认:否/自动分配:否).

3.wsh_picking_batches_pub.Release_Batch发放销售订单(并发,ONLINE都行).

4.INV_Trolin_Util.Query_Rows获取物料搬运单行

5.INV_MOVE_ORDER_PUB.Process_Move_Order_Line

修改物料搬运单行(头上的发出子库无需修改).

6.inv_replenish_detail_pub.line_details_pub

创建物料搬运单分配行(注1)

7.inv_pick_wave_pick_confirm_pub.pick_confirm

挑库确认

8.wsh_deliveries_pub.delivery_action交货号发运

9.wsh_ship_confirm_actions.interface_all发运确认

注1:如果挑库发放因为业务需求的原因不能这是自动分配:否,或者由于其他原因在此处已经有了物料搬运单行的分配行,那么请使用API

inv_mo_line_detail_util.reduce_allocation_quantity

来删除配分行(当减小数量等于发运的数量时,事务处理行将被删除)。

下面给出修改物料搬运单行,重新生成分配的单行代码的调用示例:

[java]view plaincopy

DECLARE

--CommonDeclarations

l_api_versionNUMBER:=1.0;

l_init_msg_listVARCHAR2(2):=FND_API.G_TRUE;

l_return_valuesVARCHAR2(2):=FND_API.G_FALSE;

l_commitVARCHAR2(2):=FND_API.G_FALSE;

x_return_statusVARCHAR2(2);

x_msg_countNUMBER:=;

x_msg_dataVARCHAR2(255);

--APIspecificdeclarations

l_header_idNUMBER:=;

l_trohdr_recINV_MOVE_ORDER_PUB.TROHDR_REC_TYPE;

l_trohdr_val_recINV_MOVE_ORDER_PUB.TROHDR_VAL_REC_TYPE;

l_trolin_tblINV_MOVE_ORDER_PUB.TROLIN_TBL_TYPE;

o_trolin_tblINV_MOVE_ORDER_PUB.TROLIN_TBL_TYPE;

l_trolin_val_tblINV_MOVE_ORDER_PUB.TROLIN_VAL_TBL_TYPE;

x_trolin_tblINV_MOVE_ORDER_PUB.TROLIN_TBL_TYPE;

x_trolin_val_tblINV_MOVE_ORDER_PUB.TROLIN_VAL_TBL_TYPE;

x_trohdr_recINV_MOVE_ORDER_PUB.TROHDR_REC_TYPE;

x_trohdr_val_recINV_MOVE_ORDER_PUB.TROHDR_VAL_REC_TYPE;

--CursortoloadMoveOrderHeaders

l_mold_tblINV_MO_LINE_DETAIL_UTIL.g_mmtt_tbl_type;

x_mold_tblINV_MO_LINE_DETAIL_UTIL.g_mmtt_tbl_type;

l_move_order_typeNUMBER:=3;

l_msg_returnNUMBER;

x_number_of_rowsNUMBER;

x_detailed_qtyNUMBER;

x_revisionVARCHAR2(20);

x_locator_idNUMBER;

x_transfer_to_locationNUMBER;

x_lot_numberVARCHAR2(80);

x_expiration_dateDATE;

x_transaction_temp_idNUMBER;

p_transaction_header_idNUMBER;

p_transaction_modeNUMBER;

p_move_order_typeNUMBER:=3;

p_serial_flagVARCHAR2(1);

p_plan_tasksBOOLEAN;

p_auto_pick_confirmBOOLEAN;

p_commitBOOLEAN;

l_t_header_idNUMBER;

l_lot_numberVARCHAR2(80):='SLT0021';--mtl_lot_numbers.lot_number;

l_serial_numberVARCHAR2(20):='3.06.S0019';--mtl_serial_numbers.serial_number

l_subinvetory_codeVARCHAR2(10):='BJJF_CLK';--mtl_secondary_inventories.secondary_inventory_name

l_locator_idNUMBER:=42;--mtl_item_locations.inventory_location_id

l_trx_header_idNUMBER:=93023;--mtl_txn_request_headers.header_id

BEGIN

FND_GLOBAL.APPS_INITIALIZE(1371,50627,660);--Suhasini/MfgMgr/INV

INV_MOVE_ORDER_PUB.Get_Move_Order(

P_API_VERSION_NUMBER=>l_api_version

,P_INIT_MSG_LIST=>l_init_msg_list

,P_RETURN_VALUES=>l_return_values

,X_RETURN_STATUS=>x_return_status

,X_MSG_COUNT=>x_msg_count

,X_MSG_DATA=>x_msg_data

,P_HEADER_ID=>l_trx_header_id--93023

,P_HEADER=>NULL

,X_TROHDR_REC=>l_trohdr_rec

,X_TROHDR_VAL_REC=>l_trohdr_val_rec

,X_TROLIN_TBL=>l_trolin_tbl

,X_TROLIN_VAL_TBL=>l_trolin_val_tbl

);

--PrinttheMoveOrderHeader/Linestobeprocessed

IF(x_return_status=FND_API.G_RET_STS_SUCCESS)THEN

l_trohdr_rec.operation:=INV_GLOBALS.G_OPR_UPDATE;

--FORiIN1..l_trolin_tbl.COUNTLOOP

l_trolin_tbl(1).from_subinventory_code:=l_subinvetory_code;

l_trolin_tbl(1).from_locator_id:=l_locator_id;

l_trolin_tb1(i).lot_number:=l_lot_number;

l_trolin_tbl(1).serial_number_start:=l_serial_number;

l_trolin_tbl(1).serial_number_end:=l_serial_number;

l_trolin_tbl(1).attribute1:='updatemoveordertest!';

l_trolin_tbl(1).operation:=INV_GLOBALS.G_OPR_UPDATE;

--ENDLOOP;

ELSE

DBMS_OUTPUT.PUT_LINE('Get_Move_Ordererror!');

RETURN;

ENDIF;

INV_MOVE_ORDER_PUB.Process_Move_Order_Line(p_api_version_number=>1.0

,p_init_msg_list=>l_init_msg_list

,p_return_values=>l_return_values

,p_commit=>l_commit

,x_return_status=>x_return_status

,x_msg_count=>x_msg_count

,x_msg_data=>x_msg_data

,p_trolin_tbl=>l_trolin_tbl

,p_trolin_old_tbl=>l_trolin_tbl

,x_trolin_tbl=>x_trolin_tbl);

IF(x_return_status<>FND_API.G_RET_STS_SUCCESS)THEN

FORiIN1..x_msg_countLOOP

fnd_msg_pub.get(p_msg_index=>i

,p_encoded=>'F'

,p_data=>x_msg_data

,p_msg_index_out=>l_msg_return);

DBMS_OUTPUT.PUT_LINE(x_msg_data);

ENDLOOP;

RETURN;

ELSE

DBMS_OUTPUT.PUT_LINE('MODIFYSUCESS!');

ENDIF;

/*inv_mo_line_detail_util.reduce_allocation_quantity(

x_return_status=>x_return_status

,p_transaction_temp_id=>2242994

,p_quantity=>1

,p_secondary_quantity=>1);

IFx_return_status<>'S'THEN

DBMS_OUTPUT.PUT_LINE('EE');

ELSE

DBMS_OUTPUT.PUT_LINE('SS');

ENDIF;*/

inv_replenish_detail_pub.line_details_pub(

p_line_id=>l_trolin_tbl(1).line_id

,x_number_of_rows=>x_number_of_rows

,x_detailed_qty=>x_detailed_qty

,x_return_status=>x_return_status

,x_msg_count=>x_msg_count

,x_msg_data=>x_msg_data

,x_revision=>x_revision

,x_locator_id=>x_locator_id

,x_transfer_to_location=>x_transfer_to_location

,x_lot_number=>x_lot_number

,x_expiration_date=>x_expiration_date

,x_transaction_temp_id=>x_transaction_temp_id

,p_transaction_header_id=>NULL

,p_transaction_mode=>NULL

,p_move_order_type=>p_move_order_type

,p_serial_flag=>FND_API.G_FALSE

,p_plan_tasks=>FALSE

,p_auto_pick_confirm=>FALSE

,p_commit=>FALSE);

IF(x_return_status<>FND_API.G_RET_STS_SUCCESS)THEN

DBMS_OUTPUT.PUT_LINE('E');

FORiIN1..x_msg_countLOOP

fnd_msg_pub.get(p_msg_index=>i

,p_encoded=>'F'

,p_data=>x_msg_data

,p_msg_index_out=>l_msg_return);

DBMS_OUTPUT.PUT_LINE(x_msg_data);

ENDLOOP;

RETURN;

ELSE

DBMS_OUTPUT.PUT_LINE('ssssss');

DBMS_OUTPUT.PUT_LINE('x_number_of_rows:'||to_char(x_number_of_rows));

DBMS_OUTPUT.PUT_LINE('x_locator_id:'||to_char(x_locator_id));

DBMS_OUTPUT.PUT_LINE('x_lot_number:'||to_char(x_lot_number));

DBMS_OUTPUT.PUT_LINE('x_transfer_to_location:'||to_char(x_transfer_to_location));

DBMS_OUTPUT.PUT_LINE('x_transaction_temp_id:'||to_char(x_transaction_temp_id));

ENDIF;

l_trolin_tbl:=INV_Trolin_Util.Query_Rows(p_line_id=>l_trolin_tbl(1).line_id);

l_mold_tbl:=INV_MO_LINE_DETAIL_UTIL.query_rows(p_line_id=>l_trolin_tbl(1).line_id);

INV_PICK_WAVE_PICK_CONFIRM_PUB.Pick_Confirm(p_api_version_number=>l_api_version,

p_init_msg_list=>l_init_msg_list,

p_commit=>l_commit,

x_return_status=>x_return_status,

x_msg_count=>x_msg_count,

x_msg_data=>x_msg_data,

p_move_order_type=>l_move_order_type,

p_transaction_mode=>1,

p_trolin_tbl=>l_trolin_tbl,

p_mold_tbl=>l_mold_tbl,

x_mmtt_tbl=>x_mold_tbl,

x_trolin_tbl=>x_trolin_tbl);

IF(x_return_status<>FND_API.G_RET_STS_SUCCESS)THEN

DBMS_OUTPUT.PUT_LINE('E');

FORiIN1..x_msg_countLOOP

fnd_msg_pub.get(p_msg_index=>i

,p_encoded=>'F'

,p_data=>x_msg_data

,p_msg_index_out=>l_msg_return);

DBMS_OUTPUT.PUT_LINE(x_msg_data);

ENDLOOP;

RETURN;

ELSE

DBMS_OUTPUT.PUT_LINE('S');

ENDIF;

--ENDLOOP;

EXCEPTION

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE||':'||SQLERRM);

END;

其他需求情况

有可能业务上只需要在发运出库的时候在交货号显示序列号和批次号,但是实际库存控制并没有这个需求,也可以在挑库确认后,通过API来修改交货号的属性来达到显示序列号和批次号的目的:wsh_delivery_details_pub.Update_Shipping_Attributes

但是这个并不能达到实际出库控制的效果

下面也给出一个示例:

DECLARE

--这只是一个取数的例子,修改成别的取数逻辑,

--cux开头的是客户化的表

CURSORdev_header_cur(p_item_keyVARCHAR2)IS

SELECT

wdd.source_header_idASsource_header_id

,wdd.source_header_numberASsource_header_number

,wdd.source_line_idASsource_line_id

,wda.delivery_idASdelivery_id

,wdd.delivery_detail_idASdelivery_detail_id

,wdd.organization_idASorganization_id

,wdd.source_codeASsource_code

,wdd.requested_quantityASrequested_quantity

,tll.batch_numberASlot_number

,tll.sequence_numberASserial_number

,tll.line_numberASline_number

,tll.header_idASload_header_id

,tll.line_idASload_line_id

,tll.send_sec_inv_codeASsend_subinventory

,tll.send_inv_location_idASsend_locator_id

FROM

cux_tr_load_doc_wf_headerscwh

,cux_tr_load_doc_wf_linescwl

,cux_tr_load_doc_lines_alltll

,oe_order_headers_allooh

,oe_order_lines_allool

,wsh_delivery_detailswdd

,wsh_delivery_assignmentswda

WHERE

cwh.l_inner_oe_header_id = ooh.header_id

ANDcwh.header_id = cwl.header_id

ANDcwl.load_doc_line_id = tll.line_id

ANDcwl.l_inner_oe_line_id = ool.line_id

ANDool.line_id = wdd.source_line_id--bug fix 2010-08-19

ANDwdd.delivery_detail_id = wda.delivery_detail_id

--

-- the value of parameter

--

ANDcwh.item_key ='STH001';

l_indexNUMBER;

l_msg_returnNUMBER;

x_return_statusVARCHAR2(1);

x_msg_countNUMBER;

x_msg_dataVARCHAR2(2000);

l_source_codeVARCHAR2(40);

l_serialrangetabtypewsh_glbl_var_strct_grp.ddserialrangetabtype;

l_changedattributetabtypewsh_delivery_details_pub.changedattributetabtype;

BEGIN

fnd_global.APPS_INITIALIZE( user_id=> -1

,resp_id=> -1

,resp_appl_id => -1);

l_index :=;

FORdev_header_recINdev_header_cur('STH001')LOOP

l_index:= l_index +1;

l_source_code:= dev_header_rec.source_code;

l_changedattributetabtype(l_index).source_header_id:= dev_header_rec.source_header_id;

l_changedattributetabtype(l_index).source_line_id:= dev_header_rec.source_line_id;

l_changedattributetabtype(l_index).delivery_detail_id:= dev_header_rec.delivery_detail_id;

l_changedattributetabtype(l_index).subinventory:='CLK_SD';

l_changedattributetabtype(l_index).locator_id:=42;--货位控制

l_changedattributetabtype(l_index).lot_number:='LOT_SK001';--批次

IFdev_header_rec.requested_quantity =1THEN

l_changedattributetabtype(l_index).serial_number :='LEOCHEN194';

ENDIF;

FORiIN1..dev_header_rec.requested_quantityLOOP

l_serialrangetabtype(1).delivery_detail_id := dev_header_rec.delivery_detail_id;

l_serialrangetabtype(1).from_serial_number :='LEOCHEN194';--LEOCHEN165

l_serialrangetabtype(1).to_serial_number:='LEOCHEN194';

--v_serialRangeTabType(1).quantity:= 1;--Dl.ordered_qty;

l_serialrangetabtype(2).delivery_detail_id := dev_header_rec.delivery_detail_id;

l_serialrangetabtype(2).from_serial_number :='LEOCHEN195';--LEOCHEN165

l_serialrangetabtype(2).to_serial_number:='LEOCHEN195';

--......在此设置多个序列号在一行的情况

ENDLOOP;

ENDLOOP;

wsh_delivery_details_pub.Update_Shipping_Attributes(p_api_version_number =>1.0,

p_init_msg_list=> FND_API.G_FALSE,

p_commit=> FND_API.G_FALSE,

x_return_status=> x_return_status,

x_msg_count=> x_msg_count,

x_msg_data=> x_msg_data,

p_changed_attributes => l_changedattributetabtype,

p_source_code=> l_source_code,

p_container_flag=>NULL,

p_serial_range_tab=> l_serialrangetabtype );

IFx_return_status <> fnd_api.G_RET_STS_SUCCESSTHEN

FORiIN1..x_msg_countLOOP

fnd_msg_pub.get(p_msg_index=> i

,p_encoded=>'F'

,p_data=> x_msg_data

,p_msg_index_out => l_msg_return);

dbms_output.put_line(x_msg_data);

ENDLOOP;

ELSE

dbms_output.put_line('S');

ENDIF;

END;

感谢各位的阅读,以上就是“API怎么实现批次序列号的销售出库”的内容了,经过本文的学习后,相信大家对API怎么实现批次序列号的销售出库这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!