Physical Inventory Tag interface Program
Business Requirement:
User want to update the bulk of lines in physical tag counts and physical adjustment as well. The below interface is used to satisfy the both conditions with validation.
step :1
--------
-- Create staging table for upload the csv file
CREATE TABLE APPS.XXHMI_PHYSICAL_COUNT_DATA
(
PHYSICAL_INVENTORY_NAME VARCHAR2(30 BYTE),
TAG_NUMBER VARCHAR2(40 BYTE),
OPERATING_UNIT VARCHAR2(40 BYTE),
ITEM_NAME VARCHAR2(150 BYTE),
SUBINVENTORY_NAME VARCHAR2(10 BYTE),
LOCATOR_NAME VARCHAR2(122 BYTE),
PARENT_LPN VARCHAR2(30 BYTE),
TAG_QUANTITY NUMBER,
TAG_UOM VARCHAR2(3 BYTE),
EMPLOYEE_NUMBER VARCHAR2(30 BYTE),
PROCESS_FLAG VARCHAR2(1 BYTE),
REMARKS VARCHAR2(100 BYTE)
)
Step 2:
Register the loader concurrent with the following shortname XXHMI_PHY_CNT_TAG in to oracle apps.
Parameter : File name
CTL file:
-------------
options (skip=1)
load data
TRUNCATE
INTO TABLE XXHMI_PHYSICAL_COUNT_DATA
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS(
Physical_Inventory_Name,
TAG_NUMBER,
Operating_unit,
item_name,
subinventory_name,
locator_name,
PARENT_LPN,
TAG_quantity,
TAG_UOM,
employee_number,
process_flag CONSTANT 'N',
remarks)
Step 3: Register the below package in oracle apps
Executable Name : XXHMI_PHYSICAL_COUNT_TAGS.main
Parameter : filename
CREATE OR REPLACE PACKAGE BODY APPS.XXHMI_PHYSICAL_COUNT_TAGS
IS
/*******************************************************************************
* *
* Project : HLIFE *
* Module : INV *
* Table Name : XXHMI_PHYSICAL_COUNT_DATA *
* Description : Upload Physical Tag Data *
* *
* *
* *
* *
********************************************************************************
* Program History *
* *
* Date In Charge Description *
* ---------- --------- ----------------------------------------------- *
* 15-dec-2011 Vinoth kumar For Physical Tag data upload *
*******************************************************************************/
PROCEDURE main (errbuf OUT VARCHAR2,
retcode OUT NUMBER,
p_file_name IN VARCHAR2)
IS
l_retcode NUMBER;
l_errbuff VARCHAR2 (4000);
BEGIN
fnd_global.apps_initialize (fnd_profile.VALUE ('USER_ID'),
fnd_profile.VALUE ('RESP_ID'),
fnd_profile.VALUE ('RESP_APPL_ID'),
NULL,
NULL);
load_file_data (errbuf => l_errbuff,
retcode => l_retcode,
p_file_name => p_file_name);
IF l_retcode = 0
THEN
BEGIN
update_data_interface (errbuf => l_errbuff, retcode => l_retcode);
END;
END IF;
EXCEPTION
WHEN OTHERS
THEN
errbuf := 'ERROR IN MAIN PROCEDURE' || SQLERRM || SQLCODE;
retcode := 2;
fnd_file.put_line (fnd_file.output, 'Check outfile');
COMMIT;
END;
PROCEDURE load_file_data (errbuf OUT VARCHAR2,
retcode OUT NUMBER,
p_file_name IN VARCHAR2)
IS
l_request_id fnd_concurrent_requests.request_id%TYPE;
l_status_code fnd_concurrent_requests.status_code%TYPE := '~';
lb_wait BOOLEAN;
lc_phase VARCHAR2 (100);
lc_status VARCHAR2 (30);
lc_devpha VARCHAR2 (100);
lc_devsta VARCHAR2 (100);
lc_mesg VARCHAR2 (50);
ln_data_discarded NUMBER;
l_in_file_path VARCHAR2 (2000);
BEGIN
/*BEGIN
DELETE FROM xxhmi_subinventory_xl xxhmi;
COMMIT;
END;*/
BEGIN
retcode := 0;
SELECT '/usr/tmp' --DESCRIPTION -- UTL directory for reading the CSV file
INTO l_in_file_path
FROM DUAL;
IF l_in_file_path IS NULL
THEN
fnd_file.put_line (
fnd_file.LOG,
'Path is not defined for reading in Lookup type HMI_INBOUND_IFACE_FILE_PATH'
);
retcode := 2;
RETURN;
END IF;
EXCEPTION
WHEN OTHERS
THEN
fnd_file.put_line (
fnd_file.LOG,
'Issue is uploading the excel data' || SQLCODE || SQLERRM
);
retcode := 2;
RETURN;
END;
fnd_global.apps_initialize (fnd_profile.VALUE ('USER_ID'),
fnd_profile.VALUE ('RESP_ID'),
fnd_profile.VALUE ('RESP_APPL_ID'),
NULL,
NULL);
l_request_id :=
fnd_request.submit_request ('XXHMI', --'XXHN', -- APPLICATION.
'XXHMI_PHY_CNT_TAG', -- Loader short name
-- CONCURRENT PROGRAM.
NULL, -- DESCRIPTION.
NULL, -- START_TIME.
FALSE, -- SUB_REQUEST.
l_in_file_path || '/' || p_file_name,
CHR (0));
COMMIT;
IF (l_request_id = 0)
THEN
retcode := 2;
fnd_file.put_line (fnd_file.LOG,
'Failed to submit the loader program');
ELSE
lb_wait :=
fnd_concurrent.wait_for_request (request_id => l_request_id,
INTERVAL => 2,
phase => lc_phase,
status => lc_status,
dev_phase => lc_devpha,
dev_status => lc_devsta,
MESSAGE => lc_mesg);
IF lc_status IN ('Error')
THEN
retcode := 2;
fnd_file.put_line (
fnd_file.LOG,
'Error while reading data from file check request id '
|| l_request_id
);
ELSIF lc_status IN ('Warning')
THEN
SELECT fcr.ofile_size
INTO ln_data_discarded
FROM fnd_concurrent_requests fcr
WHERE fcr.request_id = l_request_id;
IF ln_data_discarded IS NOT NULL
THEN
retcode := 2;
END IF;
ELSE
retcode := 0;
fnd_file.put_line (
fnd_file.LOG,
'File read sucessfully check request id ' || l_request_id
);
END IF;
END IF;
/* IF retcode = 0
THEN
BEGIN
trim_data;
END;
END IF;*/
EXCEPTION
WHEN OTHERS
THEN
fnd_file.put_line (fnd_file.LOG,
'Error From Main' || SQLCODE || SQLERRM);
retcode := 2;
END load_file_data;
PROCEDURE update_data_interface (errbuf OUT VARCHAR2, retcode OUT NUMBER)
IS
CURSOR c_validate
IS
SELECT * FROM XXHMI_PHYSICAL_COUNT_DATA;
CURSOR c_err
IS
SELECT *
FROM xxhmi_physical_count_data
WHERE PROCESS_FLAG <> 'Y';
--cursor c_process is select * from XXHMI_PHYSICAL_COUNT_DATA where process_flag='N'
v_phy_inv_id NUMBER;
v_operating_unit NUMBER;
v_item_id NUMBER;
v_locator_id NUMBER;
v_emp_id NUMBER;
v_adjust_id NUMBER;
v_count NUMBER;
v_count1 NUMBER;
v_lpn_id NUMBER;
v_remarks VARCHAR2 (250);
v_item_cost NUMBER;
v_cost_id NUMBER;
BEGIN
-- retcode := 0;
FOR i IN c_validate
LOOP
v_remarks := NULL;
v_lpn_id := NULL;
BEGIN
SELECT PHYSICAL_INVENTORY_ID
INTO v_phy_inv_id
FROM mtl_physical_inventories
WHERE PHYSICAL_INVENTORY_NAME = i.PHYSICAL_INVENTORY_NAME
AND organization_id IN
(SELECT organization_id
FROM hr_operating_units
WHERE name = i.operating_unit);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid Physical Inventory';
END;
BEGIN
SELECT COUNT ( * )
INTO v_count1
FROM mtl_physical_inventory_tags
WHERE TAG_NUMBER = i.TAG_NUMBER
AND PHYSICAL_INVENTORY_ID IN
(SELECT PHYSICAL_INVENTORY_ID
FROM mtl_physical_inventories
WHERE PHYSICAL_INVENTORY_NAME =
i.PHYSICAL_INVENTORY_NAME
AND organization_id IN
(SELECT organization_id
FROM hr_operating_units
WHERE name =
i.operating_unit));
IF v_count1 = 0
THEN
v_remarks := v_remarks || 'Invalid Tag Number';
END IF;
END;
BEGIN
SELECT organization_id
INTO v_operating_unit
FROM hr_operating_units
WHERE NAME = i.operating_unit;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid operating unit';
END;
BEGIN
SELECT COUNT ( * )
INTO v_count
FROM mtl_item_locations_kfv
WHERE SUBINVENTORY_CODE = i.SUBINVENTORY_NAME;
IF v_count = 0
THEN
v_remarks := v_remarks || 'Invalid subinventory';
END IF;
END;
BEGIN
SELECT DISTINCT INVENTORY_ITEM_ID
INTO v_item_id
FROM mtl_system_items_b
WHERE segment1 = i.ITEM_NAME;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid item_name';
END;
DBMS_OUTPUT.put_line ('hi v1');
BEGIN
SELECT ITEM_COST
INTO v_item_cost
FROM cst_item_costs
WHERE inventory_item_id = v_item_id
AND organization_id = v_operating_unit;
DBMS_OUTPUT.put_line ('hi v2');
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid item cost';
END;
-- BEGIN
-- DBMS_OUTPUT.put_line ('hi vcost');
-- SELECT DISTINCT NVL (cost_group_id, NULL)
-- INTO v_cost_id
-- FROM MTL_ONHAND_QUANTITIES_DETAIL
-- WHERE 1 = 1
-- AND inventory_item_id = v_item_id --12200
-- AND organization_id = v_operating_unit --81
-- AND SUBINVENTORY_CODE = i.subinventory_name;
-- DBMS_OUTPUT.put_line ('hi v3');
-- EXCEPTION
-- WHEN NO_DATA_FOUND
-- THEN
-- v_remarks :=
-- v_remarks
-- || 'Cost group not available'
-- || SQLERRM
-- || v_cost_id;
-- END;
BEGIN
SELECT INVENTORY_LOCATION_ID
INTO v_locator_id
FROM MTL_ITEM_LOCATIONS_kfv
WHERE CONCATENATED_SEGMENTS = LTRIM (RTRIM (i.LOCATOR_NAME))
AND organization_id IN
(SELECT organization_id
FROM hr_operating_units
WHERE name = i.operating_unit);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid Locator name';
END;
DBMS_OUTPUT.put_line ('hi v4');
BEGIN
SELECT user_id
INTO v_emp_id
FROM fnd_user
WHERE user_name = i.employee_number;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid employee number';
END;
IF i.PARENT_LPN IS NOT NULL
THEN
BEGIN
SELECT LPN_ID
INTO v_lpn_id
FROM wms_license_plate_numbers
WHERE license_plate_number = i.PARENT_LPN;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_remarks := v_remarks || 'Invalid LPN';
END;
END IF;
IF v_remarks IS NULL AND i.PROCESS_FLAG <> 'Y'
--or PROCESS_FLAG ='N')
THEN
SELECT MTL_PHYSICAL_ADJUSTMENTS_S.NEXTVAL
INTO v_adjust_id
FROM DUAL;
v_remarks := 'Success';
UPDATE mtl_physical_inventory_tags
SET LAST_UPDATE_DATE = SYSDATE,
ADJUSTMENT_ID = v_adjust_id,
INVENTORY_ITEM_ID = v_item_id,
TAG_QUANTITY = i.TAG_QUANTITY,
TAG_UOM = i.TAG_UOM,
TAG_QUANTITY_AT_STANDARD_UOM = i.TAG_QUANTITY,
STANDARD_UOM = i.TAG_UOM,
SUBINVENTORY = i.SUBINVENTORY_NAME,
LOCATOR_ID = v_locator_id,
COUNTED_BY_EMPLOYEE_ID = v_emp_id,
PARENT_LPN_ID = v_lpn_id,
OUTERMOST_LPN_ID = v_lpn_id,
LAST_UPDATED_BY = v_emp_id,
LAST_UPDATE_LOGIN = v_emp_id,
CREATED_BY = v_emp_id
--,
-- COST_GROUP_ID = NVL (v_cost_id, NULL)
WHERE PHYSICAL_INVENTORY_ID = v_phy_inv_id
AND ORGANIZATION_ID = v_operating_unit
AND TAG_NUMBER = i.TAG_NUMBER;
-- IF process_flag = 'N'
-- THEN
INSERT INTO MTL_PHYSICAL_ADJUSTMENTS (ADJUSTMENT_ID,
ORGANIZATION_ID,
PHYSICAL_INVENTORY_ID,
INVENTORY_ITEM_ID,
SUBINVENTORY_NAME,
SYSTEM_QUANTITY,
LAST_UPDATE_DATE,
LAST_UPDATED_BY,
CREATION_DATE,
CREATED_BY,
LAST_UPDATE_LOGIN,
COUNT_QUANTITY,
ADJUSTMENT_QUANTITY,
REVISION,
LOCATOR_ID,
PARENT_LPN_ID,
OUTERMOST_LPN_ID,
-- COST_GROUP_ID,
LOT_NUMBER,
LOT_EXPIRATION_DATE,
SERIAL_NUMBER,
ACTUAL_COST,
SECONDARY_SYSTEM_QTY,
SECONDARY_COUNT_QTY,
SECONDARY_ADJUSTMENT_QTY)
VALUES (v_adjust_id,
v_operating_unit,
v_phy_inv_id,
v_item_id,
i.SUBINVENTORY_NAME,
0,
SYSDATE,
v_emp_id,
SYSDATE,
v_emp_id,
v_emp_id,
i.TAG_QUANTITY,
i.tag_quantity,
NULL,
v_locator_id,
v_lpn_id,
v_lpn_id,
-- NVL (v_cost_id, NULL),
NULL,
NULL,
NULL,
v_item_cost,
NULL,
NULL,
NULL);
-- END IF;
UPDATE XXHMI_PHYSICAL_COUNT_DATA
SET Process_flag = 'Y', remarks = 'Success'
WHERE PHYSICAL_INVENTORY_NAME = i.PHYSICAL_INVENTORY_NAME
AND TAG_NUMBER = i.TAG_NUMBER
AND OPERATING_UNIT = i.OPERATING_UNIT;
COMMIT;
ELSE
UPDATE XXHMI_PHYSICAL_COUNT_DATA
SET Process_flag = 'E', remarks = v_remarks
WHERE PHYSICAL_INVENTORY_NAME = i.PHYSICAL_INVENTORY_NAME
AND TAG_NUMBER = i.TAG_NUMBER
AND OPERATING_UNIT = i.OPERATING_UNIT;
COMMIT;
END IF;
fnd_file.put_line (
fnd_file.LOG,
i.PHYSICAL_INVENTORY_NAME
|| '-'
|| i.TAG_NUMBER
|| '-'
|| v_remarks
);
END LOOP;
BEGIN
fnd_file.put_line (
fnd_file.output,
'PHYSICAL_INVENTORY_NAME'
|| '|'
|| 'TAG_NUMBER'
|| '|'
|| 'OPERATING_UNIT'
|| '|'
|| 'ITEM_NAME'
|| '|'
|| 'SUBINVENTORY_NAME'
|| '|'
|| 'LOCATOR_NAME'
|| '|'
|| 'PARENT_LPN'
|| '|'
|| 'TAG_QUANTITY'
|| '|'
|| 'TAG_UOM'
|| '|'
|| 'EMPLOYEE_NUMBER'
|| '|'
|| 'PROCESS_FLAG'
|| '|'
|| 'REMARKS'
);
FOR j IN c_err
LOOP
fnd_file.put_line (
fnd_file.output,
J.PHYSICAL_INVENTORY_NAME
|| '|'
|| J.TAG_NUMBER
|| '|'
|| J.OPERATING_UNIT
|| '|'
|| J.ITEM_NAME
|| '|'
|| J.SUBINVENTORY_NAME
|| '|'
|| J.LOCATOR_NAME
|| '|'
|| J.PARENT_LPN
|| '|'
|| J.TAG_QUANTITY
|| '|'
|| J.TAG_UOM
|| '|'
|| J.EMPLOYEE_NUMBER
|| '|'
|| J.PROCESS_FLAG
|| '|'
|| J.REMARKS
);
END LOOP;
END;
EXCEPTION
WHEN OTHERS
THEN
fnd_file.put_line (fnd_file.LOG,
'update_data_interface' || SQLCODE || SQLERRM);
DBMS_OUTPUT.put_line ('update_data_interface' || SQLCODE || SQLERRM);
-- retcode := 2;
RETURN;
END update_data_interface;
END XXHMI_PHYSICAL_COUNT_TAGS;
/
Step :4
Once register the concurrent then prepare the csv file and move to the utl dir (/USR/TMP/)
Step :5
Run the main program with the parameter of your file name with extension
Eg: Sample.csv
** note case senstive
Step :6 check the data in the front end
***************************END***********************