轉自:http://blog.csdn.net/cunxiyuan108/article/details/6006961
目的:模擬EBS Form界面的功能,調用標準的API實現自動處理物料搬運單。
實現思路:
1. 先創建一個客戶化的表,這個表中用來保存物料搬運單的一些信息。
2. 調用標準的API:inv_loc_wms_pub.create_locator動態創建貨位(根據項目、任務和庫存三個段 來創建)。
3. 調用標準的API:inv_quantity_tree_pub.query_quantities檢查某一庫存組織的某一子庫存下某一物料的現用量和可用量。
4. 調用標準的API:inv_mo_line_detail_util.insert_row在MMTT表中插入一條記錄。
5. 調用標準的API:INV_Replenish_Detail_PUB.line_details_pub創建物料搬運單的分配行。
6. 調用標準的API: inv_trolin_util.query_rows得到物料搬運單行的相關信息。
7. 調用標準的API:INV_PICK_WAVE_PICK_CONFIRM_PUB.Pick_Confirm進行自動挑庫確認(處理物料搬運單)。
8. 調用標準的API:inv_mo_line_detail_util.delete_row刪除MMTT表中的未處理的記錄(如果步驟4中的記錄沒有被處理)。
9. 更新客戶化表的處理狀態和錯誤信息。
10. 將處理的結果進行統計,並使用HTML輸出。
整個程序包如下:
CREATE OR REPLACE PACKAGE BODY CUX_EDIINT_ITEM_MOVE_IN_PKG IS
--自定義預置文件CUX_MO_DEBUG_FLAG:用來判斷是否輸出調試信息
--fnd_profile.VALUE('CUX_MO_DEBUG_FLAG')爲NULL,不輸出調試信息,輸出錯誤信息
--fnd_profile.VALUE('CUX_MO_DEBUG_FLAG')爲'N',不輸出調試信息,輸出錯誤信息
--fnd_profile.VALUE('CUX_MO_DEBUG_FLAG')爲'Y', 輸出調試信息,輸出錯誤信息
l_mo_debug_falg VARCHAR2(1) := NVL(fnd_profile.VALUE('CUX_MO_DEBUG_FLAG'),
'N');
--日誌
PROCEDURE put_log(p_msg IN VARCHAR2) IS
BEGIN
fnd_file.put_line(fnd_file.log, p_msg);
END put_log;
--輸出
PROCEDURE put_file(p_msg IN VARCHAR2) IS
BEGIN
fnd_file.put_line(fnd_file.OUTPUT, p_msg);
END put_file;
/*=======================================================
* FUNCTION / PROCEDURE
* get_org_count
* DESCRIPTION:
* 得到本次請求處理(成功或者失敗)的物料搬運單的所有OU 數量,0表示不存在,1表示存在。
* ARGUMENT:
* p_org_id :OU id
* p_process_id :物料搬運單處理狀態
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
FUNCTION get_org_count(p_org_id NUMBER, p_process_id NUMBER) RETURN NUMBER IS
l_org_count NUMBER;
BEGIN
SELECT COUNT(1)
INTO l_org_count
FROM cux_ediint_item_move_in ceimi
WHERE ceimi.ou_org_id = p_org_id
AND ceimi.process_id = p_process_id
AND ceimi.request_id = fnd_global.conc_request_id
AND ROWNUM = 1;
RETURN l_org_count;
EXCEPTION
WHEN OTHERS THEN
put_log('得到OU關聯的處理條數時候出現錯誤:' || SQLERRM);
RETURN NULL;
END get_org_count;
/*=======================================================
* FUNCTION / PROCEDURE
* output_move_order_info
* DESCRIPTION:
* 輸出處理信息
* ARGUMENT:
* p_line_count :本次請求處理的記錄總數量
* p_line_seccess_count : 本次請求處理成功的記錄數量
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE output_move_order_info(p_line_count IN NUMBER,
p_line_success_count IN NUMBER) IS
--取出物料搬運單客戶化表中的業務實體的信息,不取重複的記錄
CURSOR cur_org_info IS
SELECT DISTINCT
hou.organization_id org_id, --庫存組織id
hou.name org_name --庫存組織名稱
FROM cux_ediint_item_move_in ceimi,
mtl_txn_request_lines mtrl,
mtl_txn_request_headers mtrh,
org_organization_definitions ood,
hr_operating_units hou
WHERE ceimi.line_id = mtrl.line_id
AND mtrl.header_id = mtrh.header_id
AND ood.organization_id = mtrl.organization_id
AND ood.operating_unit = hou.organization_id
AND ceimi.request_id = fnd_global.conc_request_id;
--處理成功的物料搬運單行信息
CURSOR cur_move_order_success(p_org_id NUMBER) IS
SELECT hou.name org_name, --OU名稱
ceimi.header_id header_id, --物料搬運單頭id
mtrh.request_number request_number, --物料搬運單編號
ml.meaning move_order_type_meaning, --物料搬運單類型
ceimi.line_id line_id, --物料搬運單行id
mtrl.line_number line_number, --行編號
msib.segment1 item_code, --物料編碼
ceimi.transaction_quantity transaction_quantity, --事務處理數量
ood.organization_code organization_code, --庫存組織代碼
ood.organization_name organization_name, --庫存組織名稱
mtrl.from_subinventory_code from_subinventory_code, --來源子庫存
mtrl.to_subinventory_code to_subinventory_code --目標子庫存
FROM cux_ediint_item_move_in ceimi,
mtl_txn_request_lines mtrl,
mtl_txn_request_headers mtrh,
org_organization_definitions ood,
hr_operating_units hou,
mfg_lookups ml,
mtl_system_items_b msib
WHERE ceimi.line_id = mtrl.line_id
AND mtrl.header_id = mtrh.header_id
AND ood.organization_id = mtrl.organization_id
AND ood.operating_unit = hou.organization_id
AND mtrh.move_order_type = ml.lookup_code
AND ml.lookup_type = 'MOVE_ORDER_TYPE'
AND msib.organization_id = mtrl.organization_id
AND msib.inventory_item_id = mtrl.inventory_item_id
AND ceimi.process_id = 4 --處理成功的記錄
AND ceimi.request_id = fnd_global.conc_request_id
AND hou.organization_id = p_org_id;
--出錯的物料搬運單行信息
CURSOR cur_move_order_error(p_org_id NUMBER) IS
SELECT hou.name org_name, --OU名稱
ceimi.header_id header_id, --物料搬運單頭id
mtrh.request_number request_number, --物料搬運單編號
ml.meaning move_order_type_meaning,--物料搬運單類型
ceimi.line_id line_id, --物料搬運單行id
mtrl.line_number line_number, --行編號
msib.segment1 item_code, --物料編碼
ceimi.transaction_quantity transaction_quantity, --事務處理數量
ood.organization_code organization_code, --庫存組織代碼
ood.organization_name organization_name, --庫存組織名稱
mtrl.from_subinventory_code from_subinventory_code,--來源子庫存
mtrl.to_subinventory_code to_subinventory_code, --目標子庫存
ceimi.error_message error_message --錯誤信息
FROM cux_ediint_item_move_in ceimi,
mtl_txn_request_lines mtrl,
mtl_txn_request_headers mtrh,
org_organization_definitions ood,
hr_operating_units hou,
mfg_lookups ml,
mtl_system_items_b msib
WHERE ceimi.line_id = mtrl.line_id
AND mtrl.header_id = mtrh.header_id
AND ood.organization_id = mtrl.organization_id
AND ood.operating_unit = hou.organization_id
AND mtrh.move_order_type = ml.lookup_code
AND ml.lookup_type = 'MOVE_ORDER_TYPE'
AND msib.organization_id = mtrl.organization_id
AND msib.inventory_item_id = mtrl.inventory_item_id
AND ceimi.process_id = 3 --處理失敗的記錄
AND ceimi.request_id = fnd_global.conc_request_id
AND hou.organization_id = p_org_id;
l_user_name VARCHAR2(100); --用戶名
l_success_index NUMBER; --循環標誌
l_error_index NUMBER; --循環標誌
l_count NUMBER; --循環標誌
l_org_count NUMBER; --循環標誌
BEGIN
SELECT fu.user_name
INTO l_user_name
FROM fnd_user fu
WHERE fu.user_id = NVL(fnd_global.user_id, -1);
put_file(chr(13) || chr(10));
put_file('提交人:' || rpad(l_user_name, 20, ' '));
put_file('報表日期:' || TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
put_file(chr(13) || chr(10));
put_file('本次處理的總的記錄條數爲: ' || to_char(p_line_count) || ' 條');
put_file('處理成功的記錄條數爲: ' || to_char(p_line_success_count) || ' 條');
IF (p_line_count > p_line_success_count) THEN
put_file('處理出錯的記錄條數爲: ' ||
to_char(p_line_count - p_line_success_count) || ' 條');
END IF;
put_file(chr(13) || chr(10));
IF p_line_success_count <> 0 THEN
put_file('處理成功的物料搬運單');
put_file(lpad('-', 190, '-'));
--輸出處理成功的物料搬運單的信息
FOR rec_org_info IN cur_org_info LOOP
l_org_count := get_org_count(rec_org_info.org_id, 4);
IF l_org_count <> 0 THEN
put_file('業務實體:' || rec_org_info.org_name);
put_file(rpad('-', 190, '-'));
put_file(rpad('物料搬運單編號', 30, ' ') || rpad('類型', 20, ' ') ||
rpad('行號', 20, ' ') || rpad('物料', 40, ' ') ||
rpad('來源子庫存', 20, ' ') || rpad('目標子庫存', 20, ' ') ||
rpad('事務處理數量', 40, ' '));
put_file(chr(13) || chr(10));
END IF;
FOR rec_move_order_succes IN cur_move_order_success(rec_org_info.org_id) LOOP
put_file(rpad(rec_move_order_succes.request_number, 30, ' ') ||
rpad(rec_move_order_succes.move_order_type_meaning,
20,
' ') ||
rpad(rec_move_order_succes.line_number, 20, ' ') ||
rpad(rec_move_order_succes.item_code, 40, ' ') ||
rpad(rec_move_order_succes.from_subinventory_code,
20,
' ') || rpad(rec_move_order_succes.to_subinventory_code,
20,
' ') ||
rpad(rec_move_order_succes.transaction_quantity,
40,
' '));
put_file(chr(13) || chr(10));
END LOOP; --FOR rec_hold_order_info IN cur_hold_order_info LOOP
put_file(chr(13) || chr(10));
END LOOP; --FOR rec_org_info IN cur_org_info LOOP
put_file(lpad('-', 95, '-') || rpad('-', 95, '-'));
END IF;
put_file(chr(13) || chr(10));
--輸出處理失敗的物料搬運單
IF p_line_count - p_line_success_count > 0 THEN
put_file('處理出錯的物料搬運單');
put_file(lpad('處理出錯的', 145, '-') || rpad('物料搬運單', 145, '-'));
IF (p_line_count >= p_line_success_count) THEN
--如果存在錯誤的記錄
--輸出處理成功的物料搬運單的信息
FOR rec_org_info IN cur_org_info LOOP
l_org_count := get_org_count(rec_org_info.org_id, 3);
IF l_org_count <> 0 THEN
put_file('業務實體:' || rec_org_info.org_name);
put_file(rpad('-', 290, '-'));
put_file(rpad('物料搬運單編號', 30, ' ') || rpad('類型', 20, ' ') ||
rpad('行號', 20, ' ') || rpad('物料', 40, ' ') ||
rpad('來源子庫存', 20, ' ') || rpad('目標子庫存', 20, ' ') ||
rpad('事務處理數量', 40, ' ') || rpad('錯誤信息', 100, ' '));
put_file(chr(13) || chr(10));
END IF;
FOR rec_move_order_error IN cur_move_order_error(rec_org_info.org_id) LOOP
put_file(rpad(rec_move_order_error.request_number, 30, ' ') ||
rpad(rec_move_order_error.move_order_type_meaning,
20,
' ') ||
rpad(rec_move_order_error.line_number, 20, ' ') ||
rpad(rec_move_order_error.item_code, 40, ' ') ||
rpad(rec_move_order_error.from_subinventory_code,
20,
' ') || rpad(rec_move_order_error.to_subinventory_code,
20,
' ') ||
rpad(rec_move_order_error.transaction_quantity,
40,
' ') ||
rpad(rec_move_order_error.error_message, 100, ' '));
put_file(chr(13) || chr(10));
END LOOP; --FOR rec_hold_order_info IN cur_hold_order_info LOOP
END LOOP; --FOR rec_org_info IN cur_org_info LOOP
END IF;
IF p_line_count - p_line_success_count > 0 THEN
put_file(lpad('-', 145, '-') || rpad('-', 145, '-'));
END IF;
END IF;
END output_move_order_info;
/*=======================================================
* FUNCTION / PROCEDURE
* get_move_order
* DESCRIPTION:
* 得到物料搬運單的一條記錄(一個物料搬運單頭和對應的所有的物表搬運單的行)
* ARGUMENT:
* x_return_status :狀態
* x_msg_count :錯誤信息數量
* x_msg_data :錯誤信息
* x_trohdr_rec :物料搬運單頭的一行記錄
* x_trohdr_val_rec :物料搬運單頭的一行記錄對應的值
* x_trolin_tbl :一個物料搬運單頭對應的所有物料搬運單行
* x_trolin_val_tbl :一個物料搬運單頭對應的所有物料搬運單行的值
* p_header_id :物料搬運單頭id
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE get_move_order(x_return_status OUT NOCOPY VARCHAR2,
x_msg_count OUT NOCOPY NUMBER,
x_msg_data OUT NOCOPY VARCHAR2,
x_trohdr_rec OUT NOCOPY INV_MOVE_ORDER_PUB.Trohdr_Rec_Type,
x_trohdr_val_rec OUT NOCOPY INV_MOVE_ORDER_PUB.Trohdr_Val_Rec_Type,
x_trolin_tbl OUT NOCOPY INV_MOVE_ORDER_PUB.Trolin_Tbl_Type,
x_trolin_val_tbl OUT NOCOPY INV_MOVE_ORDER_PUB.Trolin_Val_Tbl_Type,
p_header_id IN NUMBER) IS
BEGIN
--調用系統標準的API得到物料搬運單的相關信息
INV_Move_Order_PUB.Get_Move_Order(p_api_version_number => 1.0,
p_init_msg_list => fnd_api.G_FALSE,
p_return_values => fnd_api.G_FALSE,
x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
p_header_id => p_header_id,
p_header => fnd_api.G_MISS_CHAR,
x_trohdr_rec => x_trohdr_rec,
x_trohdr_val_rec => x_trohdr_val_rec,
x_trolin_tbl => x_trolin_tbl,
x_trolin_val_tbl => x_trolin_val_tbl);
EXCEPTION
WHEN OTHERS THEN
put_log('得到物料搬運單時出現異常:' || SQLERRM);
END get_move_order;
/*=======================================================
* FUNCTION / PROCEDURE
* get_locator_type
* DESCRIPTION:
* 得到貨位控制類型
* ARGUMENT:
* p_organization_id :庫存組織id
* p_secondary_inventory_code:子庫存代碼
* RETURN:
* 貨位控制類型
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
FUNCTION get_locator_type(p_organization_id IN NUMBER,
p_secondary_inventory_code IN VARCHAR2)
RETURN NUMBER IS
l_locator_type_id NUMBER; --貨位控制類型
BEGIN
SELECT msi.locator_type
INTO l_locator_type_id
FROM mtl_secondary_inventories msi
WHERE msi.organization_id = p_organization_id
AND msi.secondary_inventory_name = p_secondary_inventory_code;
RETURN l_locator_type_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
WHEN TOO_MANY_ROWS THEN
put_log('得到貨位控制類型時返回的多個行!');
WHEN OTHERS THEN
put_log('得到貨位控制類型時出現異常:' || SQLERRM);
END get_locator_type;
/*=======================================================
* FUNCTION / PROCEDURE
* create_locator
* DESCRIPTION:
* 自動創建貨位
* ARGUMENT:
* x_return_status :狀態
* x_msg_count :錯誤信息數量
* x_msg_data :錯誤信息
* x_locator_id :貨位id
* x_locator_exists :是否存在貨位
* p_organization_id :庫存組織id
* p_subinventory_code :子庫存代碼
* p_project_id :項目id
* p_task_id :任務id
* p_locator_type :貨位類型
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE create_locator(x_return_status OUT NOCOPY VARCHAR2,
x_msg_count OUT NOCOPY NUMBER,
x_msg_data OUT NOCOPY VARCHAR2,
x_locator_id OUT NUMBER,
x_locator_exists OUT VARCHAR2,
p_organization_id IN NUMBER,
p_subinventory_code IN VARCHAR2,
p_project_id IN NUMBER,
p_task_id IN NUMBER,
p_locator_type IN NUMBER) IS
l_segment_delimiter VARCHAR2(1); --鍵彈性域段分隔符
l_concatenated_segments VARCHAR2(100); --庫存貨位組合
l_project_number VARCHAR2(25); --項目編號
l_task_number VARCHAR2(25); --任務編號
l_user_id NUMBER; --登錄的用戶
l_resp_id NUMBER; --職位id
l_resp_appl_id NUMBER; --職責應用id
BEGIN
--設置MFG_ORGANIZATION_ID預置文件的值
fnd_profile.put('MFG_ORGANIZATION_ID', p_organization_id);
--得到段分隔符
SELECT fifs.concatenated_segment_delimiter
INTO l_segment_delimiter
FROM fnd_id_flex_structures fifs
WHERE fifs.id_flex_structure_code = 'STOCK_LOCATORS';
--得到項目編號
SELECT ppa.segment1
INTO l_project_number
FROM pa_projects_all ppa
WHERE ppa.project_id = p_project_id;
--得到任務編號
SELECT pt.task_number
INTO l_task_number
FROM pa_tasks pt
WHERE pt.task_id = p_task_id;
--拼接子庫存貨位組合
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('庫存組織id:' || p_organization_id);
put_log('貨位類型:' || p_locator_type);
put_log('子庫存:' || p_subinventory_code);
END IF;
l_concatenated_segments := p_subinventory_code || l_segment_delimiter ||
l_project_number || l_segment_delimiter ||
l_task_number;
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('彈性域組合:' || l_concatenated_segments);
END IF;
--調用API自動創建貨位
inv_loc_wms_pub.create_locator(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
x_inventory_location_id => x_locator_id,
x_locator_exists => x_locator_exists,
p_organization_id => p_organization_id,
p_organization_code => NULL,
p_concatenated_segments => l_concatenated_segments,
p_description => NULL,
p_inventory_location_type => p_locator_type,
p_picking_order => NULL,
p_location_maximum_units => NULL,
p_subinventory_code => p_subinventory_code,
p_location_weight_uom_code => NULL,
p_max_weight => NULL,
p_volume_uom_code => NULL,
p_max_cubic_area => NULL,
p_x_coordinate => NULL,
p_y_coordinate => NULL,
p_z_coordinate => NULL,
p_physical_location_id => NULL,
p_pick_uom_code => NULL,
p_dimension_uom_code => NULL,
p_length => NULL,
p_width => NULL,
p_height => NULL,
p_status_id => NULL,
p_dropping_order => NULL);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('自動生成的貨位返回狀態:' || x_return_status);
put_log('自動生成的貨位錯誤條數:' || x_msg_count);
put_log('自動生成的貨位錯誤信息:' || x_msg_data);
put_log('自動生成的貨位id爲:' || x_locator_id);
END IF;
IF x_locator_id IS NULL THEN
put_log('自動創建貨位時出錯:' || x_msg_data);
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('自動創建貨位時出現異常:' || SQLERRM);
END create_locator;
/*=======================================================
* FUNCTION / PROCEDURE
* check_and_create_locator
* DESCRIPTION:
* 檢查和生成貨位
* ARGUMENT:
* x_return_status :狀態
* x_msg_count :錯誤信息數量
* x_msg_data :錯誤信息
* x_locator_type :貨位類型
* x_from_locator_id :來源貨位id
* x_to_locator_id :目標貨位id
* p_trolin_rec :物料搬運單行的一行記錄
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE check_and_create_locator(x_return_status OUT VARCHAR2,
x_msg_data OUT VARCHAR2,
x_locator_type OUT VARCHAR2,
x_from_locator_id OUT NUMBER,
x_to_locator_id OUT NUMBER,
p_trolin_rec IN INV_MOVE_ORDER_PUB.Trolin_Rec_Type) IS
l_from_inv_locator_type NUMBER; --源子庫存的貨位控制類型
l_to_inv_locator_type NUMBER; --目標子庫存的貨位控制類型
x_msg_count NUMBER; --錯誤信息數
x_locator_id NUMBER; --貨位id
x_locator_exists VARCHAR2(1); --貨位是否存在標誌
BEGIN
--來源子庫存的貨位控制類型
l_from_inv_locator_type := get_locator_type(p_trolin_rec.organization_id,
p_trolin_rec.from_subinventory_code);
--目標子庫存的貨位控制類型
l_to_inv_locator_type := get_locator_type(p_trolin_rec.organization_id,
p_trolin_rec.to_subinventory_code);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log(p_trolin_rec.from_subinventory_code || '的來源字庫貨位類型爲:' ||
l_from_inv_locator_type);
put_log(p_trolin_rec.to_subinventory_code || '的來源字庫貨位類型爲:' ||
l_to_inv_locator_type);
END IF;
IF l_from_inv_locator_type = l_to_inv_locator_type THEN
IF l_from_inv_locator_type <> 0 THEN--啓用了貨位控制
x_locator_type := l_from_inv_locator_type;
IF p_trolin_rec.from_locator_id IS NOT NULL THEN --貨位不爲空
x_return_status := fnd_api.G_RET_STS_SUCCESS;
x_from_locator_id := p_trolin_rec.from_locator_id;
ELSE--貨位爲空
--自動創建貨位(源庫存貨位)
create_locator(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
x_locator_id => x_from_locator_id,
x_locator_exists => x_locator_exists,
p_organization_id => p_trolin_rec.organization_id,
p_subinventory_code => p_trolin_rec.from_subinventory_code,
p_project_id => p_trolin_rec.project_id,
p_task_id => p_trolin_rec.task_id,
p_locator_type => x_locator_type);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('x_return_status:' || x_return_status);
put_log('x_msg_count:' || x_msg_count);
put_log('x_msg_data:' || x_msg_data);
put_log('x_from_locator_id:' || x_from_locator_id);
put_log('x_locator_exists:' || x_locator_exists);
END IF;
IF x_from_locator_id IS NULL THEN
x_msg_data := '自動創建貨位時錯誤異常,請確認是否已經包含子庫存、項目和任務的信息';
END IF;
END IF;
ELSE--未啓用貨位控制
x_locator_type := 0;
END IF;
IF l_to_inv_locator_type <> 0 THEN --啓用了貨位控制
x_locator_type := l_to_inv_locator_type;
IF p_trolin_rec.to_locator_id IS NOT NULL THEN--貨位不爲空
x_return_status := fnd_api.G_RET_STS_SUCCESS;
x_to_locator_id := p_trolin_rec.to_locator_id;
ELSE--貨位爲空
--自動創建貨位(目標庫存貨位)
create_locator(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
x_locator_id => x_to_locator_id,
x_locator_exists => x_locator_exists,
p_organization_id => p_trolin_rec.organization_id,
p_subinventory_code => p_trolin_rec.to_subinventory_code,
p_project_id => p_trolin_rec.project_id,
p_task_id => p_trolin_rec.task_id,
p_locator_type => x_locator_type);
IF x_from_locator_id IS NULL THEN
x_msg_data := '自動創建貨位時錯誤異常,請確認是否已經包含子庫存、項目和任務的信息';
END IF;
END IF;
ELSE --未啓用貨位控制
x_locator_type := 0;
END IF;
ELSE
put_log('源子庫存和目標子庫存的貨位控制類型不一致:');
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('檢查和生成貨位時出現異常:' || SQLERRM);
END check_and_create_locator;
/*=======================================================
* FUNCTION / PROCEDURE
* validate_subinv_quantity
* DESCRIPTION:
* 驗證子庫存的現用量和可用量
* ARGUMENT:
* x_return_status :狀態
* x_msg_count :錯誤信息數量
* x_msg_data :錯誤信息
* p_trolin_rec :物料搬運單行的一行記錄
* p_transaction_quantity :事務處理數量
* p_transaction_date :事務處理日期
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE validate_subinv_quantity(x_return_status OUT NOCOPY VARCHAR2,
x_msg_count OUT NOCOPY NUMBER,
x_msg_data OUT NOCOPY VARCHAR2,
p_trolin_rec IN INV_MOVE_ORDER_PUB.Trolin_Rec_Type,
p_transaction_quantity IN NUMBER,
p_transaction_date IN DATE) IS
x_qoh NUMBER; --quantity on hand
x_rqoh NUMBER; --reservable quantity on hand
x_qr NUMBER; --quantity reserved
x_qs NUMBER; --quantity suggested
x_att NUMBER; --available to transact
x_atr NUMBER := 0; --available to reserve
x_sqoh NUMBER; --secondary quantity on hand -- invConv change
x_srqoh NUMBER; --secondary reservable quantity on hand -- invConv change
x_sqr NUMBER; --secondary quantity reserved -- invConv change
x_sqs NUMBER; --secondare quantity suggested -- invConv change
x_satt NUMBER; --secondary available to transact -- invConv change
x_satr NUMBER; --secondary available to reserve -- invConv change
l_lot_control_flag BOOLEAN := FALSE;
l_organization_code VARCHAR2(3); --庫存組織代碼
l_item_code VARCHAR2(40); --物料代碼
x_locator_type VARCHAR2(60); --貨位控制類型
x_from_locator_id NUMBER; --來源貨位
x_to_locator_id NUMBER; --目標貨位
l_locator_id NUMBER; --子庫存的貨位
BEGIN
--得到庫存代碼
SELECT mp.organization_code
INTO l_organization_code
FROM mtl_parameters mp
WHERE mp.organization_id = p_trolin_rec.organization_id;
--得到物料代碼
SELECT msib.segment1
INTO l_item_code
FROM mtl_system_items_b msib
WHERE msib.organization_id = p_trolin_rec.organization_id
AND msib.inventory_item_id = p_trolin_rec.inventory_item_id;
--調用系統的api檢查某一庫存組織某一字庫的某一個物料的現有量、可用量等數量
inv_quantity_tree_pub.query_quantities(p_api_version_number => 1.0,
x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
p_organization_id => p_trolin_rec.organization_id, --庫存組織
p_inventory_item_id => p_trolin_rec.inventory_item_id, --item id
p_tree_mode => 2,
p_is_revision_control => FALSE,
p_is_lot_control => l_lot_control_flag, --是否啓用批次控制
p_lot_expiration_date => p_transaction_date, --事務處理數量
p_is_serial_control => FALSE,
p_grade_code => NULL, -- INVCONV NOT NEEDED NOW
p_revision => NULL, --版本號
p_lot_number => NULL, --批次控制
p_subinventory_code => p_trolin_rec.from_subinventory_code, --來源子庫存代碼
p_locator_id => NULL, --貨位id
x_qoh => x_qoh, --現有量
x_rqoh => x_rqoh, --現有包流量
x_qr => x_qr, --保留量
x_qs => x_qs, --建議保留量
x_att => x_att, --可處理數量
x_atr => x_atr, --保留量
x_sqoh => x_sqoh, -- INVCONV
x_srqoh => x_srqoh, -- INVCONV
x_sqr => x_sqr, -- INVCONV
x_sqs => x_sqs, -- INVCONV
x_satt => x_satt, -- INVCONV
x_satr => x_satr); -- INVCONV
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('得到的庫存現用量的狀態爲:' || x_return_status);
put_log('得到的庫存現用量爲:' || x_atr);
END IF;
IF x_atr <= 0 THEN
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
x_msg_data := '庫存組織 ' || l_organization_code || ' 的子庫存 ' ||
p_trolin_rec.from_subinventory_code || ' 中物料 ' ||
l_item_code || ' 的可用量爲' || x_atr;
RETURN;
END IF;
--檢查並創建貨位
check_and_create_locator(x_return_status => x_return_status,
x_msg_data => x_msg_data,
x_locator_type => x_locator_type,
x_from_locator_id => x_from_locator_id,
x_to_locator_id => x_to_locator_id,
p_trolin_rec => p_trolin_rec);
IF x_locator_type <> 0 THEN
l_locator_id := x_from_locator_id;
ELSE
l_locator_id := NULL;
END IF;
IF x_return_status IS NULL THEN
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
x_msg_data := x_msg_data;
RETURN;
END IF;
--調用系統的api檢查某一庫存組織某一字庫的某一個物料的現有量、可用量等數量
x_qoh := NULL;
x_rqoh := NULL;
x_qr := NULL;
x_qs := NULL;
x_att := NULL;
x_atr := NULL;
x_sqoh := NULL;
x_srqoh := NULL;
x_sqr := NULL;
x_sqs := NULL;
x_satt := NULL;
x_satr := NULL;
--調用API得到庫存下的物料的現用量和可用量
inv_quantity_tree_pub.query_quantities(p_api_version_number => 1.0,
x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
p_organization_id => p_trolin_rec.organization_id, --庫存組織
p_inventory_item_id => p_trolin_rec.inventory_item_id, --item id
p_tree_mode => 2,
p_is_revision_control => FALSE,
p_is_lot_control => l_lot_control_flag, --是否啓用批次控制
p_lot_expiration_date => p_transaction_date, --事務處理數量
p_is_serial_control => FALSE,
p_grade_code => NULL, -- INVCONV NOT NEEDED NOW
p_revision => NULL, --版本號
p_lot_number => NULL, --批次控制
p_subinventory_code => p_trolin_rec.from_subinventory_code, --來源子庫存代碼
p_locator_id => l_locator_id, --貨位id
x_qoh => x_qoh, --現有量
x_rqoh => x_rqoh, --現有包流量
x_qr => x_qr, --保留量
x_qs => x_qs, --建議保留量
x_att => x_att, --可處理數量
x_atr => x_atr, --保留量
x_sqoh => x_sqoh, -- INVCONV
x_srqoh => x_srqoh, -- INVCONV
x_sqr => x_sqr, -- INVCONV
x_sqs => x_sqs, -- INVCONV
x_satt => x_satt, -- INVCONV
x_satr => x_satr); -- INVCONV
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('庫存組織');
END IF;
IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
x_msg_data := '獲取 庫存組織 ' || l_organization_code || ' 的子庫存 ' ||
p_trolin_rec.from_subinventory_code || ' 中物料 ' ||
l_item_code || ' 的可用量時出現異常!';
END IF;
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('得到的庫存現用量的狀態爲:' || x_return_status);
put_log('得到的庫存現用量爲:' || x_atr);
END IF;
IF x_atr <= 0 THEN
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
x_msg_data := '庫存組織 ' || l_organization_code || ' 的子庫存 ' ||
p_trolin_rec.from_subinventory_code || ' 中物料 ' ||
l_item_code || ' 的可用量爲 ' || x_atr;
END IF;
IF x_atr <> 0 AND x_atr < p_transaction_quantity THEN
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
x_msg_data := '庫存組織 ' || l_organization_code || ' 的子庫存 ' ||
p_trolin_rec.from_subinventory_code || ' 中物料 ' ||
l_item_code || ' 的可用量 ' || x_atr || ' 小於處理數量 ' ||
p_transaction_quantity;
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('檢查庫存的現用量和可用量時出現異常:' || SQLERRM);
END validate_subinv_quantity;
/*=======================================================
* FUNCTION / PROCEDURE
* validate_data
* DESCRIPTION:
* 驗證客戶化臨時表的數據
* ARGUMENT:
* x_return_status :狀態
* x_msg_count :錯誤信息數量
* x_msg_data :錯誤信息
* p_trolin_rec :物料搬運單行的一行記錄
* p_line_id :物料搬運單行id
* p_transaction_quantity :事務處理數量
* p_transaction_date :事務處理日期
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE validate_data(x_return_status OUT NOCOPY VARCHAR2,
x_msg_count OUT NOCOPY NUMBER,
x_msg_data OUT NOCOPY VARCHAR2,
p_trolin_rec IN INV_MOVE_ORDER_PUB.Trolin_Rec_Type,
p_line_id IN NUMBER,
p_transaction_quantity IN NUMBER,
p_transaction_date IN DATE) IS
l_error_flag VARCHAR2(1) := 'N'; --錯誤標誌
l_error_message VARCHAR2(1000) := NULL;--錯誤信息
BEGIN
--初始化
l_error_flag := 'N';
IF p_trolin_rec.quantity <> p_transaction_quantity THEN
--接口中的數量和EBS系統中的剩餘的數量不一致
l_error_flag := 'Y';
l_error_message := '接口中的數量' || p_transaction_quantity ||
'與EBS系統中的剩餘的數量' || p_trolin_rec.quantity || '不一致';
GOTO end_error;
END IF;
--檢查並驗證庫存的現用量和可用量
validate_subinv_quantity(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
p_trolin_rec => p_trolin_rec,
p_transaction_quantity => p_transaction_quantity,
p_transaction_date => p_transaction_date);
IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
RETURN;
END IF;
NULL; --添加一個可執行語句,防止GOTO語句出錯
<<end_error>>
IF l_error_flag = 'N' THEN
x_return_status := fnd_api.G_RET_STS_SUCCESS;
ELSE
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
x_msg_count := 1;
x_msg_data := l_error_message;
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('進行數據有效性驗證時出現異常:' || SQLERRM);
END validate_data;
/*=======================================================
* FUNCTION / PROCEDURE
* get_trolin_rec
* DESCRIPTION:
* 得到物料搬運單的一行記錄
* ARGUMENT:
* x_return_status :狀態
* x_trolin_rec :物料搬運單行的一行記錄
* p_trolin_tbl :一條物料搬運單的所有搬運單行
* p_line_id :物料搬運單行id
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE get_trolin_rec(x_return_status OUT NOCOPY VARCHAR2,
x_trolin_rec OUT NOCOPY INV_MOVE_ORDER_PUB.Trolin_Rec_Type,
p_trolin_tbl IN INV_MOVE_ORDER_PUB.Trolin_Tbl_Type,
p_line_id IN NUMBER) IS
l_table_index NUMBER := 0;
BEGIN
FOR l_table_index IN 1 .. p_trolin_tbl.COUNT LOOP
IF p_line_id = p_trolin_tbl(l_table_index).line_id THEN
x_trolin_rec := p_trolin_tbl(l_table_index);
x_return_status := fnd_api.G_RET_STS_SUCCESS;
RETURN;
END IF;
END LOOP; --FOR x_table_index IN x_trolin_tbl.COUNT LOOP
x_return_status := fnd_api.G_RET_STS_UNEXP_ERROR;
EXCEPTION
WHEN OTHERS THEN
put_log('得到物料搬運單時出現異常:' || SQLERRM);
END get_trolin_rec;
/*=======================================================
* FUNCTION / PROCEDURE
* get_transaction_action_id
* DESCRIPTION:
* 得到事務處理的活動id
* ARGUMENT:
* p_transaction_type_id:事務處理類型id
* RETURN:
* 事務處理的活動id
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
FUNCTION get_transaction_action_id(p_transaction_type_id IN NUMBER)
RETURN NUMBER IS
l_transaction_action_id NUMBER;--事務處理的活動id
BEGIN
SELECT mtt.transaction_action_id
INTO l_transaction_action_id
FROM mtl_transaction_types mtt
WHERE mtt.transaction_type_id = p_transaction_type_id;
RETURN l_transaction_action_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
WHEN TOO_MANY_ROWS THEN
put_log('得到事務處理的活動id時返回的多個行!');
WHEN OTHERS THEN
put_log('得到物料搬運單活動id時出現異常:' || SQLERRM);
END get_transaction_action_id;
/*=======================================================
* FUNCTION / PROCEDURE
* get_acct_period_id
* DESCRIPTION:
* 得到庫存會計期id
* ARGUMENT:
* p_organization_id :庫存組織id
* p_transaction_date:事務處理日期
* RETURN:
* 庫存會計期id
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
FUNCTION get_acct_period_id(p_organization_id IN NUMBER,
p_transaction_date IN DATE) RETURN NUMBER IS
l_acct_period_id NUMBER;--庫存會計期id
BEGIN
SELECT oap.acct_period_id
INTO l_acct_period_id
FROM org_acct_periods oap
WHERE oap.organization_id = p_organization_id
AND (p_transaction_date BETWEEN oap.period_start_date AND
oap.schedule_close_date);
RETURN l_acct_period_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
WHEN TOO_MANY_ROWS THEN
put_log('得到庫存會計期id時返回的多個行!');
WHEN OTHERS THEN
put_log('得到庫存會計期id時出現異常:' || SQLERRM);
END get_acct_period_id;
/*=======================================================
* FUNCTION / PROCEDURE
* insert_mmtt_row
* DESCRIPTION:
* 插入某一物料搬運單事務處理臨時表的一條記錄
* ARGUMENT:
* x_return_status :狀態
* x_transaction_temp_id :臨時表id
* x_msg_data :錯誤信息
* x_trohdr_rec :物料搬運單頭的一行記錄
* x_trohdr_val_rec :物料搬運單頭的一行記錄對應的值
* x_trolin_tbl :一個物料搬運單頭對應的所有物料搬運單行
* x_trolin_val_tbl :一個物料搬運單頭對應的所有物料搬運單行的值
* p_header_id :物料搬運單頭id
* p_line_id :物料搬運單行id
* p_transaction_quantity :事務處理數量
* p_transaction_date :事務處理日期
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE insert_mmtt_row(x_return_status OUT NOCOPY VARCHAR2,
x_transaction_temp_id OUT NUMBER,
p_trohdr_rec IN INV_MOVE_ORDER_PUB.Trohdr_Rec_Type,
p_trohdr_val_rec IN INV_MOVE_ORDER_PUB.Trohdr_Val_Rec_Type,
p_trolin_tbl IN INV_MOVE_ORDER_PUB.Trolin_Tbl_Type,
p_trolin_val_tbl IN INV_MOVE_ORDER_PUB.Trolin_Val_Tbl_Type,
p_header_id IN NUMBER,
p_line_id IN NUMBER,
p_transaction_quantity IN NUMBER,
p_transaction_date IN DATE) IS
l_mo_line_detail_rec inv_mo_line_detail_util.g_mmtt_rec;
l_transaction_temp_id NUMBER; --臨時表的id
l_trolin_rec INV_MOVE_ORDER_PUB.Trolin_Rec_Type;
x_locator_type VARCHAR2(60); --貨位控制類型
x_from_locator_id NUMBER; --來源貨位
x_to_locator_id NUMBER; --目標貨位
x_msg_data VARCHAR2(2000); --錯誤信息
BEGIN
--得到某一物料搬運單行的信息
get_trolin_rec(x_return_status => x_return_status,
x_trolin_rec => l_trolin_rec,
p_trolin_tbl => p_trolin_tbl,
p_line_id => p_line_id);
--檢查是否啓用貨位控制,如果啓用,則動態生成貨位
SELECT mtl_material_transactions_s.nextval
INTO l_transaction_temp_id
FROM DUAL;
--判斷貨位是否已經存在,如果存在,則自動創建貨位
check_and_create_locator(x_return_status => x_return_status,
x_msg_data => x_msg_data,
x_locator_type => x_locator_type,
x_from_locator_id => x_from_locator_id,
x_to_locator_id => x_to_locator_id,
p_trolin_rec => l_trolin_rec);
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('項目號:' || l_trolin_rec.project_id);
put_log('項目號:' || l_trolin_rec.task_id);
put_log('來源貨位id:' || x_from_locator_id);
put_log('目標貨位id:' || x_to_locator_id);
END IF;
l_mo_line_detail_rec.locator_id := x_from_locator_id; --源子庫存貨位
l_mo_line_detail_rec.transfer_to_location := x_to_locator_id; --目標子庫存貨位
l_mo_line_detail_rec.transaction_header_id := NULL;
l_mo_line_detail_rec.transaction_temp_id := l_transaction_temp_id;
l_mo_line_detail_rec.source_code := NULL;
l_mo_line_detail_rec.source_line_id := NULL;
l_mo_line_detail_rec.transaction_mode := 1;
l_mo_line_detail_rec.lock_flag := 'N';
l_mo_line_detail_rec.last_update_date := SYSDATE;
l_mo_line_detail_rec.last_updated_by := fnd_global.user_id;
l_mo_line_detail_rec.creation_date := SYSDATE;
l_mo_line_detail_rec.created_by := fnd_global.user_id;
l_mo_line_detail_rec.last_update_login := fnd_global.user_id;
l_mo_line_detail_rec.request_id := NULL;
l_mo_line_detail_rec.program_application_id := NULL;
l_mo_line_detail_rec.program_id := NULL;
l_mo_line_detail_rec.program_update_date := NULL;
--從物料搬運單得到item_id
l_mo_line_detail_rec.inventory_item_id := l_trolin_rec.inventory_item_id;
l_mo_line_detail_rec.revision := NULL;
l_mo_line_detail_rec.organization_id := l_trolin_rec.organization_id;
l_mo_line_detail_rec.subinventory_code := l_trolin_rec.from_subinventory_code;
--l_mo_line_detail_rec.locator_id := l_trolin_rec.from_locator_id;
l_mo_line_detail_rec.transaction_quantity := p_transaction_quantity;
l_mo_line_detail_rec.primary_quantity := p_transaction_quantity;
l_mo_line_detail_rec.transaction_uom := l_trolin_rec.uom_code;
l_mo_line_detail_rec.transaction_cost := NULL;
l_mo_line_detail_rec.transaction_type_id := l_trolin_rec.transaction_type_id;
l_mo_line_detail_rec.transaction_action_id := get_transaction_action_id(l_trolin_rec.transaction_type_id);
l_mo_line_detail_rec.transaction_source_type_id := l_trolin_rec.transaction_source_type_id;
l_mo_line_detail_rec.transaction_source_id := p_header_id;
l_mo_line_detail_rec.transaction_source_name := NULL;
l_mo_line_detail_rec.transaction_date := p_transaction_date;
l_mo_line_detail_rec.acct_period_id := get_acct_period_id(l_trolin_rec.organization_id,
p_transaction_date); --賬戶期間id
l_mo_line_detail_rec.distribution_account_id := NULL;
l_mo_line_detail_rec.transaction_reference := NULL;
l_mo_line_detail_rec.requisition_line_id := NULL;
l_mo_line_detail_rec.requisition_distribution_id := NULL;
l_mo_line_detail_rec.reason_id := l_trolin_rec.reason_id;
l_mo_line_detail_rec.lot_number := l_trolin_rec.lot_number;
l_mo_line_detail_rec.lot_expiration_date := NULL;
l_mo_line_detail_rec.serial_number := NULL;
l_mo_line_detail_rec.receiving_document := NULL;
l_mo_line_detail_rec.demand_id := NULL;
l_mo_line_detail_rec.rcv_transaction_id := NULL;
l_mo_line_detail_rec.move_transaction_id := NULL;
l_mo_line_detail_rec.completion_transaction_id := NULL;
l_mo_line_detail_rec.wip_entity_type := NULL;
l_mo_line_detail_rec.schedule_id := NULL;
l_mo_line_detail_rec.repetitive_line_id := NULL;
l_mo_line_detail_rec.employee_code := NULL;
l_mo_line_detail_rec.primary_switch := NULL;
l_mo_line_detail_rec.schedule_update_code := NULL;
l_mo_line_detail_rec.setup_teardown_code := NULL;
l_mo_line_detail_rec.item_ordering := NULL;
l_mo_line_detail_rec.negative_req_flag := NULL;
l_mo_line_detail_rec.operation_seq_num := NULL;
l_mo_line_detail_rec.picking_line_id := NULL;
l_mo_line_detail_rec.trx_source_line_id := p_line_id;
l_mo_line_detail_rec.trx_source_delivery_id := NULL;
l_mo_line_detail_rec.physical_adjustment_id := NULL;
l_mo_line_detail_rec.cycle_count_id := NULL;
l_mo_line_detail_rec.rma_line_id := NULL;
l_mo_line_detail_rec.customer_ship_id := NULL;
l_mo_line_detail_rec.currency_code := NULL;
l_mo_line_detail_rec.currency_conversion_rate := NULL;
l_mo_line_detail_rec.currency_conversion_type := NULL;
l_mo_line_detail_rec.currency_conversion_date := NULL;
l_mo_line_detail_rec.ussgl_transaction_code := NULL;
l_mo_line_detail_rec.vendor_lot_number := NULL;
l_mo_line_detail_rec.encumbrance_account := NULL;
l_mo_line_detail_rec.encumbrance_amount := NULL;
l_mo_line_detail_rec.ship_to_location := NULL;
l_mo_line_detail_rec.shipment_number := NULL;
l_mo_line_detail_rec.transfer_cost := NULL;
l_mo_line_detail_rec.transportation_cost := NULL;
l_mo_line_detail_rec.transportation_account := NULL;
l_mo_line_detail_rec.freight_code := NULL;
l_mo_line_detail_rec.containers := NULL;
l_mo_line_detail_rec.waybill_airbill := NULL;
l_mo_line_detail_rec.expected_arrival_date := NULL;
l_mo_line_detail_rec.transfer_subinventory := l_trolin_rec.to_subinventory_code;
l_mo_line_detail_rec.transfer_organization := NULL;
l_mo_line_detail_rec.new_average_cost := NULL;
l_mo_line_detail_rec.value_change := NULL;
l_mo_line_detail_rec.percentage_change := NULL;
l_mo_line_detail_rec.material_allocation_temp_id := NULL;
l_mo_line_detail_rec.demand_source_header_id := p_header_id;
l_mo_line_detail_rec.demand_source_line := to_char(p_line_id);
l_mo_line_detail_rec.demand_source_delivery := NULL;
l_mo_line_detail_rec.item_segments := NULL;
l_mo_line_detail_rec.item_description := NULL;
l_mo_line_detail_rec.item_trx_enabled_flag := NULL;
l_mo_line_detail_rec.item_location_control_code := NULL;
l_mo_line_detail_rec.item_restrict_subinv_code := NULL;
l_mo_line_detail_rec.item_restrict_locators_code := NULL;
l_mo_line_detail_rec.item_revision_qty_control_code := NULL;
l_mo_line_detail_rec.item_primary_uom_code := NULL;
l_mo_line_detail_rec.item_uom_class := NULL;
l_mo_line_detail_rec.item_shelf_life_code := NULL;
l_mo_line_detail_rec.item_shelf_life_days := NULL;
l_mo_line_detail_rec.item_lot_control_code := NULL;
l_mo_line_detail_rec.item_serial_control_code := NULL;
l_mo_line_detail_rec.item_inventory_asset_flag := NULL;
l_mo_line_detail_rec.allowed_units_lookup_code := NULL;
l_mo_line_detail_rec.department_id := NULL;
l_mo_line_detail_rec.department_code := NULL;
l_mo_line_detail_rec.wip_supply_type := NULL;
l_mo_line_detail_rec.supply_subinventory := NULL;
l_mo_line_detail_rec.supply_locator_id := NULL;
l_mo_line_detail_rec.valid_subinventory_flag := NULL;
l_mo_line_detail_rec.valid_locator_flag := NULL;
l_mo_line_detail_rec.locator_segments := NULL;
l_mo_line_detail_rec.current_locator_control_code := NULL;
l_mo_line_detail_rec.number_of_lots_entered := NULL;
l_mo_line_detail_rec.wip_commit_flag := NULL;
l_mo_line_detail_rec.next_lot_number := NULL;
l_mo_line_detail_rec.lot_alpha_prefix := NULL;
l_mo_line_detail_rec.next_serial_number := NULL;
l_mo_line_detail_rec.serial_alpha_prefix := NULL;
l_mo_line_detail_rec.shippable_flag := NULL;
l_mo_line_detail_rec.posting_flag := 'Y';
l_mo_line_detail_rec.required_flag := NULL;
l_mo_line_detail_rec.process_flag := 'Y';
l_mo_line_detail_rec.error_code := NULL;
l_mo_line_detail_rec.error_explanation := NULL;
l_mo_line_detail_rec.attribute_category := NULL;
l_mo_line_detail_rec.attribute1 := NULL;
l_mo_line_detail_rec.attribute2 := NULL;
l_mo_line_detail_rec.attribute3 := NULL;
l_mo_line_detail_rec.attribute4 := NULL;
l_mo_line_detail_rec.attribute5 := NULL;
l_mo_line_detail_rec.attribute6 := NULL;
l_mo_line_detail_rec.attribute7 := NULL;
l_mo_line_detail_rec.attribute8 := NULL;
l_mo_line_detail_rec.attribute9 := NULL;
l_mo_line_detail_rec.attribute10 := NULL;
l_mo_line_detail_rec.attribute11 := NULL;
l_mo_line_detail_rec.attribute12 := NULL;
l_mo_line_detail_rec.attribute13 := NULL;
l_mo_line_detail_rec.attribute14 := NULL;
l_mo_line_detail_rec.attribute15 := NULL;
l_mo_line_detail_rec.movement_id := NULL;
l_mo_line_detail_rec.reservation_quantity := NULL;
l_mo_line_detail_rec.shipped_quantity := NULL;
l_mo_line_detail_rec.transaction_line_number := NULL;
l_mo_line_detail_rec.task_id := NULL;
l_mo_line_detail_rec.to_task_id := NULL;
l_mo_line_detail_rec.source_task_id := NULL;
l_mo_line_detail_rec.project_id := NULL;
l_mo_line_detail_rec.source_project_id := NULL;
l_mo_line_detail_rec.pa_expenditure_org_id := NULL;
l_mo_line_detail_rec.to_project_id := NULL;
l_mo_line_detail_rec.expenditure_type := NULL;
l_mo_line_detail_rec.final_completion_flag := 'N';
l_mo_line_detail_rec.transfer_percentage := NULL;
l_mo_line_detail_rec.transaction_sequence_id := NULL;
l_mo_line_detail_rec.material_account := NULL;
l_mo_line_detail_rec.material_overhead_account := NULL;
l_mo_line_detail_rec.resource_account := NULL;
l_mo_line_detail_rec.outside_processing_account := NULL;
l_mo_line_detail_rec.overhead_account := NULL;
l_mo_line_detail_rec.flow_schedule := NULL;
l_mo_line_detail_rec.cost_group_id := NULL;
l_mo_line_detail_rec.demand_class := NULL;
l_mo_line_detail_rec.qa_collection_id := NULL;
l_mo_line_detail_rec.kanban_card_id := NULL;
l_mo_line_detail_rec.overcompletion_transaction_id := NULL;
l_mo_line_detail_rec.overcompletion_primary_qty := NULL;
l_mo_line_detail_rec.overcompletion_transaction_qty := NULL;
l_mo_line_detail_rec.end_item_unit_number := NULL;
l_mo_line_detail_rec.scheduled_payback_date := NULL;
l_mo_line_detail_rec.line_type_code := NULL;
l_mo_line_detail_rec.parent_transaction_temp_id := NULL;
l_mo_line_detail_rec.put_away_strategy_id := NULL;
l_mo_line_detail_rec.put_away_rule_id := NULL;
l_mo_line_detail_rec.pick_strategy_id := l_trolin_rec.pick_strategy_id;
l_mo_line_detail_rec.pick_rule_id := NULL;
l_mo_line_detail_rec.common_bom_seq_id := NULL;
l_mo_line_detail_rec.common_routing_seq_id := NULL;
l_mo_line_detail_rec.cost_type_id := NULL;
l_mo_line_detail_rec.org_cost_group_id := NULL;
l_mo_line_detail_rec.move_order_line_id := p_line_id;
l_mo_line_detail_rec.task_group_id := NULL;
l_mo_line_detail_rec.pick_slip_number := l_trolin_rec.pick_slip_number;
l_mo_line_detail_rec.reservation_id := NULL;
l_mo_line_detail_rec.transaction_status := 2; -- --Indicates if it has to be processed or just saved. NULL or 1 is default behavior. 2 is save only. 3 is ready to process
l_mo_line_detail_rec.transfer_cost_group_id := NULL;
l_mo_line_detail_rec.lpn_id := NULL;
l_mo_line_detail_rec.transfer_lpn_id := NULL;
l_mo_line_detail_rec.pick_slip_date := l_trolin_rec.pick_slip_date;
l_mo_line_detail_rec.content_lpn_id := NULL;
l_mo_line_detail_rec.secondary_transaction_quantity := NULL;
l_mo_line_detail_rec.secondary_uom_code := NULL;
--調用標準的API對MMTT進行插入
inv_mo_line_detail_util.insert_row(x_return_status => x_return_status,
p_mo_line_detail_rec => l_mo_line_detail_rec);
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('x_return_status:' || x_return_status);
END IF;
IF x_return_status = fnd_api.G_RET_STS_SUCCESS THEN
x_transaction_temp_id := l_transaction_temp_id; --回傳mmtt的唯一性標識
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('插入mmtt處理行時出現異常:' || SQLERRM);
END insert_mmtt_row;
/*=======================================================
* FUNCTION / PROCEDURE
* delete_mmtt_row
* DESCRIPTION:
* 刪除某一物料搬運單事務處理臨時表的一條記錄
* ARGUMENT:
* p_header_id:物料搬運單頭id
* p_line_id :物料搬運單行id
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE delete_mmtt_row(x_return_status OUT VARCHAR2,
p_line_id IN NUMBER,
p_transaction_temp_id IN NUMBER) IS
BEGIN
inv_mo_line_detail_util.delete_row(x_return_status => x_return_status,
p_line_id => p_line_id,
p_line_detail_id => p_transaction_temp_id);
EXCEPTION
WHEN OTHERS THEN
put_log('刪除某一物料搬運單的處理行時出現異常:' || SQLERRM);
END delete_mmtt_row;
/*=======================================================
* FUNCTION / PROCEDURE
* process_data
* DESCRIPTION:
* 自動處理物料搬運單
* ARGUMENT:
* x_return_status :返回狀態
* x_msg_count :返回的行數
* x_msg_data :返回的信息
* p_line_id :物料搬運單行id
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE process_data(x_return_status OUT NOCOPY VARCHAR2,
x_msg_count OUT NOCOPY NUMBER,
x_msg_data OUT NOCOPY VARCHAR2,
p_line_id IN NUMBER) IS
x_number_of_rows NUMBER;
x_detailed_qty NUMBER;
x_revision VARCHAR2(3);
x_locator_id NUMBER;
x_transfer_to_location NUMBER;
x_lot_number VARCHAR2(80);
x_expiration_date DATE;
x_transaction_temp_id NUMBER;
l_trolin_tbl INV_MOVE_ORDER_PUB.Trolin_Tbl_Type;
l_mold_tbl INV_MO_LINE_DETAIL_UTIL.g_mmtt_tbl_type;
x_mmtt_tbl INV_MO_LINE_DETAIL_UTIL.g_mmtt_tbl_type;
x_trolin_tbl INV_Move_Order_PUB.Trolin_Tbl_Type;
l_mo_line_detail_rec inv_mo_line_detail_util.g_mmtt_rec;
BEGIN
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('--------創建物料搬運單分配行開始----------');
END IF;
INV_Replenish_Detail_PUB.line_details_pub(p_line_id => p_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 => 1,
p_serial_flag => FND_API.G_TRUE,
p_plan_tasks => NULL,
p_auto_pick_confirm => NULL,
p_commit => NULL);
IF l_mo_debug_falg = 'Y' THEN
--輸出調試信息
put_log('x_number_of_rows:' || x_number_of_rows);
put_log('x_return_status:' || x_return_status);
put_log('--------創建物料搬運單分配行結束----------');
END IF;
IF x_number_of_rows > 0 AND x_return_status = fnd_api.G_RET_STS_SUCCESS THEN
--得到物料搬運單行信息
IF l_mo_debug_falg = 'Y' THEN --輸出調試信息
put_log('--------獲得物料搬運單行信息開始----------');
END IF;
l_trolin_tbl := inv_trolin_util.query_rows(p_line_id => p_line_id);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('--------獲得物料搬運單行信息結束----------');
put_log('--------自動挑庫確認開始----------');
END IF;
--自動挑庫確認
INV_PICK_WAVE_PICK_CONFIRM_PUB.Pick_Confirm(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_move_order_type => 1,
p_transaction_mode => 1,
p_trolin_tbl => l_trolin_tbl,
p_mold_tbl => l_mold_tbl,
x_mmtt_tbl => x_mmtt_tbl,
x_trolin_tbl => x_trolin_tbl,
p_transaction_date => NULL);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('x_return_status:' || x_return_status);
put_log('x_msg_count:' || x_msg_count);
put_log('x_msg_data:' || x_msg_data);
put_log('--------自動挑庫確認結束----------');
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('自動處理物料搬運單時出錯:' || SQLERRM);
END process_data;
/*=======================================================
* FUNCTION / PROCEDURE
* process_history_data
* DESCRIPTION:
* 處理上一次錯誤的歷史記錄
* ARGUMENT:
* x_processd_flag:上一次的錯誤記錄是否已經被處理
* p_line_id :物料搬運單行id
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
PROCEDURE process_history_data(x_processd_flag OUT VARCHAR2,
p_line_id IN NUMBER) IS
CURSOR cur_processed_order_info IS
SELECT mtrl.header_id header_id, --物料搬運單頭id,
mtrh.request_number request_number, --物料搬運單編號
mtrl.line_id line_id, --物料搬運單行id
mtrl.line_number line_number, --行號
mtrl.organization_id organization_id, --庫存組織ID
mtrl.inventory_item_id inventory_item_id, --物料ID
mtrh.transaction_type_id transaction_type_id, --事務處理類型ID
mtt.transaction_type_name transaction_type_name, --事務處理類型名稱
mlt.lookup_code line_status, --行狀態
mlt.meaning line_status_meaning --行狀態含義
FROM mtl_txn_request_lines mtrl,
mtl_txn_request_headers mtrh,
mtl_transaction_types mtt,
mfg_lookups mlt
WHERE mtrl.header_id = mtrh.header_id
AND mtrl.transaction_type_id = mtt.transaction_type_id
AND mtrl.line_status = mlt.lookup_code
AND mlt.lookup_type = 'MTL_TXN_REQUEST_STATUS'
AND mtrl.line_status = 5 --表示已經關閉,表示上次錯誤的記錄已經成功處理
AND mtt.transaction_action_id = 2 --事務處理的活動爲 子庫存轉移 的記錄
AND mtrl.line_id = p_line_id;
l_processed_count NUMBER := 0;
v_processd_flag VARCHAR2(1); --上次錯誤的 記錄是否已經被處理
BEGIN
x_processd_flag := 'N'; --默認爲上次的記錄沒有被處理
FOR rec_processed_order_info IN cur_processed_order_info LOOP
l_processed_count := l_processed_count + 1;
IF l_processed_count <> 0 THEN
v_processd_flag := 'Y';
EXIT;
END IF;
END LOOP;
IF l_processed_count = 0 THEN
v_processd_flag := 'N';
END IF;
IF v_processd_flag = 'Y' THEN
x_processd_flag := 'Y';
--如果上一次的錯誤記錄已經被處理,則更新客戶化表中的記錄的狀態
UPDATE cux_ediint_item_move_in ceimi
SET ceimi.process_id = 4, --將3改成4,表示此條記錄已經被處理,將這條記錄的狀態改成已經處理
ceimi.error_message = NULL, --錯誤信息修改成空
ceimi.attribute15 = '上一次處理出錯,已經通過系統手工或者其他方式進行處理!',
ceimi.last_update_date = SYSDATE,
ceimi.last_updated_by = fnd_global.user_id,
ceimi.last_update_login = fnd_global.user_id
WHERE ceimi.line_id = p_line_id
AND ceimi.process_id IN (1, 3); --錯誤的狀態
END IF;
EXCEPTION
WHEN OTHERS THEN
put_log('刪除某一物料搬運單的處理行時出現異常:' || SQLERRM);
END process_history_data;
/*=======================================================
* FUNCTION / PROCEDURE
* main
* DESCRIPTION:
* 併發程序入口
* ARGUMENT:
* errbuf :併發程序的系統參數,返回錯誤信息
* retcode :併發程序的系統參數, 執行狀態
* RETURN:
* N/A
* HISTORY:
* 1.00 27/10/2010 cxy
=========================================================*/
/*================================================================
* 主程序的步驟:
* 10 初始化
* 20 處理歷史記錄
* 30 驗證數據有效性
* 40 在MMTT表中插入一條記錄
* 50 自動處理物料搬運單
* 60 更新客戶化表的狀態和錯誤信息
* 70 輸出處理結果
=================================================================*/
PROCEDURE main(errbuf OUT NOCOPY VARCHAR2, retcode OUT NOCOPY VARCHAR2) IS
--使用cursor取出客戶化事務處理表中的所有物料搬運單頭信息,不取重複的記錄
CURSOR cur_item_move_imp_header IS
SELECT DISTINCT ceimi.header_id header_id, --物料搬運單頭id
ceimi.request_number request_number --物料搬運單編號
FROM cux_ediint_item_move_in ceimi
WHERE ceimi.process_id IN (0, 3); ----處理新增或者上次出錯的記錄,0表示沒有處理的記錄,3表示上一次處理出錯的記錄
--使用cursor 取出客戶化表中的物料搬運單行信息
CURSOR cur_item_move_imp_line(p_header_id NUMBER) IS
SELECT ceimi.header_id header_id, --物料搬運單頭id
ceimi.request_number request_number, --物料搬運單編號
ceimi.line_id line_id, --物料搬運單行id
ceimi.transaction_quantity transaction_quantity, --事務處理數量
ceimi.transaction_date transaction_date --事務處理日期
FROM cux_ediint_item_move_in ceimi
WHERE ceimi.process_id IN (0, 3) --處理新增或者上次出錯的記錄,0表示沒有處理的記錄,3表示上一次處理出錯的記錄
AND ceimi.header_id = p_header_id
ORDER BY ceimi.line_id;
x_return_status VARCHAR2(10); --處理狀態
x_msg_count NUMBER; --錯誤信息數量
x_msg_data VARCHAR2(2000); --錯誤信息
x_trohdr_rec INV_MOVE_ORDER_PUB.Trohdr_Rec_Type; --物料搬運單頭記錄
x_trohdr_val_rec INV_MOVE_ORDER_PUB.Trohdr_Val_Rec_Type; --物料搬運單頭對應的記錄
x_trolin_tbl INV_MOVE_ORDER_PUB.Trolin_Tbl_Type; --物料搬運單的所有行記錄
x_trolin_val_tbl INV_MOVE_ORDER_PUB.Trolin_Val_Tbl_Type; --物料搬運單的所有行對應的記錄
x_trolin_rec INV_MOVE_ORDER_PUB.Trolin_Rec_Type; --一條物料搬運單行
l_line_count NUMBER := 0; --處理的總行數
l_line_success_count NUMBER := 0; --處理成功的行數
x_transaction_temp_id NUMBER; --取得mmtt表的唯一性標識
x_processd_flag VARCHAR2(1); --上一次的歷史記錄是否被手工處理
BEGIN
--循環所有的物料搬運單
FOR rec_item_move_imp_header IN cur_item_move_imp_header LOOP
/*============================================================
* 10 初始化
* ------------------------------------------------------------
* 描述:初始化變量,並得到物料搬運單的相關信息
=============================================================*/
x_trohdr_rec := NULL; --物料搬運單頭記錄
x_trohdr_val_rec := NULL;
--得到物料搬運單信息
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('---------------獲取物料搬運單信息開始---------------------------');
END IF;
x_return_status := NULL; --處理狀態
get_move_order(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
x_trohdr_rec => x_trohdr_rec,
x_trohdr_val_rec => x_trohdr_val_rec,
x_trolin_tbl => x_trolin_tbl,
x_trolin_val_tbl => x_trolin_val_tbl,
p_header_id => rec_item_move_imp_header.header_id);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('---------------獲取物料搬運單行狀態:x_return_status:' ||
x_return_status);
put_log('---------------錯誤信息條數:x_msg_count:' || x_msg_count);
put_log('---------------錯誤信息:x_msg_data:' || x_msg_data);
put_log('---------------獲取物料搬運單信息結束---------------------------');
END IF;
--物料搬運單頭狀態正常,則處理此物料搬運單的所有行記錄
IF x_return_status = fnd_api.G_RET_STS_SUCCESS THEN
--循環物料搬運單的行,自動處理物料搬運單按照行進行處理
FOR rec_item_move_imp_line IN cur_item_move_imp_line(rec_item_move_imp_header.header_id) LOOP
--進行初始化
x_return_status := NULL; --處理狀態
x_msg_count := NULL; --錯誤信息條數
x_msg_data := NULL; --錯誤信息
--爲此執行塊創建一個SAVEPOINT
BEGIN
--創建SAVEPOINT cux_item_move_line
SAVEPOINT cux_item_move_line;
UPDATE cux_ediint_item_move_in ceimi
SET ceimi.process_id = 1, --1表示程序正在處理
ceimi.request_id = fnd_global.conc_request_id,
ceimi.last_update_date = SYSDATE,
ceimi.last_updated_by = fnd_global.user_id,
ceimi.last_update_login = fnd_global.user_id
WHERE ceimi.line_id = rec_item_move_imp_line.line_id;
/*=========================================================
* 20 處理歷史記錄
* ---------------------------------------------------------
* 描述:檢測歷史數據是否已經被處理,
* 並更新客戶表的狀態和錯誤信息
==========================================================*/
process_history_data(x_processd_flag => x_processd_flag,
p_line_id => rec_item_move_imp_line.line_id);
IF x_processd_flag = 'N' THEN
--等於‘N'表示上次處理錯誤的記錄沒有被手工處理
--得到某一物料搬運單行的信息
get_trolin_rec(x_return_status => x_return_status,
x_trolin_rec => x_trolin_rec,
p_trolin_tbl => x_trolin_tbl,
p_line_id => rec_item_move_imp_line.line_id);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('得到某一物料搬運單行的狀態:' || x_return_status);
END IF;
IF x_return_status = fnd_api.G_RET_STS_SUCCESS THEN
l_line_count := l_line_count + 1; --此次處理的總條數
/*==========================================================
* 30 驗證數據有效性
* ----------------------------------------------------------
* 描述:驗證客戶化表中的數據有效性,驗證接口表中的數量是否
* 等於物料搬運單的數量。並驗證庫存現用量和可用量。
============================================================*/
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('----------------開始驗證---------------------------');
END IF;
--驗證數據的有效性,包括是否存在貨位,物料可用量等信息
validate_data(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
p_trolin_rec => x_trolin_rec,
p_line_id => rec_item_move_imp_line.line_id,
p_transaction_quantity => rec_item_move_imp_line.transaction_quantity,
p_transaction_date => rec_item_move_imp_line.transaction_date);
IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
put_log('錯誤信息爲:' || x_msg_data);
--如果未通過驗證,則結束本次循環
GOTO line_end;
END IF;
IF l_mo_debug_falg = 'Y' THEN --輸出調試信息
put_log('---------------驗證結束---------------------------');
END IF;
/*=============================================================
* 40 在MMTT表中插入一條記錄
* -------------------------------------------------------------
* 描述:數據驗證通過後,給MMTT表中的字段賦值,並
* 在MMTT表中插入一條記錄。
===============================================================*/
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('---------------插入臨時表MMTT表的一條記錄開始---------------------------');
END IF;
--插入一條MMTT的記錄
insert_mmtt_row(x_return_status => x_return_status,
x_transaction_temp_id => x_transaction_temp_id,
p_trohdr_rec => x_trohdr_rec,
p_trohdr_val_rec => x_trohdr_val_rec,
p_trolin_tbl => x_trolin_tbl,
p_trolin_val_tbl => x_trolin_val_tbl,
p_header_id => rec_item_move_imp_line.header_id,
p_line_id => rec_item_move_imp_line.line_id,
p_transaction_quantity => rec_item_move_imp_line.transaction_quantity,
p_transaction_date => rec_item_move_imp_line.transaction_date);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('---------------插入臨時表MMTT表的一條記錄:x_return_status:' ||
x_return_status);
put_log('---------------插入臨時表MMTT表的一條記錄結束---------------------------');
END IF;
/*===============================================================
* 50 自動處理物料搬運單
* ---------------------------------------------------------------
* 描述:調用API自動處理物料搬運單
================================================================*/
IF x_return_status = fnd_api.G_RET_STS_SUCCESS THEN
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('---------------自動處理物料搬運單開始---------------------------');
END IF;
--處理物料搬運單
process_data(x_return_status => x_return_status,
x_msg_count => x_msg_count,
x_msg_data => x_msg_data,
p_line_id => rec_item_move_imp_line.line_id);
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('---------------x_return_status:' ||
x_return_status);
put_log('---------------x_msg_count:' || x_msg_count);
put_log('---------------x_msg_data:' || x_msg_data);
put_log('---------------自動處理物料搬運單結束---------------------------');
END IF;
ELSE
EXIT;
put_log('錯誤信息爲:' || x_msg_data);
put_log('CUX:物料搬運單事務處理時,發生異常:' || SQLERRM);
END IF;
--本次循環結束標誌
<<line_end>>
/*========================================================================
* 60 更新客戶化表的狀態和錯誤信息
* ------------------------------------------------------------------------
* 描述:更新客戶化表的狀態:
* process_flag =0,表示爲新的記錄,需要進行處理。
* process_flag =1,表示正在處理
* process_flag =3,程序處理異常或者錯誤,並將錯誤信息賦值給error_message
* process_flag =4,表示處理成功。
========================================================================*/
IF x_return_status = fnd_api.G_RET_STS_SUCCESS THEN --處理成功
l_line_success_count := l_line_success_count + 1; --處理成功的記錄
--表示處理成功
UPDATE cux_ediint_item_move_in ceimi
SET ceimi.process_id = 4, --表示處理成功
ceimi.error_message = NULL,
ceimi.last_update_date = SYSDATE,
ceimi.last_updated_by = fnd_global.user_id,
ceimi.last_update_login = fnd_global.user_id
WHERE ceimi.line_id = rec_item_move_imp_line.line_id;
END IF;
IF x_return_status = fnd_api.G_RET_STS_UNEXP_ERROR THEN--處理失敗
UPDATE cux_ediint_item_move_in ceimi
SET ceimi.process_id = 3, --程序出現異常
ceimi.error_message = TRIM(x_msg_data), --錯誤信息
ceimi.last_update_date = SYSDATE,
ceimi.last_updated_by = fnd_global.user_id,
ceimi.last_update_login = fnd_global.user_id
WHERE ceimi.line_id = rec_item_move_imp_line.line_id;
--刪除MMTT表中未被成功處理的記錄
delete_mmtt_row(x_return_status => x_return_status,
p_line_id => rec_item_move_imp_line.line_id,
p_transaction_temp_id => x_transaction_temp_id);
END IF;
END IF;
ELSE--上次處理錯誤的記錄被手工處理
l_line_count := l_line_count + 1; --此次處理的總條數
l_line_success_count := l_line_success_count + 1; --處理成功的記錄
END IF;
--一條物料搬運單行處理結束,進行事務處理的提交
COMMIT;
EXCEPTION --物料搬運行出現異常
WHEN OTHERS THEN
--如果此條記錄出現異常,則回滾到SAVEPOINT cux_item_move_line
ROLLBACK TO cux_item_move_line;
put_log('處理物料搬運單行時,發生異常:' || SQLERRM);
END; --end begin
END LOOP; --FOR rec_item_move_imp_line IN cur_item_move_imp_line LOOP
ELSE
retcode := 1; --如果存在沒有成功處理的物料搬運單,則顯示警告
put_log('得到物料搬運單頭時發生異常:' || x_msg_data);
END IF;
END LOOP; --FOR rec_item_move_imp_header IN cur_item_move_imp_header LOOP
--輸出處理的信息(包括成功的信息和錯誤的信息)
IF l_mo_debug_falg = 'Y' THEN--輸出調試信息
put_log('總行數:' || l_line_count);
put_log('處理成功的總行數:' || l_line_success_count);
END IF;
/*========================================================================
* 70 輸出處理結果
* ------------------------------------------------------------------------
* 描述:處理物料搬運單的處理結果包括:
* 1.處理錯誤的記錄
* 2.處理失敗的記錄及其錯誤信息
========================================================================*/
output_move_order_info(p_line_count => l_line_count,
p_line_success_count => l_line_success_count);
IF (l_line_count <> 0) AND (l_line_count <> l_line_success_count) THEN--如果存在處理錯誤的信息,則請求顯示警告
retcode := 1; --如果存在沒有成功處理的物料搬運單,則顯示警告
END IF;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
retcode := 2;
put_log('錯誤信息爲:' || x_msg_data);
put_log('CUX:物料搬運單事務處理時,發生異常:' || SQLERRM);
END main;
END CUX_EDIINT_ITEM_MOVE_IN_PKG;