Wednesday, October 28, 2015

How to restrict Keyflexfield LOV using Form Personalization?


It is quite easy to replace the seeded LOV record groups using forms personalization of simple text items but when it comes to restricting the KFF LOVs you may have no idea of how to do it and it can be clueless situation for many but here I'm sharing a simple solution for this type of requirements.
In the below example we will restrict  the Item Number Lov of PO Requisitions form using a DFF attribute value. It requires a collaboration of forms personlization and custom.pll to do the task. We will use the Seeded library procedure i.e. fnd_key_flex.update_definition which allows to update the where clause of KFF Lovs.

Prereqs:

Oracle Forms Builder
PLSQL
Know-how of forms Personaliation


Steps:

1 - Open the form where you need to personalize the KFF LOV and start creating a personalization with any event trigger and any condition as per your requirement

2 - In the actions tab use Builtin action type and use Call Custom Library with a specific Event name like the following


 The argument field is containing the custom event name that we will deal with in the custom.pll afterwards. You may use some other event name as per your terminology and choice.

3 - Now download the custom.pll from the AU_TOP to your local machine and open it in the form builder and edit the event procedure like the following (as per your requirement)

procedure event(event_name varchar2) is
   v_alloc_number varchar2(100);
  begin
        if (event_name = 'RESTRICT_ITEM_LOV') then  
            v_alloc_number := name_in('PO_REQ_HDR.ATTRIBUTE1');  -- getting the attribute1 value of header dff
          fnd_key_flex.update_definition (BLOCK                            => 'LINES',    
                                                                     FIELD                              =>  'ITEM_NUMBER',
                                                                     ENABLED                       => 'Y',      
                                                                     WHERE_CLAUSE          => '( INVENTORY_ITEM_ID in (Select B.Item_Id From Cust_Po_Allocation_Header_All A,Po.Cust_Po_Allocation_Lines B Where A.Header_Id = B.Header_Id And A.Allocation_Order_Number = '''||v_alloc_number||''')'||')'
                                                                     );

        end if;

  end event; 

4 - Recompile the custom.pll in the form builder and upload it to AU_TOP (don't forget to backup the original file before uploading the modified one)  

5 - Restart the application services and test the personalization 

6 - End


Thanks



Tuesday, September 22, 2015

Oracle Payables R12 Invoice Scheduled Payments (Partial Pay) Generation by Seeded APIs

Create or Replace PROCEDURE CUST_INVOICE_PAYMENTS(P_INVOICE_ID IN NUMBER,P_FROM_DATE IN Date,P_TO_DATE in Date,P_STATUS out varchar2,P_ERR_MSG out varchar2) IS

           v_check_rowid VARCHAR2(100) := null;
           V_INTERNAL_BANK_ACCT_ID NUMBER;
           V_BANK_ACCOUNT_ID NUMBER;
           V_BANK_ACCOUNT_NUM VARCHAR2(250);
           V_BANK_ACCOUNT_NAME VARCHAR2(250);
           V_CHECK_NUMBER NUMBER;
           v_event_id number;
           v_check_id number;
           V_DOC_CATEGORY_CODE VARCHAR2(50);
           v_user_id number := fnd_profile.value('USER_ID');
           V_APCC_ID NUMBER;
           V_ACCOUNT_NATURE VARCHAR2(150);
           v_msg_out varchar2(4000);
           V_INVOICE_PAYMENT_ID number;
           V_PAYMENT_DOCUMENT_ID number;
           v_doc_seq_val number;
           v_doc_seq_id number;
           v_db_seq_name varchar2(75);
           V_PAYMENT_PROFILE_ID number := 739; -- Standard Cheque
           v_stmt varchar2(250);
           v_ref_cur sys_refcursor;
         
 
       -- for payment of current invoice
        CURSOR CUR_INVOICE IS
             SELECT AIA.ORG_ID,
                    AIA.INVOICE_NUM,
                    AIA.GL_DATE,
                    AIA.PAYMENT_METHOD_LOOKUP_CODE,
                    AIA.INVOICE_ID,
                    aia.accts_pay_code_combination_id pay_ccid ,
                    AIA.VENDOR_ID,
                    AIA.VENDOR_SITE_ID,
                    AIA.ATTRIBUTE2,
                    AIA.ATTRIBUTE3,
                    AIA.ATTRIBUTE4,
                    AIA.ATTRIBUTE5,
                    AIA.ATTRIBUTE6,
                    APSA.AMOUNT_REMAINING INVOICE_AMOUNT,
                    aia.invoice_amount base_amt ,
                    AIA.DOC_CATEGORY_CODE,
                    PV.VENDOR_NAME,
                    PV.PARTY_ID ,
                    PVSA.VENDOR_SITE_CODE,
                    PVSA.ADDRESS_LINE1,
                    PVSA.ADDRESS_LINE2,
                    PVSA.ADDRESS_LINE3,
                    PVSA.CITY,
                    PVSA.COUNTRY,
                    PVSA.PARTY_SITE_ID ,
                    APSA.PAYMENT_NUM,
                    APSA.DUE_DATE ,
                    APSA.ATTRIBUTE_CATEGORY ATTRIBUTE_CATEGORY_SCH,
                    APSA.ATTRIBUTE1 ATTRIBUTE1_SCH
            FROM AP_INVOICES_ALL AIA,
              PO_VENDORS PV,
              PO_VENDOR_SITES_ALL PVSA,
              AP_PAYMENT_SCHEDULES_ALL APSA
           WHERE AIA.INVOICE_ID = APSA.INVOICE_ID
             AND   AIA.INVOICE_ID = P_INVOICE_ID
             AND   AIA.VENDOR_ID = PV.VENDOR_ID
             AND   AIA.VENDOR_SITE_ID = PVSA.VENDOR_SITE_ID
             AND APSA.AMOUNT_REMAINING <> 0
             AND APSA.HOLD_FLAG = 'N'
             AND APSA.DUE_DATE BETWEEN P_FROM_DATE AND P_TO_DATE
             AND AIA.WFAPPROVAL_STATUS LIKE  '%APPROVED%'
            ORDER BY APSA.PAYMENT_NUM;


Begin

  v_user_id := nvl(v_user_id,-1);

  FOR V_INVOICE_ROW IN CUR_INVOICE LOOP        
 
       SELECT         BANK_ACCOUNT_ID,BANK_ACCOUNT_NUM,BANK_ACCOUNT_NAME,ATTRIBUTE1
              INTO V_INTERNAL_BANK_ACCT_ID,V_BANK_ACCOUNT_NUM,V_BANK_ACCOUNT_NAME,V_ACCOUNT_NATURE
             FROM CE_BANK_ACCOUNTS
            WHERE BANK_ACCOUNT_ID =   V_INVOICE_ROW.ATTRIBUTE2;
 
          IF V_ACCOUNT_NATURE   <> V_INVOICE_ROW.DOC_CATEGORY_CODE THEN
             P_ERR_MSG := 'Invoice Document Category Does not match with Bank Account Nature';
             P_STATUS := 'E' ;
             Return;        
          ELSE
 
                 
             SELECT payment_document_id,LAST_ISSUED_DOCUMENT_NUMBER+1 ,PAYMENT_DOC_CATEGORY
               into V_PAYMENT_DOCUMENT_ID,V_CHECK_NUMBER,V_DOC_CATEGORY_CODE
               FROM CE_PAYMENT_DOCUMENTS
              WHERE internal_bank_account_id = V_INTERNAL_BANK_ACCT_ID
                AND payment_instruction_id IS NULL;
         
             select doc_sequence_id,db_sequence_name
               into v_doc_seq_id,v_db_seq_name
               from  fnd_document_sequences
               where table_name = 'AP_CHECKS_ALL'
                 and name like '%Payment%Voucher%Auto%'
                 and db_sequence_name is not null
                 and end_date is null ;

              select AP_CHECKS_S.NEXTVAL into v_check_id from dual;

              v_stmt := 'select '||v_db_seq_name||'.nextval from dual';
              open v_ref_cur for v_stmt;
              fetch v_ref_cur into v_doc_seq_val;
              close v_ref_cur;

             mo_global.set_policy_context('S',V_INVOICE_ROW.org_id); -- Single Org context for AP_CHECKS_PKG
       
             fnd_global.apps_initialize(v_user_id,20639,200) ; -- Payables Super User Resp context
       
          -- Create check
             ap_checks_pkg.insert_row ( x_rowid => v_check_rowid,
                                        x_amount => V_INVOICE_ROW.INVOICE_AMOUNT,
                                        X_Ce_Bank_Acct_Use_Id => V_INTERNAL_BANK_ACCT_ID,
                                        x_bank_account_name => V_BANK_ACCOUNT_NAME,
                                        x_check_date => V_INVOICE_ROW.DUE_DATE,
                                        x_check_id => v_check_id,
                                        x_check_number => V_CHECK_NUMBER,
                                        x_currency_code => 'PKR',
                                        x_last_updated_by => v_user_id,
                                        x_last_update_date => SYSDATE,
                                        x_payment_method_code => 'CHECK',
                                        x_payment_type_flag => 'Q',
                                        x_address_line1 => V_INVOICE_ROW.ADDRESS_LINE1,
                                        x_address_line2 => V_INVOICE_ROW.ADDRESS_LINE2,
                                        x_address_line3 => V_INVOICE_ROW.ADDRESS_LINE3,
                                        x_checkrun_name => 'Quick Payment: ID='||v_check_id,
                                        x_city => V_INVOICE_ROW.city,
                                        x_country => V_INVOICE_ROW.country,
                                        x_created_by => v_user_id,
                                        x_creation_date => SYSDATE,
                                        x_last_update_login => fnd_profile.value('LOGIN_ID'),
                                        x_status_lookup_code => 'NEGOTIABLE',
                                        x_vendor_name => V_INVOICE_ROW.VENDOR_NAME,
                                        x_vendor_site_code => V_INVOICE_ROW.VENDOR_SITE_CODE,
                                        x_external_bank_account_id => V_INTERNAL_BANK_ACCT_ID,
                                        x_bank_account_num => V_BANK_ACCOUNT_NUM,
                                        x_doc_category_code => V_DOC_CATEGORY_CODE,
                                        x_payment_profile_id => V_PAYMENT_PROFILE_ID,
                                        x_payment_document_id => V_PAYMENT_DOCUMENT_ID,
                                        x_doc_sequence_id => v_doc_seq_id,
                                        x_doc_sequence_value => v_doc_seq_val,
                                        x_org_id => V_INVOICE_ROW.org_id,
                                        x_vendor_id => V_INVOICE_ROW.vendor_id,
                                        x_vendor_site_id => V_INVOICE_ROW.vendor_site_id,
                                        x_party_id  =>  v_invoice_row.party_id ,
                                        x_party_site_id => V_INVOICE_ROW.party_site_id ,
                                        x_calling_sequence => 'PLSQL'
                                       );

        if  v_check_rowid is not null then                        
         
             create_payment_event(v_check_id,V_event_id);
 
             Select AP_INVOICE_PAYMENTS_S.nextval
              into V_INVOICE_PAYMENT_ID
              from dual;
           
           -- create payment
               ap_pay_invoice_pkg.ap_pay_invoice( p_invoice_id => V_INVOICE_ROW.invoice_id,
                                                  p_check_id => v_check_id,
                                                  p_payment_num => V_INVOICE_ROW.payment_num,
                                                  p_invoice_payment_id => v_invoice_payment_id,
                                                  P_org_id => V_INVOICE_ROW.org_id,
                                                  p_period_name => to_char(sysdate,'MON-YY'),
                                                  p_accounting_date => V_INVOICE_ROW.DUE_DATE,
                                                  P_accts_pay_ccid => V_INVOICE_ROW.pay_ccid,
                                                  P_accounting_event_id => V_event_id,
                                                  p_amount => V_INVOICE_ROW.INVOICE_AMOUNT,
                                                  p_discount_taken => 0,
                                                  p_accrual_posted_flag => 'N',
                                                  p_cash_posted_flag => 'N',
                                                  p_posted_flag => 'N',
                                                  p_set_of_books_id => 1001,
                                                  p_last_updated_by => v_user_id,
                                                  p_currency_code => 'PKR',
                                                  p_replace_flag => 'N',
                                                  P_ce_bank_acct_use_id => V_INTERNAL_BANK_ACCT_ID,
                                                  p_bank_account_num => V_BANK_ACCOUNT_NUM,
                                                  p_payment_mode => 'PAY',
                                                  P_attribute_category => V_INVOICE_ROW.ATTRIBUTE_CATEGORY_SCH,
                                                  P_attribute1 => V_INVOICE_ROW.ATTRIBUTE1_SCH,
                                                  P_calling_sequence => 'PLSQL'
                                            );

                      -- create payment history
                        AP_RECONCILIATION_PKG.INSERT_PAYMENT_HISTORY( X_CHECK_ID => v_check_id,
                                                                      X_TRANSACTION_TYPE => 'PAYMENT CREATED',
                                                                      X_ACCOUNTING_DATE => V_INVOICE_ROW.DUE_DATE,
                                                                      X_TRX_BANK_AMOUNT =>null ,
                                                                      X_ERRORS_BANK_AMOUNT => null,
                                                                      X_CHARGES_BANK_AMOUNT => null,
                                                                      X_BANK_CURRENCY_CODE => null,
                                                                      X_BANK_TO_BASE_XRATE_TYPE => null,
                                                                      X_BANK_TO_BASE_XRATE_DATE => null,
                                                                      X_BANK_TO_BASE_XRATE => null,
                                                                      X_TRX_PMT_AMOUNT => V_INVOICE_ROW.INVOICE_AMOUNT,
                                                                      X_ERRORS_PMT_AMOUNT => null,
                                                                      X_CHARGES_PMT_AMOUNT => null,
                                                                      X_PMT_CURRENCY_CODE => 'PKR',
                                                                      X_PMT_TO_BASE_XRATE_TYPE => null,
                                                                      X_PMT_TO_BASE_XRATE_DATE => null,
                                                                      X_PMT_TO_BASE_XRATE => null,
                                                                      X_TRX_BASE_AMOUNT => null,
                                                                      X_ERRORS_BASE_AMOUNT => null,
                                                                      X_CHARGES_BASE_AMOUNT => null,
                                                                      X_MATCHED_FLAG => null,
                                                                      X_REV_PMT_HIST_ID => null,
                                                                      X_ORG_ID => V_INVOICE_ROW.org_id,
                                                                      X_CREATION_DATE => sysdate,
                                                                      X_CREATED_BY => v_user_id,
                                                                      X_LAST_UPDATE_DATE => sysdate,
                                                                      X_LAST_UPDATED_BY => v_user_id,
                                                                      X_LAST_UPDATE_LOGIN => null,
                                                                      X_PROGRAM_UPDATE_DATE => null,
                                                                      X_PROGRAM_APPLICATION_ID => null,
                                                                      X_PROGRAM_ID => null,
                                                                      X_REQUEST_ID => null,
                                                                      X_CALLING_SEQUENCE => 'PLSQL',
                                                                      X_ACCOUNTING_EVENT_ID => V_event_id,
                                                                      X_INVOICE_ADJUSTMENT_EVENT_ID => null
                                                                    );
             
         begin
             
                        Update CE_PAYMENT_DOCUMENTS
                         set LAST_AVAILABLE_DOCUMENT_NUMBER = V_CHECK_NUMBER ,
                             LAST_ISSUED_DOCUMENT_NUMBER = V_CHECK_NUMBER ,
                             LAST_UPDATE_DATE = sysdate,
                             LAST_UPDATED_BY = v_user_id
                        WHERE  internal_bank_account_id = V_INTERNAL_BANK_ACCT_ID
                          AND    payment_instruction_id IS NULL;
                    end;

   P_ERR_MSG := 'Payment Created for Given Invoice : ' || V_INVOICE_ROW.INVOICE_NUM || ', Check Number ' ||V_CHECK_NUMBER || ' ,CHECK_ID '||v_check_id;
                P_STATUS := 'S' ;
                Commit;  
                else
                      P_ERR_MSG := 'Check not created' ;
                       P_STATUS := 'U' ;
                     rollback;    
             end if;                        
         END IF;
       
   End loop;


 
  Exception when others then
     P_ERR_MSG := SQLCODE||' - '||SQLERRM;
     P_STATUS := 'E' ;
     Rollback;
End CUST_INVOICE_PAYMENTS;



2. Create payment event procedure code 

Procedure create_payment_event (p_check_id in number,p_event_id out number) is

 
  P_EVENT_SOURCE_INFO APPS.XLA_EVENTS_PUB_PKG.T_EVENT_SOURCE_INFO;
  P_EVENT_TYPE_CODE VARCHAR2(200);
  P_EVENT_DATE DATE;
  P_EVENT_STATUS_CODE VARCHAR2(200);
  P_EVENT_NUMBER NUMBER;
  P_TRANSACTION_DATE DATE;
  P_REFERENCE_INFO APPS.XLA_EVENTS_PUB_PKG.T_EVENT_REFERENCE_INFO;
  P_VALUATION_METHOD VARCHAR2(200);
  P_SECURITY_CONTEXT APPS.XLA_EVENTS_PUB_PKG.T_SECURITY;
  v_Return NUMBER;

cursor c_pmt is
 select check_id , CHECK_NUMBER,CHECK_DATE , org_id,LEGAL_ENTITY_ID
  from ap_checks_all 
 where check_id = p_check_id ;  

BEGIN

 
  for rec in  c_pmt loop
  
  P_EVENT_SOURCE_INFO.source_application_id := 200;
  P_EVENT_SOURCE_INFO.application_id := 200;
  P_EVENT_SOURCE_INFO.legal_entity_id := rec.LEGAL_ENTITY_ID ;
  P_EVENT_SOURCE_INFO.ledger_id := 1001;
  P_EVENT_SOURCE_INFO.entity_type_code := 'AP_PAYMENTS' ;
  P_EVENT_SOURCE_INFO.transaction_number := rec.CHECK_NUMBER ;
  P_EVENT_SOURCE_INFO.source_id_int_1 := rec.check_id;
  
  P_EVENT_TYPE_CODE := 'PAYMENT CREATED';
  P_EVENT_DATE := rec.CHECK_DATE;
  P_EVENT_STATUS_CODE := 'U';
  P_EVENT_NUMBER := 1;
  P_TRANSACTION_DATE := rec.CHECK_date;

  P_REFERENCE_INFO.reference_num_1 := null ;
  P_REFERENCE_INFO.reference_num_2 := null ;
  P_REFERENCE_INFO.reference_char_1 := rec.CHECK_NUMBER;
  P_REFERENCE_INFO.reference_char_2 := null;
  P_REFERENCE_INFO.reference_date_1 := null;
 
   P_VALUATION_METHOD := NULL;
  -- Modify the code to initialize the variable
   P_SECURITY_CONTEXT.security_id_int_1 := rec.org_id;
   P_SECURITY_CONTEXT.security_id_int_2 := null;
   P_SECURITY_CONTEXT.security_id_char_1 := null;
   P_SECURITY_CONTEXT.security_id_char_2 := null;
   

  v_Return := XLA_EVENTS_PUB_PKG.CREATE_EVENT(
    P_EVENT_SOURCE_INFO => P_EVENT_SOURCE_INFO,
    P_EVENT_TYPE_CODE => P_EVENT_TYPE_CODE,
    P_EVENT_DATE => P_EVENT_DATE,
    P_EVENT_STATUS_CODE => P_EVENT_STATUS_CODE,
    P_EVENT_NUMBER => P_EVENT_NUMBER,
    P_TRANSACTION_DATE => P_TRANSACTION_DATE,
    P_REFERENCE_INFO => P_REFERENCE_INFO,
    P_VALUATION_METHOD => P_VALUATION_METHOD,
    P_SECURITY_CONTEXT => P_SECURITY_CONTEXT
  );
p_event_id := v_Return;

commit;

end loop;
  
Exception when others then
 fnd_file.put_line(fnd_file.log,sqlerrm);
END create_payment_event;