Items assigned using API does not appear in Oracle EBS application windows - oracle

I used the following API to assign multiple items (one by one) from one organization to another.I had created test items through the inventory responsibility using master item window and then assign them to another organization using the following code:
BEGIN
DECLARE
l_api_version NUMBER := 1.0;
l_init_msg_list VARCHAR2(2) := FND_API.G_TRUE;
l_commit VARCHAR2(2) := FND_API.G_FALSE;
x_message_list error_handler.error_tbl_type;
itemid mtl_system_items_b.inventory_item_id %TYPE;
segment1 mtl_system_items_b.segment1 %TYPE;
primary_uom_code mtl_system_items_b.primary_uom_code %TYPE;
x_return_status VARCHAR2(2);
x_msg_count NUMBER := 0;
BEGIN
SELECT inventory_item_id INTO itemid FROM mtl_system_items_b WHERE inventory_item_id=2447106 and organization_id=116;
SELECT segment1
INTO segment1 FROM mtl_system_items_b WHERE inventory_item_id=2447106 and organization_id=116;
SELECT primary_uom_code INTO primary_uom_code FROM mtl_system_items_b WHERE inventory_item_id=2447106 and organization_id=116;
EGO_ITEM_PUB.ASSIGN_ITEM_TO_ORG(
P_API_VERSION => l_api_version
, P_INIT_MSG_LIST => l_INIT_MSG_LIST
, P_COMMIT => l_COMMIT
, P_INVENTORY_ITEM_ID => itemid --(item id from the above Query)
, P_ITEM_NUMBER => segment1 --(Item Code from the above Query)
, P_ORGANIZATION_ID => 117 --(Organization Id for assingment)
, P_ORGANIZATION_CODE => 'D12'--v_organization_code
, P_PRIMARY_UOM_CODE =>primary_uom_code --(UOM from the above Query)
, X_RETURN_STATUS => X_RETURN_STATUS
, X_MSG_COUNT => X_MSG_COUNT
);
DBMS_OUTPUT.PUT_LINE('Status: '||x_return_status);
IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
DBMS_OUTPUT.PUT_LINE('Error Messages :');
Error_Handler.GET_MESSAGE_LIST(x_message_list=> x_message_list);
FOR j IN 1..x_message_list.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(x_message_list(j).message_tex t);
END LOOP;
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Exception Occured :');
DBMS_OUTPUT.PUT_LINE(SQLCODE ||':'||SQLERRM);
END;
END;
After completion, I checked into the database and the items were assigned to the organization i wanted to. However, these items were not appearing in any of the windows when i searched through GUI (Item information window or item search window) under the new organization that i assigned them too.
I tried changing few values that appeared to be abnormal (E.g: last update time was '-1' probably because i used API and not GUI using my user id and password).
Why are not the items appearing in GUI?Is there a step other than executing the above code correctly that I am missing? Please help.

You are not committing the transaction. You declare:
l_commit VARCHAR2(2) := FND_API.G_FALSE;
Which you then pass into the API. If you then query the tables using the same transaction, you will see the modified data. But the application forms are using another session.
You need to add a commit at the end. As to whether to pass in G_TRUE, you need to read the API documentation.

Related

Update with "with data as" clause and regex do not commit. Why?

Sorry for the delay! I've taken a workload greater then i can handle these couple weeks.
Ok, lets clarify things up!
There is a proprietary software running on top of it and
I do not have de ability to change this software! Actually it allows me to do a few things.
In this specific case I can not create a relation 1>N, I can not create a new table! What I do can is create fields.
So, how do i customize things? Through the database! Using triggers, functions and procedures. I know its a bad "work around" but it's what i got and works flawlessly 99% of times. Any exception my code throws the application shows on the screen!
The problem is actually the update not working.
You ask:
Why you're looping when you're forcing there to only be one iteration (unless P_QTDLINHAS can be < 1 I suppose?)
R: Couse the user can select multiple lines in the application but I dont want them to do it. So a throw an error on the screen.
Why you have nested begin/end blocks.
R: Couse I may have to throw exceptions, I got used to write begin Statements Exception some message end.
Sample data:
CREATE TABLE SAMPLE_DATA
(
PKNUMBER NUMBER NOT NULL
, DESCRIPTION VARCHAR2(20)
, GROUPTOCHANGE VARCHAR2(100)
, STATUS VARCHAR2(1 BYTE)
, CONSTRAINT SAMPLE_DATA_PK PRIMARY KEY
(
PKNUMBER
)
ENABLE
);
INSERT INTO sample_data VALUES (1000,'ORDER1',NULL,NULL);
INSERT INTO sample_data VALUES (2000,'ORDER2',NULL,NULL);
INSERT INTO sample_data VALUES (3000,'ORDER3',NULL,NULL);
INSERT INTO sample_data VALUES (4000,'ORDER4','1000,2000,30001',NULL);
In this case the field GROUPTOCHANGE will be filled by the user like this "2108,8090,8843". Each number represents a PKNUMBER in same table "SAMPLE_DATA".
yes i know! the user can type something wrong.. let's ignore this for now!
The field STATUS will eventually be updated to 'C','L','R' OR NULL. When this happens I Need this logic to be executed:
IF OLD.STATUS <> NEW.STATUS AND GROUPTOCHANGE IS NOT NULL THEN
UPDATE SAMPLE_DATA SP
SET SP.STATUS = :NEW.STATUS
WHERE SP.PKNUMBER IN (:NEW.GROUPTOCHAGE)
AND PS.GROUPTOCHANGE IS NULL;
END IF;
Dispite the bad design is it possible to do?
Thank for any help!!
Here what I've done so far:
create or replace PROCEDURE "AD_LIBERA_FRETES_FILHOS"(
P_CODUSU NUMBER,
P_IDSESSAO VARCHAR2,
P_QTDLINHAS NUMBER,
P_MENSAGEM OUT VARCHAR2)
AS
P_NUNOTA NUMBER(10);
P_CONTROLE VARCHAR(100);
P_PEDIDOS VARCHAR(100);
P_STATUS VARCHAR(100);
BEGIN
-- avoid more than 1 at a time
IF (P_QTDLINHAS > 1) THEN
RAISE_APPLICATION_ERROR(-20000, 'SELECIONE APENAS UM PEDIDO PARA EXECUTAR ESTA AÇÃO.');
END IF;
FOR I IN 1..P_QTDLINHAS LOOP
--extract param from session
P_NUNOTA := ACT_INT_FIELD(P_IDSESSAO, I, 'PKNUMBER');
P_STATUS := ACT_TXT_FIELD(P_IDSESSAO, I, 'STATUS');
--verify typed text should be "84090,89830,83393..."
BEGIN
SELECT REGEXP_REPLACE(CAB.GROUPTOCHANGE, '[0-9-, ]', ''),
CAB.GROUPTOCHANGE
INTO P_CONTROLE,
P_PEDIDOS
FROM SAMPLE_DATA CAB
WHERE CAB.PKNUMBER = P_NUNOTA;
END;
IF (P_CONTROLE IS NOT NULL) THEN
RAISE_APPLICATION_ERROR(-20000, '<B> SOMETHING WRONG !</B>');
ELSE
--perform de update (not working)
BEGIN
UPDATE SAMPLE_DATA C
SET C.STATUS = P_STATUS
WHERE
C.GROUPTOCHANGE IS NULL AND
C.PKNUMBER IN
(WITH DATA AS
(SELECT CAB.GROUPTOCHANGE STR
FROM SAMPLE_DATA CAB
WHERE CAB.PKNUMBER = P_NUNOTA )
SELECT TRIM(REGEXP_SUBSTR(STR, '[^,]+', 1, LEVEL)) STR
FROM DATA CONNECT BY INSTR(STR, ',', 1, LEVEL - 1) > 0);
END;
END IF;
END LOOP;
--mgs to show
P_MENSAGEM := 'DONE!! CHECK -> '||P_PEDIDOS;
END;

How to Get datablock default where that oracle forms generate with Enter-query action

I am working with oracle forms 6i.
Simply I am using database block with these items :
Employees: employee_id , job_id , department_id , manager_id
note: employees is the data-block name .
For example: when end user click enter-query button and write 50 in department_id item and then click execute-query button; data block will return all employees who are in department 50.
My question is : How can I get the WHERE CLAUSE that oracle forms generate when returned desired data?...
I used this code in pre-query trigger
:parameters.whr:=get_block_property('employees',default_where);
But it returned no results
You're close, but not close enough. It is the GET_BLOCK_PROPERTY you need, but use its LAST_QUERY parameter. It will return SQL statement of the last query in the specified block.
Alternatively, use system variable :SYSTEM.LAST_QUERY (returns the same result).
Here's an example( the following code might be put in KEY-EXEQRY trigger of employees block ):
declare
l_lastq varchar2(4000);
l_where_position number;
l_where_clause varchar2(4000);
begin
execute_query;
l_lastq := :system.last_query;
l_where_position := instr(lower(l_lastq), 'where');
if l_where_position > 0 then
l_where_clause := substr(l_lastq, l_where_position, length(l_lastq));
message('WHERE clause: ' || l_where_clause);
end if;
end;

Checking if every table object has a different name

I have a Users table, each User has a identifier, a name and some other fields.
I need to check if there is another user with the same name after inserting or updating, so I made this trigger:
CREATE OR REPLACE TRIGGER user_name
BEFORE
INSERT OR UPDATE
ON Users
FOR EACH ROW
DECLARE
count INTEGER;
BEGIN
SELECT COUNT(*) INTO count FROM Users WHERE name = :new.name AND idUser <> :new.idUser;
IF count > 0
THEN raise_application_error(-20007, 'There is already another user with the same name');
END IF;
END;
It seems to work when inserting new users, but it doesn't when I update them, it looks like it "ignores" the idUser check so it always fails as it finds the same user with the same name.
Why is this happening? Thank you
In triggers , there are 3 states as you know inserts update and delete , In update states there are new values and old values , I mean when you update a column you , you will replace the old value with new one , in trigger you can use the old and the new value of the column .. Please check this example
CREATE or REPLACE TRIGGER test001
AFTER INSERT OR UPDATE OR DELETE ON tabletest001
DECLARE
Operation NUMBER;
CustomerCode CHAR(10 BYTE);
BEGIN
IF INSERTING THEN
Operation := 1;
CustomerCode := :new.field1;
END IF;
IF UPDATING THEN
Operation := 2;
CustomerCode := :old.field1;
END IF;
// DO SOMETHING ...
EXCEPTION
WHEN OTHERS THEN ErrorCode := SQLCODE;
END;
/
in the above example , in update state I used old.value of the column , so in your example you should check the old value not new , please try it
if updating then
SELECT COUNT(*) INTO count FROM Users WHERE name = :old.name AND idUser <> :old.idUser;
IF count > 0
THEN raise_application_error(-20007, 'There is already another user with the same name');
end if
however as in the comments adviced you is to use primary key, however my answer is to give you understanding to triggers

Using detail to delivery API's

I created this procedure
CREATE OR REPLACE PROCEDURE APPS.test_dlv3
IS
BEGIN
DECLARE
-- STANDARD PARAMETERS.
pApiVersion NUMBER := 1.0;
pInitMsgList VARCHAR2(30);
pCommit VARCHAR2(30);
-- PARAMETERS FOR WSH_DELIVERY_DETAILS_PUB.DETAIL_TO_DELIVERY
pDeliveryId NUMBER;
pDeliveryName VARCHAR2(30);
pTabOfDelDet WSH_DELIVERY_DETAILS_PUB.id_tab_type;
pAction VARCHAR2(30);
-- OUT PARAMETERS
xReturnStatus VARCHAR2(10);
xMsgCount NUMBER;
xMsgData VARCHAR2(2000);
xMsgDetails VARCHAR2(3000);
xMsgSummary VARCHAR2(3000);
-- HANDLE EXCEPTIONS
vFailApiException EXCEPTION;
BEGIN
-- INITIALIZE RETURN STATUS
xReturnStatus := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
-- CALL THIS PROCEDURE TO INITIALIZE APPLICATIONS PARAMETERS.
FND_GLOBAL.APPS_INITIALIZE(
user_id => , --hide
resp_id => , --hide
resp_appl_id => ); --hide
-- VALUES FOR WSH_DELIVERY_DETAILS_PUB.DETAIL_TO_DELIVERY
pDeliveryId := 379358;
pDeliveryName := 'Delivery01';
pTabOfDelDet(1) := 354601 ;
pAction := 'ASSIGN';
-- CALL TO WSH_DELIVERY_DETAILS_PUB.DETAIL_TO_DELIVERY.
WSH_DELIVERY_DETAILS_PUB.detail_to_delivery(
p_api_version => pApiVersion,
p_init_msg_list => pInitMsgList,
p_commit => pCommit,
x_return_status => xReturnStatus,
x_msg_count => xMsgCount,
x_msg_data => xMsgData,
p_TabOfDelDets => pTabOfDelDet,
p_action => pAction,
p_delivery_id => pDeliveryId,
p_delivery_name => pDeliveryName );
IF (xReturnStatus <> WSH_UTIL_CORE.G_RET_STS_SUCCESS) THEN RAISE vFailApiException;
ELSE DBMS_OUTPUT.PUT_LINE('Detail '||pTabOfDelDet(1)|| ' assignment to the delivery '|| pDeliveryName ||' is successful');
END IF;
Exception
WHEN vFailApiException THEN WSH_UTIL_CORE.get_messages('Y', xMsgSummary, xMsgDetails, xMsgCount);
IF xMsgCount > 1 THEN xMsgData := xMsgSummary || xMsgDetails;
DBMS_OUTPUT.PUT_LINE('Message Data : '||xMsgData);
ELSE xMsgData := xMsgSummary;
DBMS_OUTPUT.PUT_LINE('Message Data : '||xMsgData);
END IF;
END;
END;
/
But the result is always like this :
Message Data : Error: Error in assigning one or more details to a delivery.
Warning: These entities can not be grouped together as their grouping attributes do not match.
Can anyone help me??
Each inventory organization that you ship from has Shipping Parameters defined in the Order Management/Shipping Execution setups.
One area of that form is "Delivery Grouping Attributes". Some attributes are mandatory -- ship from and ship to. Think about it -- if two order lines are being shipped from two different locations, they're not part of the same delivery (they can be part of the same trip, but that is a separate though related concept in Oracle Shipping Execution).
Anyway, if the organization you are shipping from has Shipping Parameters set up that specify a given attribute is part of the Delivery Grouping Attributes, then every delivery detail (~order line, sort of, but not always) you add to the delivery must match that attribute for the delivery.
For example, if "Ship Method" is a delivery grouping attribute and you try to add an order line shipped "Next Day Air" to a "LTL Truck" delivery, you'll get the error you are encountering.
Check the Shipping Parameters for the organizations from which you are shipping and then check the value of each Delivery Grouping Attribute to make sure they match between the delivery and the delivery detail you are attempting to assign to the delivery.

Oracle Forms list does not display values

I want to make list which will display values, like text item but in list.
My code:
DECLARE
rg_dept RecordGroup;
rg_dname VARCHAR2(4) := 'Name';
dlist_ID Item := Find_Item('PROJESCT.LIST_ID');
nDummy NUMBER;
BEGIN
rg_dept := Find_Group(rg_dname);
-- Delete any existing Group first
IF NOT Id_Null(rg_dept) THEN
Delete_Group(rg_dept);
END IF;
-- Now create a Record Group using a SQL query
-- Your Query must have a Label and a Value (two Columns)
-- and the data types must match your item type
rg_dept := Create_Group_From_Query(rg_dname,'SELECT department_name, to_char(department_id) FROM departments');
--Clear the existing List
Clear_List(dlist_ID);
-- Populate the Record Group
nDummy := Populate_Group(rg_dept);
-- Populate the List Item
Populate_List(dlist_ID ,rg_dept);
END;
If I make list item and add this code, form will display nothing; if I remove list, all is ok.
P.S. Trigger: when-list-item-change
I should recommend you to populate your lists from e.g. When-new-Form-Instance. As usual you will get a good idea what you need to do from Forms help (menu 'Help/Online Help'). This is a procedure I have made to simple populate list only by specifying the name of the list item and the select statement to populate the lsit item with.
PROCEDURE populate_list_item (
p_item_name VARCHAR2
, p_select VARCHAR2
) IS
l_rg_id RECORDGROUP;
l_list_id ITEM;
l_err_num PLS_INTEGER;
FUNCTION create_temp_group (
p_select VARCHAR2
) RETURN RECORDGROUP IS
l_rg_id RECORDGROUP;
l_group_name VARCHAR2(30) := 'TMP$RG';
BEGIN
l_rg_id := FIND_GROUP(l_group_name);
--Make sure that record group don't alreay exist
IF NOT ID_NULL(l_rg_id) THEN
DELETE_GROUP(l_rg_id);
END IF;
--Populate the temporary record group
l_rg_id := CREATE_GROUP_FROM_QUERY(l_group_name, p_select);
RETURN l_rg_id;
END create_temp_group;
BEGIN
l_rg_id := create_temp_group(p_select);
l_err_num := Populate_Group(l_rg_id);
--Allow for no data found in the selection query
IF l_err_num NOT IN (0, 1403) THEN
RAISE Form_Trigger_Failure;
END IF;
l_list_id := Find_Item(p_item_name);
IF ID_NULL(l_list_id) THEN
RAISE Form_Trigger_Failure;
END IF;
Populate_List(l_list_id, l_rg_id);
Delete_Group(l_rg_id);
END populate_list_item;
The When-New-Form-Instance is a form level trigger and should be under the form (instead of block or item):
The best thing to do is to build all your record groups at design time. It does not slow down the performance unless you have some huge, already slow form. Then populate your list items at run time. Always Copy/paste the code from Forms help.
--Oracle Forms Example: Create a record group from a query, and populate it.
DECLARE
rg_name VARCHAR2(40) := 'Salary_Range';
rg_id RecordGroup;
errcode NUMBER;
BEGIN
/*
** Make sure group doesn't already exist
*/
rg_id := Find_Group( rg_name );
/*
** If it does not exist, create it and add the two
** necessary columns to it.
*/
IF Id_Null(rg_id) THEN
rg_id := Create_Group_From_Query( rg_name,
'SELECT SAL-MOD(SAL,1000) BASE_SAL_RANGE,'
||'COUNT(EMPNO) EMPS_IN_RANGE '
||'FROM EMP '
||'GROUP BY SAL-MOD(SAL,1000) '
||'ORDER BY 1');
END IF;
/*
** Populate the record group
*/
errcode := Populate_Group( rg_id );
END;

Resources