Topic: Oracle Home

Process Flow – P2P 0

Oracle ERP has two important process flows that define day to day activities across multiple modules.

  • Procure to Pay (P2P)
  • Order to Cash (OTC)

Procure to Pay Process commonly known as P2P is the process of procuring items based on necessity, paying for the goods or services procured and accounting the monetary transactions that take place during the above mentioned process. More about P2P Process can be found here.

Order to Cash Process commonly known as OTC is the process of selling the goods or services, shipping the aforementioned goods and accounting of the monetary transactions that take place during the above mentioned process. More about OTC process can be found here.

Query to retrieve Concurrent Program Details 0

The following query can be used to retrieve different details related to a Concurrent Program like Name, short name, executable details, parameters and valueset details.

Note: For this query – took the example of the seeded AR program – ‘Autoinvoice Master Program’.

SELECT fcpl.user_concurrent_program_name "Concurrent Program Name",
       fcp.concurrent_program_name       "Short Name",
       fa.application_short_name         "Module",
       fe.executable_name                "Executable",
       fe.execution_file_name            "Executable Short Name",
       DECODE (fcp.execution_method_code,
               'X', 'FlexRpt',
               'F', 'FlexSql',
               'H', 'Host',
               'S', 'Immediate',
               'K', 'Java Concurrent Program',
               'J', 'Java Stored Procedure',
               'M', 'Multi Language Function',
               'P', 'Oracle Reports',
               'I', 'PL/SQL Stored Procedure',
               'E', 'Perl Concurrent Program',
               'B', 'Request Set Stage Function',
               'L', 'SQL*Loader',
               'Q', 'SQL*Plus',
               'R', 'SQL*Report',
               'Z', 'Shutdown Callback',
               'A', 'Spawned')           "Execution Method",
       fcpl.description                  "Program Description",
       fdfcuv.column_seq_num             "Column Seq Number",
       fdfcuv.end_user_column_name       "Parameter Name",
       fdfcuv.form_left_prompt           "Prompt",
       fdfcuv.enabled_flag               " Enabled Flag",
       fdfcuv.required_flag              "Required Flag",
       fdfcuv.display_flag               "Display Flag",
       ffvs.flex_value_set_name          "Value Set Name"
  FROM fnd_executables              fe,
       fnd_concurrent_programs_tl   fcpl,
       fnd_application              fa,
       fnd_concurrent_programs      fcp,
       fnd_descr_flex_col_usage_vl  fdfcuv,
       fnd_flex_value_sets          ffvs,
       fnd_lookup_values            flv
 WHERE     1 = 1
       AND fe.executable_id = fcp.executable_id
       AND fcpl.application_id = fa.application_id
       AND fcpl.concurrent_program_id = fcp.concurrent_program_id
       AND user_concurrent_program_name = 'Autoinvoice Master Program'  -- change Concurrent program name here.. 
       AND fdfcuv.descriptive_flexfield_name =
           '$SRS$.' || fcp.concurrent_program_name
       AND ffvs.flex_value_set_id = fdfcuv.flex_value_set_id
       AND flv.lookup_type(+) = 'FLEX_DEFAULT_TYPE'
       AND flv.lookup_code(+) = fdfcuv.default_type
       AND fcpl.LANGUAGE = 'US'
       AND flv.LANGUAGE(+) = USERENV ('LANG')
       ORDER BY fdfcuv.column_seq_num;

 

MONTHS_BETWEEN 0

The MONTHS_BETWEEN function returns an numeric value of the number of months between the two input dates of the function.

Format: MONTHS_BETWEEN (datetime_expression1, datetime_expression2)

Example1:

SELECT MONTHS_BETWEEN ('10-OCT-2022', '10-OCT-2018') FROM DUAL;

Result: 48 (gives that there are 48 months in between the two dates).

Example2:

SELECT MONTHS_BETWEEN ('10-OCT-2018', '10-OCT-2022') FROM DUAL;

Result: -48 (the first date is a lower (earlier) date than the second date).

Example3:

select months_between (SYSDATE+1000,SYSDATE) FROM DUAL;

Result: 32.8709677419355 (a non-integer result).

 

 

NEXT_DAY 0

NEXT_DAY function returns the date of the first instance of the particular day of the week after the specified date.

Format: NEXT_DAY (input_date, day_of_the_week);

Note: For the examples below – the SYSDATE is: 10/30/2018 2:08:06 PM

Example1:

select NEXT_DAY (SYSDATE, 'WEDNESDAY') FROM DUAL;

Result: 10/31/2018 2:08:06 PM

Example2: (takes lower case of the day)

select NEXT_DAY (SYSDATE, 'monday') FROM DUAL;

Result: 11/5/2018 2:08:06 PM

Example3: (the function allows a little typo in the name of the day).

select NEXT_DAY (SYSDATE, 'monnnnnnday') FROM DUAL;

Result: 11/5/2018 2:08:06 PM

Example4: (if the day is not a day of the week at all – then it throws an error).

SELECT NEXT_DAY (SYSDATE, 'testday') FROM DUAL;

Result: Error.

 

 

 

LAST_DAY 0

LAST_DAY function returns the last day of the month in which the input date falls in.

The syntax of this function is: LAST_DAY(datetime-expression).

Example:

The Sysdate in this example is: 10/29/2018 8:24:07 PM

SELECT LAST_DAY (SYSDATE) FROM DUAL;

Result: 10/31/2018 8:24:07 PM

Example 2:

The Sysdate in this example is: 10/29/2018 8:24:46 PM

SELECT LAST_DAY (SYSDATE-300) FROM DUAL;

Result: 1/31/2018 8:24:46 PM

ADD_MONTHS 0

Add_months function returns a DATETIME value – that adds ‘n‘ number of months from the input date provided.

The syntax of ADD_MONTHS function is:  ADD_MONTHS (input_date, n) where:

  • input_Date – is the date from which the function is to be applied on.
  • n – n is the integer value of number of months to add from the input date
SELECT ADD_MONTHS (SYSDATE, 10) FROM DUAL;

(Sysdate is: 10/29/2018 7:52:53 PM)

Logic: Adds 10 months to the sysdate

Result: 8/29/2019 7:52:53 PM

SELECT ADD_MONTHS (SYSDATE, -10) FROM DUAL;

(Sysdate is: 10/29/2018 7:53:46 PM)

Logic: Adds 10 months to the sysdate

Result: 12/29/2017  7:53:46 PM

Create Customer using create_cust_account API 0

The following script helps to create a Customer with basic information (mandatory information) in Oracle Applications TCA Architecture.

DECLARE
    l_cust_account_rec       hz_cust_account_v2pub.cust_account_rec_type;
    l_org_rec                hz_party_v2pub.organization_rec_type;
    l_customer_profile_rec   hz_customer_profile_v2pub.customer_profile_rec_type;
    l_account_name           hz_cust_accounts.account_name%TYPE;

    l_msg_count              NUMBER;
    l_msg_data               VARCHAR2 (4000);
    l_err_msg                VARCHAR2 (4000);
    l_return_status          VARCHAR2 (1);
    l_cust_account_id        NUMBER;
    l_account_number         hz_cust_accounts.account_number%TYPE;
    l_party_id               hz_cust_accounts.party_id%TYPE;
    l_party_number           hz_parties.party_id%TYPE;
    l_cust_acct_profile_id   hz_customer_profiles.cust_account_profile_id%TYPE;
BEGIN
    l_cust_account_rec.account_name := 'Test Customer 98765432';
    l_cust_account_rec.account_number := '98765432';
    l_cust_account_rec.customer_type := 'R';
    l_cust_account_rec.attribute1 := SYSDATE;
    l_cust_account_rec.created_by_module := 'HZ_CPUI';
    l_org_rec.organization_name := 'Test Customer 98765432';

    hz_cust_account_v2pub.create_cust_account (
        p_init_msg_list          => fnd_api.g_true,
        p_cust_account_rec       => l_cust_account_rec,
        p_organization_rec       => l_org_rec,
        p_customer_profile_rec   => l_customer_profile_rec,
        p_create_profile_amt     => fnd_api.g_true,
        x_return_status          => l_return_status,
        x_msg_count              => l_msg_count,
        x_msg_data               => l_msg_data,
        x_cust_account_id        => l_cust_account_id,
        x_account_number         => l_account_number,
        x_party_id               => l_party_id,
        x_party_number           => l_party_number,
        x_profile_id             => l_cust_acct_profile_id);

    DBMS_OUTPUT.put_line ('API Return status is: ' || l_return_status);
    
    IF l_return_status <> 'S'
    THEN 
        DBMS_OUTPUT.put_line ('Error message is: ' || SUBSTR (l_msg_data, 200));
    END IF; 
    
    IF l_return_status = 'S'
    THEN
        BEGIN
            SELECT account_name
              INTO l_account_name
              FROM hz_cust_accounts
             WHERE account_number = '98769876';

            DBMS_OUTPUT.put_line (
                   'Customer Account created with Account number: '
                || l_account_number
                || ' and Cust Account ID: '
                || l_cust_account_id
                || ' and Account Name: '
                || l_account_name);
        EXCEPTION
            WHEN OTHERS
            THEN
                DBMS_OUTPUT.put_line (
                    'Error during deriving Account Name: ' || SQLERRM);
        END;
    END IF;
EXCEPTION
    WHEN OTHERS
    THEN
        DBMS_OUTPUT.put_line ('Error during creating account: ' || SQLERRM);
END;

The DMBS Output is shown as below:

Upon running the script above, a Customer is created. The customer can be found in Hz_Cust_accounts table.

Below is the query to check the customer and some important columns in the Hz_Cust_Accounts table.

SELECT cust_account_id,
       party_id,
       account_number,
       status,
       customer_type,
       account_name,
       created_by_module,
       h.*
  FROM hz_cust_accounts h
 WHERE account_number = '98765432';

 

 

Customer, Party, Party Sites, Customer Sites, Site Uses 0

In this post, we shall look at the details of Creating a Customer and the tables affecting it.

Navigation: AR Superuser -> Customers -> Customers

In the OAF page that opened, fill out the following details:

Organization Name, Account Number, Profile Class: Default (Oracle provides this profile class) and Account Site Address: Give a correct address that exists as per HZ_GEOGRAPHIES hierarchy.

Upon creating the account, a record now exists in the Hz_Cust_Accounts table

In the example below – created a Customer with Account number – 10820181

HZ_CUST_ACCOUNTS

SELECT *
  FROM hz_cust_accounts
 WHERE account_number = '10820181';

As can be seen a Party is also created with a party Id – 51284811

HZ_PARTIES

SELECT PARTY_ID, PARTY_NUMBER, PARTY_NAME, PARTY_TYPE, STATUS, JGZZ_FISCAL_CODE, H.* 
  FROM hz_parties H
 WHERE party_id = 51284811;
--- JGZZ_FISCAL_CODE holds the tax payer id.

HZ_PARTY_SITES

 SELECT PARTY_SITE_ID, PARTY_ID, LOCATION_ID, PARTY_SITE_NUMBER, STATUS, CREATED_BY_MODULE, H.*
  FROM HZ_PARTY_SITES H
 WHERE PARTY_ID = 51284811;

HZ_LOCATIONS

Get the location_id from the Hz_Party_Sites

SELECT location_id,
       ORIG_SYSTEM_REFERENCE,
       country,
       address1,
       address2,
       city,
       state,
       county,
       postal_code,
       h.*
  FROM hz_locations h
 WHERE location_id = 38779066;

HZ_CUST_ACCT_SITES_ALL

Hz_Cust_Acct_Sites_all table details about the customer account sites across all the operating units. A Customer site has addresses where the customer intends to do business at. A Customer can have more than one site and across more than one operating unit. The site signifies whether the site is a Primary Bill_To or a Primary Ship_To site. Join between the Customer table and Customer site table is the Cust_acct_id.

A Bill_To_Flag indicates if it is a bill to site.

  • Y for a Bill-To site
  • P for the primary Bill-To site
  • N for a site that is not a Bill-To site.

A Ship_to_Flag indicates if it is a Ship to site.

  • Y for a Ship-To site
  • P for the primary Ship-To site
  • N for a site that is not a Ship-To site
SELECT cust_acct_site_id,
       cust_account_id,
       party_site_id,
       status,
       bill_to_flag,
       h.*
  FROM hz_cust_acct_sites_all h
 WHERE cust_account_id = 46149842;

HZ_CUST_SITE_USES_ALL

The HZ_CUST_SITE_USES_ALL table stores business purposes assigned to customer account sites, for example Bill-To, Ship-To, and
Statements. Each customer account site can have one or more purposes. This table is a child of the HZ_CUST_ACCT_SITES_ALL table, with the foreign key CUST_ACCT_SITE_ID. The HZ_CUST_SITE_USES_ALL table also stores operating unit identifier, though the HZ_CUST_ACCT_SITES_ALL table itself stores the operating unit for customer account sites.

SELECT site_use_id,
       cust_acct_site_id,
       site_use_code,
       primary_flag     status,
       location,
       h.*
  FROM HZ_CUST_SITE_USES_ALL h
 WHERE cust_acct_site_id = 49348980;

 

Cursors – Explicit Cursors 0

What are Cursors? 

A cursor is a pointer to a private SQL area that stores information about the processing of a SELECT statement or a DML statement (Insert, Update or Delete). In layman terms, a Cursor is used to fetch (SELECT) a particular dataset from a much larger dataset which can then be used for data manipulation using other DML Operations like Insert, Update or Delete.

There are two types of Cursors: Implicit Cursors and Explicit Cursors.

In this post, we will discuss mainly about Explicit Cursors.

Explicit Cursors: Unlike Implicit cursors, application developers have control over the life cycle of the explicit cursors by manually performing the OPEN and FETCH operations and then CLOSE the Cursor.

A Cursor is defined in the declarative part of the PL/SQL Block and the following are three stages are part of the Cursor life cycle.

  • OPEN
    •  Open: Database allocates a private work area in the user’s session memory for cursor processing.
    •  Parse SQL: Validates the SQL query for syntax and privileges.
    •  Bind SQL: Provides an input value to the bind variables that are part of the query.
    •  Executes the SQL Statement (that has the required conditions in the WHERE condition).
  • FETCH
    • Fetches the data from the parsed SQL statement. Fetches the data into a block variable and increments the record pointer.
  • CLOSE
    • Closes the cursor and releases the memory back to System Global Area (SGA).

Consider the following dataset to demonstrate an example of an Explicit cursor. Create a sample table and insert data into the table.

CREATE TABLE xx_test_cursor
(
    emp_name         VARCHAR2 (200),
    emp_id           NUMBER,
    emp_join_date    DATE,
    manager_name     VARCHAR2 (200)
);

INSERT INTO xx_test_cursor
     VALUES ('John',1001,SYSDATE - 30, 'Frank');

INSERT INTO xx_test_cursor
     VALUES ('Graeme', 1002, SYSDATE - 40, 'Frank');

INSERT INTO xx_test_cursor
     VALUES ('Shawn', 1003, SYSDATE - 50, 'Frank');

INSERT INTO xx_test_cursor
     VALUES ('Jonty', 1004, SYSDATE - 60, 'Frank');

INSERT INTO xx_test_cursor
     VALUES ('Mike', 1007, SYSDATE - 60, 'Frank');
     
INSERT INTO xx_test_cursor
     VALUES ('Peter', 1008, SYSDATE - 60, 'Justin');

INSERT INTO xx_test_cursor
     VALUES ('Jason', 1009, SYSDATE - 60, 'Justin');

INSERT INTO xx_test_cursor
     VALUES ('Glenn', 1010, SYSDATE - 60, 'Justin');

INSERT INTO xx_test_cursor
     VALUES ('Adam', 1011, SYSDATE - 60, 'Justin');
     
INSERT INTO xx_test_cursor
     VALUES ('Chris', 1012, SYSDATE - 60, 'Justin');

COMMIT;
SELECT * FROM xx_test_cursor
order by emp_id;

EMP_NAME	EMP_ID	EMP_JOIN_DATE	        MANAGER_NAME
John	         1,001	08/27/2018 19:01:10	Frank
Graeme	         1,002	08/17/2018 19:01:11	Frank
Shawn	         1,003	08/07/2018 19:01:12	Frank
Jonty	         1,004	07/28/2018 19:01:13	Frank
DARELL	         1,005	07/28/2018 19:23:58	Frank
Mike	         1,007	07/31/2018 01:50:23	Justin
Peter	         1,008	07/31/2018 01:50:24	Justin
Jason	         1,009	07/31/2018 01:50:26	Justin
Glenn	         1,010	07/31/2018 01:50:27	Justin
Adam	         1,011	07/31/2018 01:50:28	Justin

The following code will display the data from the table in the required format.

Cursor – FETCH

  • Code from Line Number 2 to 5 is where the code is being defined in the declare section.
  • Code in line number 13 opens the cursor.
  • Code in line number 14 fetches the data from the SQL cursor into a record variable that has a cursor type datatype.
  • Once all the data is fetched, code in line number 15 closes the Cursor.
  • Code from Line 17 to 29, checks if there is any data in the record variable, then loops through the record using an index, and displays the data in the required format, and then closes the loop.
DECLARE
    CURSOR c_data 
    IS
        SELECT emp_name, emp_join_date, manager_name 
        FROM xx_test_cursor;

    TYPE rec_data_type IS TABLE OF c_data%ROWTYPE
         INDEX BY BINARY_INTEGER;
         
    l_data rec_data_type;
    
BEGIN
    OPEN c_data;
    FETCH c_data BULK COLLECT INTO l_data;
    CLOSE c_data;

    IF l_data.COUNT > 0
    THEN
        FOR i IN l_data.FIRST .. l_data.LAST
        LOOP
            DBMS_OUTPUT.put_line (
                   'Employee: '
                || l_data (i).emp_name
                || ' Join date is: '
                || l_data (i).emp_join_date
                || ' and Manager is: '
                || l_data (i).manager_name);
        END LOOP;
    END IF;
EXCEPTION
    WHEN OTHERS
    THEN
        DBMS_OUTPUT.put_line ('Exception when processing data: ' || SQLERRM);
END;
Corresponding Dbms_output is: 

Employee: Mike Join date is: 31-JUL-18 and Manager is: Justin
Employee: Peter Join date is: 31-JUL-18 and Manager is: Justin
Employee: Jason Join date is: 31-JUL-18 and Manager is: Justin
Employee: Glenn Join date is: 31-JUL-18 and Manager is: Justin
Employee: Adam Join date is: 31-JUL-18 and Manager is: Justin
Employee: John Join date is: 27-AUG-18 and Manager is: Frank
Employee: Graeme Join date is: 17-AUG-18 and Manager is: Frank
Employee: Shawn Join date is: 07-AUG-18 and Manager is: Frank
Employee: Jonty Join date is: 28-JUL-18 and Manager is: Frank
Employee: DARELL Join date is: 28-JUL-18 and Manager is: Frank

FOR LOOP: 

DECLARE
    CURSOR c_data 
    IS 
    SELECT emp_name, emp_join_date, manager_name
    FROM xx_test_cursor;
BEGIN
    FOR rec_data IN c_data
    LOOP
        DBMS_OUTPUT.put_line (
               'Employee: '
            || rec_data.emp_name
            || ' Join date is: '
            || rec_data.emp_join_date
            || ' and Manager is: '
            || rec_data.manager_name);
    END LOOP;
EXCEPTION
    WHEN OTHERS
    THEN
        DBMS_OUTPUT.put_line ('Exception when processing data: ' || SQLERRM);
END;
Corresponding dbms_output is: 

Employee: Mike Join date is: 31-JUL-18 and Manager is: Justin
Employee: Peter Join date is: 31-JUL-18 and Manager is: Justin
Employee: Jason Join date is: 31-JUL-18 and Manager is: Justin
Employee: Glenn Join date is: 31-JUL-18 and Manager is: Justin
Employee: Adam Join date is: 31-JUL-18 and Manager is: Justin
Employee: John Join date is: 27-AUG-18 and Manager is: Frank
Employee: Graeme Join date is: 17-AUG-18 and Manager is: Frank
Employee: Shawn Join date is: 07-AUG-18 and Manager is: Frank
Employee: Jonty Join date is: 28-JUL-18 and Manager is: Frank
Employee: DARELL Join date is: 28-JUL-18 and Manager is: Frank