Monday, February 9, 2015

GL Journal WebADI Import - Custom Validations

Dear Readers

Many of you may be aware that Oracle provide a means to load GL journal entries from WebADI sheet via a seeded functionality

This process has several seeded validations on Source, Category, Period etc. But now, let us suppose that you wanted to add some custom validation in there to prevent loading certain records if the custom logic is not met

Let us just say for the case of this example, that we want to prevent user from loading records with DR amount as 100 ... sounds funny but this can be modified as per your requirement I am just taking this as an example

For this, there is a seeded package gl_import_hook_pkg which provides means to add custom logic

In this package in the FUNCTION pre_module_hook add the code as below

  FUNCTION pre_module_hook(sob_id    IN     NUMBER,
         run_id    IN     NUMBER,
         errbuf    IN OUT NOCOPY VARCHAR2) RETURN BOOLEAN IS
  BEGIN
    -- AX section
    IF ax_setup_pkg.ax_installed THEN
      IF NOT ax_ezl_filter_pkg.EZLFilter(sob_id, run_id, errbuf) THEN
        RETURN FALSE;
      END IF;
    END IF;

    -- Please put your function call here.  Make it the following format:
    --    IF (NOT dummy(sob_id, run_id, errbuf)) THEN
    --      RETURN(FALSE);
    --    END IF;

        IF (NOT anand_test_hook_prc(sob_id, run_id, errbuf)) THEN
          RETURN(FALSE);
        END IF;

    RETURN(TRUE);
  END pre_module_hook;


The code for my custom function is as below

CREATE OR REPLACE FUNCTION anand_test_hook_prc
(
sob_id NUMBER, run_id NUMBER, errbuf IN OUT NOCOPY VARCHAR2
)
RETURN BOOLEAN
AS
   lv_count NUMBER;
   lv_group_id NUMBER;
   lv_je_source VARCHAR2(240);
BEGIN
   INSERT INTO anand_test_hook_dbg VALUES('inside hook process run id value is ' || run_id);
   SELECT   COUNT(*)
   INTO     lv_count
   FROM     gl_interface_control
   WHERE    interface_run_id = run_id;
   INSERT INTO anand_test_hook_dbg VALUES('count in control is ' || lv_count);

   IF lv_count = 1 THEN
      SELECT   group_id, je_source_name
      INTO     lv_group_id, lv_je_source
      FROM     gl_interface_control
      WHERE    interface_run_id = run_id;

      IF lv_je_source = 'Spreadsheet' THEN
         SELECT   COUNT(1)
         INTO     lv_count
         FROM     gl_interface
         WHERE    group_id = lv_group_id
         AND      entered_dr = 100;

         INSERT INTO anand_test_hook_dbg VALUES('count in iface is ' || lv_count);

         IF lv_count <> 0 THEN
            fnd_file.put_line(fnd_file.log, ' *** CUSTOM VALIDATION FAILED *** --> There are records in this batch which have 100 as debit amount');
            fnd_file.put_line(fnd_file.output, ' *** CUSTOM VALIDATION FAILED *** --> There are records in this batch which have 100 as debit amount');
            RETURN FALSE;
         END IF;
      END IF;
   END IF;

   RETURN TRUE;

END anand_test_hook_prc;

When you now try to load GL JV with DR = 100, the custom validation will fail and prevent importing of such records :-)

Hope this helps

Cheers
A

Generation of Org-Chart from Oracle HRMS

Dear Readers

Just wanted to share a useful information (maybe it can be used somewhere else in future) of how we can generate an org-chart from Oracle HR data using Google API’s

Step-1: Using the data in PER_ALL_PEOPLE_F and PER_ALL_ASSIGNMENTS_F, generate a list of employees with their supervisor name as per below.
select
ppf.full_name empl_name,
ppfm.full_name mgr_name
from per_all_people_f ppf, per_all_people_f ppfm, per_all_assignments_f paf
where sysdate between ppf.effective_start_date and ppf.effective_end_date
and sysdate between ppfm.effective_start_date and ppfm.effective_end_date
and ppf.person_id = paf.person_id
and sysdate between paf.effective_start_date and paf.effective_end_date
and paf.supervisor_id = ppfm.person_id (+)
and ppfm.full_name like 'Stock%'
order by 2 desc

Step-2: Use the below PLSQL block to write out a HTML file in a directory
DECLARE
   v_file utl_file.file_type;
BEGIN
   v_file := utl_file.fopen('/usr/tmp', 'Sample.htm', 'W');
   utl_file.put_line(v_file, '<html>');
   utl_file.put_line(v_file, '  <head>');
   utl_file.put_line(v_file, '    <script type="text/javascript" src="https://www.google.com/jsapi"></script>');
   utl_file.put_line(v_file, '    <script type="text/javascript">');
   utl_file.put_line(v_file, '      google.load("visualization", "1", {packages:["orgchart"]});');
   utl_file.put_line(v_file, '      google.setOnLoadCallback(drawChart);');
   utl_file.put_line(v_file, '      function drawChart() {');
   utl_file.put_line(v_file, '        var data = new google.visualization.DataTable();');
   utl_file.put_line(v_file, '        data.addColumn(''string'', ''Name'');');
   utl_file.put_line(v_file, '        data.addColumn(''string'', ''Manager'');');
   utl_file.put_line(v_file, '        data.addColumn(''string'', ''ToolTip'');');
   utl_file.put_line(v_file, '        data.addRows([');

   FOR i IN
   (
      select
      ppf.full_name empl_name,
      ppfm.full_name mgr_name
      from per_all_people_f ppf, per_all_people_f ppfm, per_all_assignments_f paf
      where sysdate between ppf.effective_start_date and ppf.effective_end_date
      and sysdate between ppfm.effective_start_date and ppfm.effective_end_date
      and ppf.person_id = paf.person_id
      and sysdate between paf.effective_start_date and paf.effective_end_date
      and paf.supervisor_id = ppfm.person_id (+)
      and ppfm.full_name like 'Stock%'
      order by 2 desc
   ) loop
      utl_file.put_line(v_file, '[''' || i.empl_name || ''', ''' || i.mgr_name || ''', ''''],');
   END LOOP;

   utl_file.put_line(v_file, ']);');
   utl_file.put_line(v_file, '        var chart = new google.visualization.OrgChart(document.getElementById(''chart_div''));');
   utl_file.put_line(v_file, '        chart.draw(data, {allowHtml:true,allowCollapse:true,color:''#ffffff'',selectionColor:''#cc3636''});');
   utl_file.put_line(v_file, '      }');
   utl_file.put_line(v_file, '   </script>');
   utl_file.put_line(v_file, '    </head>');
   utl_file.put_line(v_file, '  <body>');
   utl_file.put_line(v_file, '    <div id="chart_div"></div>');
   utl_file.put_line(v_file, '  </body>');
   utl_file.put_line(v_file, '</html>');
   utl_file.fclose(v_file);
END;

Step-3: Voila!!! The HTML file (when opened in Chrome/Firefox etc.) chart as below



Hope this helps you sometime

Cheers
A

Wednesday, November 5, 2014

Item Cost with Material and Material Overhead Elements - Data Conversion

Dear Reader

In this post, we will see how we can convert the data for item costs (with the material and Material overhead elements)

Below is a sample script of the data which needs to be inserted into the interface tables

INSERT INTO cst_item_costs_interface
(
   inventory_item_id,
   organization_id,
   cost_type_id,
   inventory_asset_flag,
   item_cost,
   process_flag,
   transaction_type
)
values
(
   :inventory_item_id,
   :organization_id,
   :cost_type_id, --derive Pending cost type ID from cst_cost_types table
   1,
   :material_cost,
   1,
   'CREATE'
);

INSERT INTO cst_item_cst_dtls_interface
(
   inventory_item_id,
   organization_id,
   cost_type_id,
   level_type,
   operation_seq_num,
   item_cost,
   usage_rate_or_amount,
   cost_element_id,
   process_flag,
   transaction_type
)
values
(
   :inventory_item_id,
   :organization_id,
   :cost_type_id, --derive Pending cost type ID from cst_cost_types table
   1,
   1,
   :material_cost,
   :material_cost,
   1, --element ID = 1 for Material element of the cost
   1,
   'CREATE'
);

INSERT INTO cst_item_cst_dtls_interface
(
   inventory_item_id,
   organization_id,
   cost_type_id,
   level_type,
   operation_seq_num,
   resource_id,
   item_cost,
   usage_rate_or_amount,
   cost_element_id,
   process_flag,
   transaction_type
)
values
(
   :inventory_item_id,
   :organization_id,
   :cost_type_id, --derive Pending cost type ID from cst_cost_types table
   1,
   1,
   :resource_id,  --Overhead cost is always associated with a resource. Derive this from BOM_RESOURCES_V (maybe Freight or any custom resource you have)
   :material_ovhd_cost,
   :material_ovhd_cost,
   2, --element ID = 2 for Material Overhead element of the cost
   1,
   'CREATE'
);


Once the data is inserted into the table, launch the concurrent program "CSTPCIMP" to import this data into base tables

Once done, the data should appear in cst_item_costs and cst_item_cost_details table

Cheers
A