Take a look at the INV_Quantity_Tree_Pub package (under the APPS user) in your database. The "query_quantities" API has the following parameters;
P_API_VERSION_NUMBER NUMBER IN
P_INIT_MSG_LST VARCHAR2 IN Y
X_RETURN_STATUS VARCHAR2 OUT
X_MSG_COUNT NUMBER OUT
X_MSG_DATA VARCHAR2 OUT
P_ORGANIZATION_ID NUMBER IN
P_INVENTORY_ITEM_ID NUMBER IN
P_TREE_MODE NUMBER IN
P_IS_REVISION_CONTROL BOOLEAN IN
P_IS_LOT_CONTROL BOOLEAN IN
P_IS_SERIAL_CONTROL BOOLEAN IN
P_DEMAND_SOURCE_TYPE_ID NUMBER IN Y
P_DEMAND_SOURCE_HEADER_ID NUMBER IN Y
P_DEMAND_SOURCE_LINE_ID NUMBER IN Y
P_DEMAND_SOURCE_NAME VARCHAR2 IN Y
P_LOT_EXPIRATION_DATE DATE IN Y
P_REVISION VARCHAR2 IN
P_LOT_NUMBER VARCHAR2 IN
P_SUBINVENTORY_CODE VARCHAR2 IN
P_LOCATOR_ID NUMBER IN
P_ONHAND_SOURCE NUMBER IN Y
X_QOH NUMBER OUT
X_RQOH NUMBER OUT
X_QR NUMBER OUT
X_QS NUMBER OUT
X_ATT NUMBER OUT
X_ATR NUMBER OUT
P_TRANSFER_SUBINVENTORY_CODE VARCHAR2 IN Y
P_COST_GROUP_ID NUMBER IN Y
P_LPN_ID NUMBER IN Y
P_TRANSFER_LOCATOR_ID NUMBER IN Y
I said they have "provided a reasonably useful API" not that they had provided an "easy to use API"! Clearly if you want to get anything useful out of this API then you need to build a wrapper package for this (particularly if you want to be able to query quantities in SQL rather than PL/SQL - which I'm assuming you do).
I'm going to suggest you create a wrapper function called "get_onhand_quantity" as an example, it should be pretty clear how you alter this to return some of the other quantities associated with the item, here is the SQL:
CREATE OR REPLACE FUNCTION get_onhand_quantity(p_organization_id IN NUMBER,
p_inventory_item_id IN NUMBER,
p_subinventory_code IN VARCHAR2,
p_locator_id IN NUMBER,
p_lot_number IN VARCHAR2)
RETURN NUMBER IS
-- The various quantity values returned
v_QuantityOnhand NUMBER;
v_QuantityReservableOnhand NUMBER;
v_QuantityReserved NUMBER;
v_QuantitySuggested NUMBER;
v_QuantityAvailableToTransact NUMBER;
v_QuantityAvailableToReserve NUMBER;
-- Monitor the return status of the API
v_ReturnStatus VARCHAR2(1);
v_ReturnMessageCount NUMBER;
v_ReturnMessageData VARCHAR2(256);
begin
INV_QUANTITY_TREE_PUB.query_quantities(p_api_version_number => 1,
p_init_msg_lst => fnd_api.g_false,
x_return_status => v_ReturnStatus,
x_msg_count => v_ReturnMessageCount,
x_msg_data => v_ReturnMessageData,
p_organization_id => p_organization_id,
p_inventory_item_id => p_inventory_item_id,
p_tree_mode => apps.INV_Quantity_Tree_PUB.g_transaction_mode,
p_is_revision_control => FALSE,
p_is_lot_control => TRUE,
p_is_serial_control => FALSE,
p_demand_source_type_id => -9999,
p_demand_source_header_id => -9999,
p_demand_source_line_id => -9999,
p_demand_source_name => NULL,
p_lot_expiration_date => NULL,
p_revision => NULL,
p_lot_number => p_lot_number,
p_subinventory_code => p_subinventory_code,
p_locator_id => p_locator_id,
p_onhand_source => inv_quantity_tree_pvt.g_all_subs,
x_qoh => v_QuantityOnhand,
x_rqoh => v_QuantityReservableOnhand,
x_qr => v_QuantityReserved,
x_qs => v_QuantitySuggested,
x_att => v_QuantityAvailableToTransact,
x_atr => v_QuantityAvailableToReserve,
p_transfer_subinventory_code => NULL,
p_cost_group_id => NULL,
p_lpn_id => NULL,
p_transfer_locator_id => NULL);
RETURN(v_QuantityOnhand);
END get_onhand_quantity;
p_inventory_item_id IN NUMBER,
p_subinventory_code IN VARCHAR2,
p_locator_id IN NUMBER,
p_lot_number IN VARCHAR2)
RETURN NUMBER IS
-- The various quantity values returned
v_QuantityOnhand NUMBER;
v_QuantityReservableOnhand NUMBER;
v_QuantityReserved NUMBER;
v_QuantitySuggested NUMBER;
v_QuantityAvailableToTransact NUMBER;
v_QuantityAvailableToReserve NUMBER;
-- Monitor the return status of the API
v_ReturnStatus VARCHAR2(1);
v_ReturnMessageCount NUMBER;
v_ReturnMessageData VARCHAR2(256);
begin
INV_QUANTITY_TREE_PUB.query_quantities(p_api_version_number => 1,
p_init_msg_lst => fnd_api.g_false,
x_return_status => v_ReturnStatus,
x_msg_count => v_ReturnMessageCount,
x_msg_data => v_ReturnMessageData,
p_organization_id => p_organization_id,
p_inventory_item_id => p_inventory_item_id,
p_tree_mode => apps.INV_Quantity_Tree_PUB.g_transaction_mode,
p_is_revision_control => FALSE,
p_is_lot_control => TRUE,
p_is_serial_control => FALSE,
p_demand_source_type_id => -9999,
p_demand_source_header_id => -9999,
p_demand_source_line_id => -9999,
p_demand_source_name => NULL,
p_lot_expiration_date => NULL,
p_revision => NULL,
p_lot_number => p_lot_number,
p_subinventory_code => p_subinventory_code,
p_locator_id => p_locator_id,
p_onhand_source => inv_quantity_tree_pvt.g_all_subs,
x_qoh => v_QuantityOnhand,
x_rqoh => v_QuantityReservableOnhand,
x_qr => v_QuantityReserved,
x_qs => v_QuantitySuggested,
x_att => v_QuantityAvailableToTransact,
x_atr => v_QuantityAvailableToReserve,
p_transfer_subinventory_code => NULL,
p_cost_group_id => NULL,
p_lpn_id => NULL,
p_transfer_locator_id => NULL);
RETURN(v_QuantityOnhand);
END get_onhand_quantity;
The script is available as a Google Document here (which might be slightly easier to see).
Now a quick test script to demonstrate how this works;
select ii.Onhand_Quantity
from noetix_sys.INVG0_item_onhand_by_lot II
where ii.ORGANIZATION_CODE = '01'
and ii.Onhand_Quantity > 0
and ii.Inventory_Item_ID = 5097
and ii.lot_number = '155498RET'
and rownum = 1;
select get_onhand_quantity(302, 5097, 'RETAIN', 37976, '155498RET') Onhand_Quantity
from dual
The first step (at the top) is to use Noetix views to find the details of an item with Onhand Quantity greater than zero so that can be plugged into the Get_Onhand_Quantity function (it was also slightly comforting to see that both queries returned the same value).
What's it like for speed? Well that's an interesting question; it's substantially faster (as you'd expect; it's not going through a view) but as the timings for the first and second queries are 0.093 and 0.031 seconds respectively the difference isn't really significant in the wider scheme of things.
It will be interesting to see if a future version of Noetix uses the API (I'd certainly recommend it!).
No comments:
Post a Comment