1. 程式人生 > >EBS標準功能-->PR自動建立PO的邏輯

EBS標準功能-->PR自動建立PO的邏輯

之前一直對這個功能感覺很神祕。最近有個需求要客製化這點(將客制的PR的欄位自動帶到PO裡面),所以針對這個自動建立的邏輯過程瞭解了一下。

這些寫下來,好讓有需要了解或者有需求要修改的人可以知道這個是啥邏輯的。

-----------------------------

自動建立Form:POXBWVRP
點建立對應的按鈕:NEW_DOCUMENT.OK
執行程式碼:
action.autocreate_button('WHEN-BUTTON-PRESSED');
接著找,對應執行的程式碼:
核心處理庫:POXBWVRP.pll
new_document5.ok('WHEN-BUTTON-PRESSED');
核心PR自動建立PO的過程:action4.autocreate_documents;
------------------------------

簡而言之,其實所謂的PR自動建立PO,程式的邏輯是:
先根據PR的資料塞PO的介面表po_headers_interface/po_lines_interface,
然後再呼叫API(PO_INTERFACE_S.create_documents)生成對應的PO資訊。
當然,這裡我說的只是最核心的邏輯,前面的一大堆PR是否可以自動生成PO等等的驗證,還有另外的連帶的資料產生等等也是必須的。

------------------------------

action4.autocreate_documents;部分程式碼:

   begin
      insert into po_headers_interface
          (interface_header_id,
          interface_source_code,
          batch_id,
          process_code,       /* This used to be process_flag */
          action,             /* This used to be action_type_code */
          document_type_code,
          document_subtype,
          document_num,
          group_code,
          vendor_id,
          vendor_site_id,
          release_num,
          release_date,
          agent_id,
          currency_code,
          rate_type_code,     /* This used to be rate_type */
          rate_date,
          rate,
          vendor_list_header_id,
          --     quote_type_lookup_code, <-- no longer in headers_interface
          --     quotation_class_code,   <-- no longer in headers_interface
          --DPCARD{
          pcard_id,
          --DPCARD}
          creation_date,
          created_by,
          last_update_date,
         last_updated_by,
         org_id,  --<R12 MOAC>
         style_id)             --<R12 STYLES PHASE II >
          values
          (x_interface_header_id,
          'PO',
          x_batch_id,
          x_action_type_code_hdr,
          x_document_mode,
          x_document_type,
          x_document_subtype,
          x_segment1,
          x_group_code,
          x_vendor_id,
          x_vendor_site_id,
          x_release_number,
          x_release_date,
          x_agent_id,
          x_currency_code,
          x_rate_type,
          x_rate_date,
          x_rate,
          x_vendor_list_header_id,
          -- x_quote_type_lookup_code,
          -- x_quotation_class_code,
          --DPCARD{
          x_pcard_id,
          --DPCARD}
          x_creation_date,
          x_created_by,
          x_last_update_date,
         x_last_updated_by,
         l_purchasing_org_id,  --<R12 MOAC>
         l_style_id);          --<R12 STYLES PHASE II >




    exception
        when others then
                fnd_message.debug('In exception when trying to insert into po_headers');
        raise form_trigger_failure;
    end;




     /******************************************************************
             PO_LINES_INTERFACE stuff
      ******************************************************************/


    /* Loop thru the selected req lines and insert into
     * the po_lines_interface table.
     */


    x_progress:='003';


    for i in 1..x_num_records loop


      /* Get the action_type_code_line = NEW, ADD, NULL */




      if (name_in('POXBWVRP_WORLD.IN_PLACEMENT_MODE') = 'TRUE') then
         x_action_type_code_line := get_group_char_cell (
                        'CURRENT_STATE.ACTION_TYPE_CODE_LINE',
                        i);
         x_line_num              := get_group_number_cell(
                        'CURRENT_STATE.PO_LINE_NUMBER',
                        i);
         x_requisition_line_id   := get_group_number_cell(
                        'CURRENT_STATE.REQUISITION_LINE_ID',
                                i);
     x_originally_on_doc     := get_group_char_cell(
                        'CURRENT_STATE.ORIGINALLY_ON_DOC',
                         i);
      else
     x_action_type_code_line := null;
         x_line_num         := null;
         x_requisition_line_id   := get_group_number_cell(
                        'REQ_LINES_MULTI.REQUISITION_LINE_ID',
                                i);
     x_originally_on_doc     := 'N';


        /* Bug 421496. gtummala. 11/9/97
         * We need to allow one-time req lines to be autocreated onto blanket
         * releases. To allow this we need at least 80.9 of POXBWPOB.pls. The backend
         * procedure needs us  to populate the blanket source line and also set the
         * line action code to 'ADD'.
         */


        x_item_id   := get_group_number_cell('REQ_LINES_MULTI.ITEM_ID', i);


        if (name_in('ACTION.DOCUMENT_TYPE') = 'RELEASE') and
           (x_item_id is NULL)  then
           x_progress:='004';


          /* Need to get the blanket source line that matches */
          x_line_num := action4.get_blanket_line_num(
                    name_in('new_document.document_number'),
                            i);


          /* Backend needs action=ADD for one-time items to be handled */
          x_action_type_code_line := 'ADD';


        end if;


      end if;


      x_progress:='005';


        -- Validations ========================================================


     /* Before we do anything, got to make sure that the req. lines
      * have not in any changed by another user/session since they
      * were queried by this session.
      *
      * If it fails then get out of this loop and don't insert into
      * po_lines_interface.
      */


      if (x_originally_on_doc = 'N') then
         x_req_line_ok_to_autocreate:= action5.req_line_ok_to_autocreate
                          (x_rec_group,
                    get_group_char_cell(x_rec_group||'.REQ_NUMBER',i),
                    get_group_number_cell(x_rec_group||'.REQ_LINE_NUMBER',i),
                            x_requisition_line_id);
      end if;




       /* FPI GA start */
       /* Populate the reference document */
       /* Reference docs need to be populated only for standard PO's (bug 2714252) */




      /* FPI GA end */


        -- Insert into Interface Table ========================================      


      /* INSERT into lines interface table */


      /* Do not insert those lines already on the document when in the
       * the current_state mode.
       */


       if ((name_in('POXBWVRP_WORLD.IN_PLACEMENT_MODE') = 'TRUE' AND
           x_originally_on_doc = 'Y'))                     OR
           (x_req_line_ok_to_autocreate=FALSE) then
          null;


       else
           IF (name_in('ACTION.DOCUMENT_TYPE') = 'STANDARD') THEN


                GA_REFERENCE.populate_ref_info(x_requisition_line_id ,
                                               x_src_header_id      ,
                                               x_src_line_id ,
                                               x_consigned_flag,  -- CONSIGNED FPI
                                               l_contract_id);    -- <GC FPJ> 
             --<bug#4387937 START> Added code to null out the contract id if a 
             --global agreement is specified during document creation.
                 IF (NAME_IN('NEW_DOCUMENT.GLOBAL_AGREEMENT_ID') IS NOT NULL)THEN
                    l_contract_id:= null;
                 END IF;
             --<bug#4387937 END>


           END IF;


      /* Get the next available interface_line_id */


            SELECT po_lines_interface_s.nextval
            INTO x_interface_line_id
            FROM dual;


          x_progress:='006';


         begin
          insert into po_lines_interface
            (interface_header_id,
            interface_line_id,
            action,                /* This used to be action_type_code */
            line_num,
            shipment_num,
            requisition_line_id,
            creation_date,
            created_by,
            from_header_id,  -- GA FPI
            from_line_id,    -- GA FPI
            consigned_flag,  -- CONSIGNED FPI
            contract_id,     -- <GC FPJ>
            last_update_date,
            last_updated_by)
          values
            (x_interface_header_id,
            x_interface_line_id,
            x_action_type_code_line,
            x_line_num,
            null,
            x_requisition_line_id,
            x_creation_date,
            x_created_by,
            x_src_header_id,    -- GA FPI
            x_src_line_id,      -- GA FPI
            x_consigned_flag,   -- CONSIGNED FPI
            l_contract_id,      -- <GC FPJ>
            x_last_update_date,
            x_last_updated_by);


          exception
             when others then
                  fnd_message.debug('In exception when trying to insert into po_lines');
          raise form_trigger_failure;
          end;


       end if;


    end loop;


   /* Start Bug 3487756: Insert vendor contact id into po_headers_interface.
     * Only insert the contact id at the interface header level 
     * if all the req. lines being autocreated have the same contact id.
     */




    -- Derive unique vendor contact id on all the requisiton lines.
    BEGIN
      SELECT distinct porl.vendor_contact_id
      INTO x_vendor_contact_id
      FROM  po_lines_interface poli
          , po_requisition_lines_all porl
      WHERE poli.interface_header_id = x_interface_header_id
        AND poli.requisition_line_id = porl.requisition_line_id;
    EXCEPTION
      WHEN too_many_rows THEN
        -- more than one vendor contact id; do not copy to header interface
        x_vendor_contact_id := NULL;
      WHEN no_data_found THEN
        x_vendor_contact_id := NULL;
      WHEN others THEN
        fnd_message.debug('In exception when selecting vendor contact id');
        raise form_trigger_failure;
    END;     


    -- Validate contact id and then update headers interface.
    BEGIN
      -- Check if the contact is valid for the supplier site.
      IF (x_vendor_contact_id IS NOT NULL)
      THEN
        SELECT (count(vendor_contact_id))
        INTO  x_vendor_contact_count
        FROM  po_vendor_contacts
        WHERE vendor_site_id = x_vendor_site_id
          AND vendor_contact_id = x_vendor_contact_id
          AND nvl(inactive_date, sysdate+1) > sysdate;
        IF (x_vendor_contact_count <= 0)
        THEN
           x_vendor_contact_id := NULL;
        END IF;  
      END IF;


      -- Update headers interface table with contact_id derived above.
      UPDATE po_headers_interface
      SET vendor_contact_id = x_vendor_contact_id
      WHERE interface_header_id = x_interface_header_id;
    EXCEPTION
      WHEN others THEN
        fnd_message.debug('In exception when updating po headers interface with vendor contact id');
        raise form_trigger_failure;
    END;


    /* End Bug 3487756 */


    /* Call the main sever side routine to actually create
     * the documents, ie:
     *             - default in values not populated
     *            - group accordingly
     *            - insert into the main tables from the
     *              the interface tables.
     *
     * x_document_id is populated with po_header_id for pos and
     * po_release_id for releases from the backend only when newly
     * created. In add to scenarios we have to get the value ourselves.
     * This is done in the wbp trigger for the ok button  in the
     * add to window.
     */


     x_progress:='007';


     --<Shared Proc FPJ START>
     l_requesting_org_id := to_number(name_in('POXBWVRP_WORLD.current_org_id'));


     --<R12 STYLES PHASE II START>
     if PO_DOC_STYLE_PVT.is_progress_payments_enabled(l_style_id) then
        if l_requesting_org_id <> l_purchasing_org_id then 
           FND_MESSAGE.set_name('PO', 'PO_REQLINE_PURCH_ORG_MISMATCH');
           FND_MESSAGE.SHOW;
           RAISE style_validate_failure;
        end if;
     end if;
     --<R12 STYLES PHASE II END>


     --Changing the call to new signature of Autocreate Backend
     PO_INTERFACE_S.create_documents (
                      p_api_version             => 1.0,
                      x_return_status           => l_return_status,
                      x_msg_count               => l_msg_count,
                      x_msg_data                => l_msg_data,
                      p_batch_id                => x_interface_header_id,
                      p_req_operating_unit_id   => l_requesting_org_id,
                      p_purch_operating_unit_id => l_purchasing_org_id,
                      x_document_id             => x_document_id,
                      x_number_lines            => x_num_lines_processed,
                      x_document_number         => l_document_number,
                      -- Bug 3648268 Use lookup code instead of hardcoded value
                      p_document_creation_method => 'AUTOCREATE',  -- <DBI FPJ>
                      p_orig_org_id              => l_purchasing_org_id    --<R12 MOAC>
     );