This chapter describes using Oracle Configurator in a programmatic mode.
This chapter covers the following topics:
This chapter describes using the runtime Oracle Configurator in programmatic mode, without direct end user interaction, which is called batch validation. This chapter includes information about:
Note: Batch validation operates only on options that are BOM Model Items in Oracle Applications. Your host application must be part of Oracle Applications to implement batch validation.
Batch validation allows a host application to perform tasks such as:
Validating a BOM-based configuration in the background
Determining a configuration quantity
Deleting lines from a configured order while keeping the configuration valid
Re-validating a previously booked order, if the configuration rules have changed in the meantime
Using a custom user interface
A host application calls batch validation through the CZ_CF_API.VALIDATE PL/SQL procedure (see Calling the CZ_CF_API.VALIDATE Procedure). This procedure passes the batch validation message to the URL of the OC Servlet (see Passing the Batch Validation Message).
A batch validation message consists of information defining the configuration context (such as an identifier for the configured model) and a list of configured options. The message can be used to revalidate a previously saved configuration.
The elements of the batch validation message are described in Elements of the Batch Validation Message.
An example of the batch validation message is provided in Example of Batch Validation Message.
The following table describes the elements of the batch validation message.
| Element | Description | 
|---|---|
| <batch_validate> | Composed of an <initialize>subelement, which initializes the configuration session, and a<config_inputs>subelement, which provides the inputs to the configuration (replacing the inputs provided by an interactive user).The <batch_validate>element can include the parametervalidation_type, which indicates the type of validation to be performed. | 
| validation_type | Optional parameter to the <batch_validate>element. Values are:
 Example: <batch_validate validation_type="validate_order"> | 
| <initialize> | Described in Session Initialization. The parameters of the initialization message are described in Initialization Parameter Descriptions. See the description of the database_id parameter for connectivity information. | 
| <config_inputs> | Composed of a list of <option>elements. | 
| <option> | Described in Session Termination. When an <option>element is used in a<config_inputs>element, only the<component_code>and<quantity>elements of the<option>are used. | 
Example of Batch Validation Message
<batch_validate validation_type="validate_order">
  <initialize>
    <param name="context_org_id">204</param>
    <param name="config_creation_date">03-25-2001-19-30-02</param>
    <param name="calling_application_id">300</param>
    <param name="responsibility_id">20559</param>
    <param name="config_header_id">21361</param>
    <param name="config_rev_nbr">1</param>
    <param name="read_only">FALSE</param>
    <param name="save_config_behavior">new_revision</param>
    <param name="database_id">ap115sun_dev115</param>
  </initialize>
  <config_inputs>
    <option>
      <component_code>143-1490-1494</component_code>
      <quantity>1</quantity>
    </option>
    <option>
      <component_code>143-297</component_code>
      <quantity>1</quantity>
    </option>
  </config_inputs>
</batch_validate>
If the host application is written in PL/SQL, it should call the VALIDATE procedure. CZ_CF_API.VALIDATE is the PL/SQL interface to batch validation. The VALIDATE procedure packages the inputs into a batch_validate init message and sends it to the configurator servlet. There are restrictions in the way that PL/SQL can request data from a URL that requires PL/SQL programs to use the CZ_CF_API.VALIDATE procedure, instead of passing the XML batch validation message.
For details on the parameters for CZ_CF_API.VALIDATE, see VALIDATE in Programmatic Tools for Development.
Calling the CZ_CF_API.VALIDATE Procedure in a Program shows fragments from a PL/SQL program that calls CZ_CF_API.VALIDATE.
Calling the CZ_CF_API.VALIDATE Procedure in a Script shows a PL/SQL script that calls CZ_CF_API.VALIDATE.
Calling the CZ_CF_API.VALIDATE Procedure in a Program
...
/*-------------------------------------------------------------------------
Procedure Name : Send_input_XML
Description    : sends the xml batch validation message to hostapp that has
                 options that are newly inserted/updated/deleted 
                 from the model.
--------------------------------------------------------------------------*/
PROCEDURE Send_input_XML
            ( p_model_line_id       IN NUMBER ,
              p_org_id              IN NUMBER ,
              p_model_id            IN NUMBER ,
              p_config_header_id    IN NUMBER , 2003/10/20
              p_config_rev_nbr      IN NUMBER ,
              p_model_qty           IN NUMBER ,
              p_creation_date       IN DATE ,
              p_deleted_options_tbl IN   OE_Order_PUB.request_tbl_type                            := OE_Order_Pub.G_MISS_REQUEST_TBL, 
              p_updated_options_tbl IN   OE_Order_PUB.request_tbl_type                            := OE_Order_Pub.G_MISS_REQUEST_TBL 
              x_out_XML_msg         OUT NOCOPY LONG ,
              x_return_F            OUT NOCOPY VARCHAR2 )  
...
      l_XML_hdr                       VARCHAR2(2000)
      l_html_pieces                  CZ_CF_API.CFG_OUTPUT_PIECES;
      l_option                       CZ_CF_API.INPUT_SELECTION;
      l_batch_val_tbl                CZ_CF_API.CFG_INPUT_LIST;
      l_url                          VARCHAR2(500):=                                          FND_PROFILE.Value('CZ_UIMGR_URL');
      l_validation_type              CZ_API_PUB.VALIDATE_ORDER; 
...
       Create_hdr_XML
            ( p_model_line_id        => p_model_line_id ,
              p_org_id               => p_org_id ,
              p_model_id             => p_model_id ,
              p_config_header_id     => p_config_header_id , 
              p_config_rev_nbr       => p_config_rev_nbr ,
              p_model_qty            => p_model_qty ,
              p_creation_date        => p_creation_date ,
              x_XML_hdr              => l_XML_hdr);
...
CZ_CF_API.Validate( config_input_list => l_batch_val_tbl ,
                          init_message      => l_XML_hdr ,
                          config_messages   => l_html_pieces ,
                          validation_status => l_validation_status ,
                          URL               => l_url 
                          p_validation_type => l_validation_type );
Calling the CZ_CF_API.VALIDATE Procedure in a Script
set serveroutput on
set verify off
-- Run this query in SQL*Plus, providing input of model id
-- This query is like what the host application might send.
-- The output might go back to some other servlet.
BEGIN DECLARE
    config_input_list        CZ_CF_API.CFG_INPUT_LIST;
---- OC Servlet URL needs to be entered here....
    l_url                    VARCHAR2(100) := 'http://www.mysite.com:10130/OA_HTML/configurator/UiServlet';
    init_message             VARCHAR2(4000) := '<initialize>';
    config_messages          CZ_CF_API.CFG_OUTPUT_PIECES;
    validation_status        NUMBER;
    list_indx                NUMBER := 1;
    l_validation_type        VARCHAR2(1) := CZ_API_PUB.VALIDATE_ORDER;
    begtime                  VARCHAR2(30) := NULL;
    endtime                  VARCHAR2(30) := NULL;
--- Build the initialization message.
    TYPE param_name_type IS
        TABLE OF VARCHAR2(25) INDEX BY BINARY_INTEGER;
    TYPE param_value_type IS
        TABLE OF VARCHAR2(40) INDEX BY BINARY_INTEGER;
    param_name               param_name_type;
    param_value              param_value_type;
    l_rec_index              BINARY_INTEGER;
    l_context_org_id         VARCHAR2(30);
    l_config_creation_date   VARCHAR2(30);
    l_user                   VARCHAR2(30);
    l_fndnam                 VARCHAR2(30);
    l_calling_application_id VARCHAR2(30);
    l_responsibility_id      VARCHAR2(30);
    l_model_id               VARCHAR2(30);
    l_config_header_id       VARCHAR2(30);
    l_config_rev_nbr         VARCHAR2(30);
    l_read_only              VARCHAR2(30);
    l_save_config_behavior   VARCHAR2(30);
    l_save_usage_behavior    VARCHAR2(30);
    l_ui_type                VARCHAR2(30);
    l_so_line_id             VARCHAR2(30);
    l_validation_org_id      VARCHAR2(30);
    l_dbc                    VARCHAR2(30);
    l_model_quantity         VARCHAR2(30);
    l_termination            VARCHAR2(30);
    l_icx_ticket             VARCHAR2(100);
--Options
    l_component_code         VARCHAR2(2000);
    l_option_quantity        VARCHAR2(30);
    l_test_param             VARCHAR2(20);
BEGIN
    fnd_global.apps_initialize(l_user,l_responsibility_id,l_calling_application_id);
    
    l_icx_ticket:=cz_cf_api.icx_session_ticket;
    dbms_output.put_line('ICX Ticket = ' || l_icx_ticket);
    param_name(1) := 'context_org_id';
    param_name(2) := 'config_creation_date';
    param_name(3) := 'user';
    param_name(4) := 'fndnam';
    param_name(5) := 'calling_application_id';
    param_name(6) := 'responsibility_id';
    param_name(7) := 'model_id';
    param_name(8) := 'config_header_id';
    param_name(9) := 'config_rev_nbr';
    param_name(10) := 'read_only';
    param_name(11) := 'save_config_behavior';
    param_name(12) := 'save_usage_behavior';
    param_name(13) := 'model_quantity';
    param_name(14) := 'database_id';
    param_name(15) := 'terminate_msg_behavior';
    param_name(16) := 'icx_session_ticket';
    SELECT
        '204',
        '10-16-2000-09-41-12',
        'MFG',
        NULL,
        '660',
        '21623',
        '143', --this is the usual value for &modelId
        NULL,
        NULL,
        NULL,
        'new_revision',
        NULL,
        '45',
        'ap123dbs_dom123',
        'brief'
    INTO
        l_context_org_id,
        l_config_creation_date,
        l_user,
        l_fndnam,
        l_calling_application_id,
        l_responsibility_id,
        l_model_id,
        l_config_header_id,
        l_config_rev_nbr,
        l_read_only,
        l_save_config_behavior,
        l_save_usage_behavior,
        l_model_quantity,
        l_dbc,
        l_termination
    FROM dual;
        
    param_value(1) := l_context_org_id;
    param_value(2) := l_config_creation_date;
    param_value(3) := l_user;
    param_value(4) := l_fndnam;
    param_value(5) := l_calling_application_id;
    param_value(6) := l_responsibility_id;
    param_value(7) := l_model_id;
    param_value(8) := l_config_header_id;
    param_value(9) := l_config_rev_nbr;
    param_value(10) := l_read_only;
    param_value(11) := l_save_config_behavior;
    param_value(12) := l_save_usage_behavior;
    param_value(13) := l_model_quantity;
    param_value(14) := l_dbc;
    param_value(15) := l_termination;
    param_value(16) := l_icx_ticket;
    
    l_rec_index := 1;
    LOOP
        IF (param_value(l_rec_index) IS NOT NULL) THEN
            init_message := init_message || '<param name=' || '"' || param_name(l_rec_index) || '"' || '>' || param_value(l_rec_index) || '</param>';
        END IF;
        l_rec_index := l_rec_index + 1;
        EXIT WHEN l_rec_index > 16; -- adjust for number of parameters
    END LOOP;
    init_message := init_message || '</initialize>';
    init_message := REPLACE(init_message,' ','+');
    dbms_output.enable(buffer_size => 200000);
    dbms_output.put_line(substr(init_message,1,255));
    dbms_output.put_line(substr(init_message,256,255));
    dbms_output.put_line(substr(init_message,512,255));
    dbms_output.put_line(substr(init_message,768,255));
    dbms_output.put_line(substr(init_message,1024,255));
    dbms_output.put_line(substr(init_message,1280,255));
    
    CZ_CF_API.VALIDATE(config_input_list,init_message,config_messages,validation_status,l_url,l_validation_type);
    
    IF ( validation_status = cz_cf_api.config_processed ) THEN
        dbms_output.put_line('Config processed successfully');
    ELSIF ( validation_status = cz_cf_api.config_processed_no_terminate ) THEN
        dbms_output.put_line('Config processed successfully, no termination message');
    ELSIF ( validation_status = cz_cf_api.init_too_long ) THEN
        dbms_output.put_line('Init message too long');
    ELSIF ( validation_status = cz_cf_api.invalid_option_request ) THEN
        dbms_output.put_line('Invalid option request');
    ELSIF ( validation_status = cz_cf_api.config_exception ) THEN
        dbms_output.put_line('General config exception');
    ELSIF ( validation_status = cz_cf_api.database_error ) THEN
        dbms_output.put_line('Database error');
    ELSIF ( validation_status = cz_cf_api.utl_http_init_failed ) THEN
        dbms_output.put_line('UTL_HTTP: initialization failed');
    ELSIF ( validation_status = cz_cf_api.utl_http_request_failed ) THEN
        dbms_output.put_line('UTL_HTTP: request failed');
    ELSE
        dbms_output.put_line('Unknown error');
    END IF;
    l_rec_index := config_messages.FIRST;
    dbms_output.put_line ( 'Recieved Response from the server follows ....' );
    LOOP
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index),1,255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index),256,255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index), 512, 255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index), 768, 255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index), 1024, 255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index), 1280, 255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index), 1536, 255))));
        dbms_output.put_line(ltrim(rtrim(substr(config_messages(l_rec_index), 1792))));
    
        EXIT WHEN l_rec_index = config_messages.last;
        l_rec_index := config_messages.next(l_rec_index);
    END LOOP;
        dbms_output.put_line ('Servlet URL used follows ....');
        dbms_output.put_line(ltrim(rtrim(l_url)));
    END;
END;
/
An end user can determine whether an order fails during batch validation if the imported order's quantities are not the same as the quantities in the original order, or if the quantities changed during an order cycle because the configuration model's rules have changed. For example, batch validation is run at booking time. If the published Model has changed from the initial order creation to booking time, then batch validation may result in different quantities causing the order to fail.
By setting the profile option CZ: Fail BV if Input Quantities Not Maintained, the end user can determine whether an order fails. This profile option is used in conjunction with the parameter in the Calling the CZ_CF_API.VALIDATE Procedure.
Batch Validation fails if the ordered configured BOM Items (input_list) do not match the batch validation BOM Items (from a previously processed configuration) and the profile option CZ: Fail BV if Configuration Changed is set to Yes. If there is a difference between the ordered configured BOM Items and the batch validation BOM Items, then the differences are logged to CZ_CONFIG_MESSAGES.
For more information about the profile options, see the Oracle Configurator Installation Guide.
A significant amount of batch validation processing time can be avoided when the CZ: Skip Validation Procedure profile option is set. If the profile option is set, then batch validate calls a customer created PL/SQL callback procedure. This callback procedure then makes the final decision based on the implementation requirements. For more information on the CZ: Skip Validation Procedure, see the Oracle Configurator Installation Guide.
The decision to skip batch validation is done on the batch server for each batch validation request. To skip parts of the batch validation process, the following criteria must be met:
There are no input arguments.
The skip profile option, CZ: Skip Validation Procedure is set to the name of the PL/SQL callback function. For more information see the Oracle Configurator Installation Guide.
Effectivity date of the current configuration session is different from the effectivity date of the restored configuration and:
All nodes in the configuration model do not have effective start or end dates that are in the interval between the old and new effective dates.
All rules in the configuration model do not have effective start or end dates that are in the interval between the old and new effective dates.
The publication record of the configuration that is being validated is the same as that of the saved configuration.
The BOM Model quantity has not changed or is not provided in the initialization string
The custom created PL/SQL callback function returns true
When this function returns a value of true, the Batch Validation process does not perform all of its typical tasks, such as restoring the configuration and validating any inputs. A new configuration is saved when requested.
The validation type is not validate_fullfillment. See Elements of the Batch Validation Message for details.
A custom coded PL/SQL callback makes the final decision whether batch validation is skipped or not. A custom coded PL/SQL callback is needed because Configurator Extensions can change the configuration model. If there are no Configurator Extensions and you want to skip batch validation, then you must have a custom coded PL/SQL callback and enable the CZ: Skip Validation Procedure profile option. For more information on the CZ: Skip Validation Procedure, see the Oracle Configurator Installation Guide. Batch validation on its own cannot determine what a Configurator Extension does.
Specification of the PL/SQL Callback Function shows the function's coding details:
Specification of the PL/SQL Callback Function
PROCEDURE my_skip_val_proc(
    p_root_inv_item_id IN NUMBER
    p_organization_id IN NUMBER
    p_config_creation_date IN DATE
    x_skip_validation OUT NOCOPY VARCHAR2
    x_return_status OUT NOCOPY VARCHAR2
    x_msg_data OUT NOCOPY VARCHAR2)
The PL/SQL callback arguments are described in the tablePL/SQL Callback Arguments:
| Parameter | Data Type | Mode | Description | 
|---|---|---|---|
| p_root_inv_item_id | number | in | Root BOM Model Inventory Item ID | 
| p_organization_id | number | in | Root BOM Model Organization ID | 
| p_config_creation_date | date | in | Configuration creation date | 
| x_skip_validation | varchar2 | out | Must return FND_API.G_TRUE if validation can be skipped; otherwise, return FND_API.G_FALSE | 
| x_return_status | varchar2 | out | Must return FND_API.G_RET_STS_SUCCESS if procedure completed successfully; otherwise return FND_API.G_RET_STS_ERROR or FND_API.G_RET_STS_UNEXP_ERROR if an error occurs within the procedure | 
| x_msg_data | varchar2 | out | Contains an error message if the procedure is returning an x_return_statusvalue of FND_API.G_RET_STS_ERROR or FND_API.G_RET_STS_UNEXP_ERROR | 
If you wish to skip batch validation and you have Models that use Configurator Extensions, then you must consider what the Configurator Extensions do when you write the callback function. If the Configurator Extension depends on the following, then the callback function should return a value of false and force validation to occur:
Data held in custom tables that changes from time to time
Data in Oracle Applications tables, other than the configuration model's definitions, that change from time to time. For example, MTL_SYSTEM_ITEMS flexfields.
Data that is obtained by queries based on the CALLING_APPLICATION_HEADER_ID or CALLING_APPLICATION_LINE_ID that is provided in the Configurator initialization message. For example, SO_ORDER_HEADERS flexfield.
These dependencies could cause a Configurator Extension to make changes to the configuration and cause a validation failure.