Extend Billing and Payment

Use an order management extensions to manage billing and payment data on your sales order.

Some of these examples test a value for the purchase order number on the order header. This test isolates the extension and prevents it from affecting other developers who might also be running test code. For details, see Overview of Creating Order Management Extensions.

Some examples include methods that you can use with an extensible flexfield, such as getOrCreateContextRow. For details about them, see Guidelines for Setting Up Extensible Flexfields in Order Management.

Get Details for Billing Plans from Order Lines

import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;

def poNumber = header.getAttribute("CustomerPONumber");
if (poNumber == null) return;
if (!poNumber.startsWith("PMC TEST")) return;

List < Message > messages = new ArrayList < Message > ();

def lines = header.getAttribute("Lines");
while (lines.hasNext()) {
    def line = lines.next();
    def billingPlans = line.getAttribute("BillingPlans");
    while (billingPlans.hasNext()) {
        def billingPlan = billingPlans.next();
        messages.add(new Message(Message.MessageType.ERROR, "BillingPlanTypeCode is " + billingPlan.getAttribute("BillingPlanTypeCode")));
        messages.add(new Message(Message.MessageType.ERROR, "BillingPlanId is " + billingPlan.getAttribute("BillingPlanId")));
        messages.add(new Message(Message.MessageType.ERROR, "ObjectVersionNumber is " + billingPlan.getAttribute("ObjectVersionNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "BillingTrxDate is " + billingPlan.getAttribute("BillingTrxDate")));
        messages.add(new Message(Message.MessageType.ERROR, "CancellationEffectiveDate is " + billingPlan.getAttribute("CancellationEffectiveDate")));
        messages.add(new Message(Message.MessageType.ERROR, "FulfillLineId is " + billingPlan.getAttribute("FulfillLineId")));

        messages.add(new Message(Message.MessageType.ERROR, "OverridePeriod is " + billingPlan.getAttribute("OverridePeriod")));
        messages.add(new Message(Message.MessageType.ERROR, "OverridePeriodAmount is " + billingPlan.getAttribute("OverridePeriodAmount")));
        messages.add(new Message(Message.MessageType.ERROR, "PeriodicityCode is " + billingPlan.getAttribute("PeriodicityCode")));
        messages.add(new Message(Message.MessageType.ERROR, "PeriodicityName is " + billingPlan.getAttribute("PeriodicityName")));
    }
}

ValidationException ex = new ValidationException(messages);
throw ex;.

Get Details for Payment Methods from Order Lines

import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;

if (!"PMC TEST".equals(header.getAttribute("CustomerPONumber"))) return;

List < Message > messages = new ArrayList < Message > ();

def lines = header.getAttribute("Lines");
while (lines.hasNext()) {
    def line = lines.next();

    def payments = line.getAttribute("Payments");

    messages.add(new Message(Message.MessageType.ERROR, "PaymentMethodCode is " + payments.hasNext()));

    while (payments.hasNext()) {
        def payment = payments.next();


        messages.add(new Message(Message.MessageType.ERROR, "PaymentMethodCode is " + payment.getAttribute("PaymentMethodCode")));
        messages.add(new Message(Message.MessageType.ERROR, "PaymentTransactionIdentifier is " + payment.getAttribute("PaymentTransactionIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "PaymentSetIdentifier is " + payment.getAttribute("PaymentSetIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "SourceTransactionPaymentIdentifier is " + payment.getAttribute("SourceTransactionPaymentIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "ReceiptMethodId is " + payment.getAttribute("ReceiptMethodId")));
        messages.add(new Message(Message.MessageType.ERROR, "PaymentMethod is " + payment.getAttribute("PaymentMethod")));
        messages.add(new Message(Message.MessageType.ERROR, "PaymentTypeCode is " + payment.getAttribute("PaymentTypeCode")));
        messages.add(new Message(Message.MessageType.ERROR, "PaymentType is " + payment.getAttribute("PaymentType")));
        messages.add(new Message(Message.MessageType.ERROR, "FulfillLineId is " + payment.getAttribute("FulfillLineId")));
        messages.add(new Message(Message.MessageType.ERROR, "HeaderId is " + payment.getAttribute("HeaderId")));
        messages.add(new Message(Message.MessageType.ERROR, "ObjectVersionNumber is " + payment.getAttribute("ObjectVersionNumber")));

        messages.add(new Message(Message.MessageType.ERROR, "AuthorizationStatus is " + payment.getAttribute("AuthorizationStatus")));
        messages.add(new Message(Message.MessageType.ERROR, "InstrumentAssignmentIdentifier is " + payment.getAttribute("InstrumentAssignmentIdentifier")));
    }

}

ValidationException ex = new ValidationException(messages);
throw ex;

Set the Billing Transaction ID

String orderTypeCode = header.getAttribute("TransactionTypeCode");
 
def billingTxnTypeId = null;
 
if( orderTypeCode.equals("STD") ) { // Get the order type.       
   billingTxnTypeId = getBillingTxnTypeId("Credit Memo"); 
}
else if ( orderTypeCode.equals("MIX") ){
   billingTxnTypeId = getBillingTxnTypeId("Invoice");          
}
 
def lines = header.getAttribute("Lines");// Get the lines for the row set.
 
while( lines.hasNext() ) {// If more order lines exist...
    def line = lines.next(); 
    line.setAttribute("BillingTransactionTypeIdentifier", billingTxnTypeId);
}
 
Long getBillingTxnTypeId(String billingTxnTypeName) {
  
  def txnTypePVO = context.getViewObject("oracle.apps.financials.receivables.publicView.TransactionTypePVO");
     
  // Create view criteria (where clause predicates)
  def vc = txnTypePVO.createViewCriteria();
  def vcrow = vc.createViewCriteriaRow();
  vcrow.setAttribute("Name", billingTxnTypeName); 
   
   
  // Execute the view object query to find a matching row
  def rowset = txnTypePVO.findByViewCriteriaWithBindVars(vc, 1, new String[0], new Object[0]);
     
  // check if we have a matching row
  def row = rowset.first();
   
  Long txnTypeId = (Long) row.getAttribute("CustTrxTypeSeqId");
  //header.setAttribute("ShippingInstructions", txnTypeId);  // debug statement
   
  return txnTypeId;
}

Prevent Updates on the Billing Transaction Type

If Order Management already sent the order line to accounts receivable, then don't allow Order Management to update the billing transaction type on the order line.

import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
 
def po = header.getAttribute("CustomerPONumber");
if (po == null || !"VS_TEST".equals(po))
    return;
 
def reference = header.getAttribute("ReferenceHeaderId");
if (reference == null) return;
 
previousLinesMap = [:];
IsBillingTrxTypeIdUpdateable(reference);
 
if(previousLinesMap.size() == 0) {
  return;
}
 
 
def billTrxTypeId = null;
def origBillTrxTypeId = null;
def refFlineId = null;
 
def lines = header.getAttribute("Lines");
def line = null;
while (lines.hasNext()) {
 
    line = lines.next();
 
    refFlineId = line.getAttribute("ReferenceFulfillmentLineIdentifier");
 
    if (refFlineId != null && previousLinesMap.containsKey(refFlineId)) {
        billTrxTypeId = line.getAttribute("BillingTransactionTypeIdentifier");
        origBillTrxTypeId = previousLinesMap.get(refFlineId);
        if( (billTrxTypeId == null && origBillTrxTypeId == null) || (billTrxTypeId != null && origBillTrxTypeId != null && billTrxTypeId == origBillTrxTypeId)) {
            continue;
        }
        throw new ValidationException("Billing Transaction Type (aka Receivable Transaction Type) can't be updated :: Line#" + line.getAttribute("DisplayLineNumber") + " [ NEW:" + billTrxTypeId + " - OLD:" + origBillTrxTypeId + " ]");
    }
}
     
void IsBillingTrxTypeIdUpdateable(def referenceHeaderId) {
 
    def statusesSet = ["AWAIT_BILLING", "BILLED", "CANCELED", "CLOSED"] as Set;
 
    def vo = context.getViewObject("oracle.apps.scm.doo.publicView.analytics.FulfillLinePVO");
    def vc = vo.createViewCriteria();
    def vcrow = vc.createViewCriteriaRow();
    vcrow.setAttribute("FulfillLineHeaderId", referenceHeaderId);
    rowset = vo.findByViewCriteria(vc, -1);
     
    def line = null;
    def fldItr = null;
    def fld = null;
    while (rowset.hasNext()) {
 
      line = rowset.next();
 
        if (statusesSet.contains(line.getAttribute("FulfillLineStatusCode"))) {
            previousLinesMap.put(line.getAttribute("FulfillLineId"), line.getAttribute("FulfillLineBillingTrxTypeId"));
            continue;
        }
 
        fldItr = line.getAttribute("FulfillLineDetail");
        while(fldItr.hasNext()) {
            fld = fldItr.next();
            if("Invoice".equals(fld.getAttribute("FulfillLineDetailTaskType"))) {
                previousLinesMap.put(line.getAttribute("FulfillLineId"), line.getAttribute("FulfillLineBillingTrxTypeId"));
                break;
            }
        }
    }
}

Set the Default Value for the Payment Term

import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
 
List < Message > messages = new ArrayList < Message > ();
def logger = context.getLogger();
 
//def PName = header.getAttribute("BillToCustomerName");
//def custActId = header.getAttribute("BillToCustomerIdentifier");
//def siteUseId = header.getAttribute("BillToAccountSiteUseIdentifier");
 
def HeaderPayTerm = header.getAttribute("PaymentTermCode");
def lines = header.getAttribute("Lines");
if (!lines.hasNext()){
    throw new ValidationException("More time is needed to process the order");
}
 
while (lines.hasNext()) {
 
    def line = lines.next();
    def custActId = line.getAttribute("BillToCustomerIdentifier");
    def siteUseId = line.getAttribute("BillToAccountSiteUseIdentifier");
    def linePayTerm = line.getAttribute("PaymentTermCode");
    def linetransactioncode = line.getAttribute("TransactionCategoryCode");
 
    //def termId = getBillToPartyIdTermId(PName);
    def termId = getTermID(custActId, siteUseId);
    def termName = gettermName(termId);
    logger.logSevere("Term Name TrxPaymentTermPVO : ", termName);
    if (HeaderPayTerm == null && linePayTerm == null && linetransactioncode != 'RETURN') {
        if (termId != null){
            header.setAttribute("PaymentTerm", termName);
            line.setAttribute("PaymentTerm", termName);
        }
    }
}
 
Object getTermID(Long custActId, Long siteUseId) {
    def termId;
    def logger = context.getLogger();
    def custProfilePVO =
        context.getViewObject("oracle.apps.financials.receivables.publicView.analytics.CustomerFinancialProfilePVO");
    def vc1 = custProfilePVO.createViewCriteria();
    def vcrow1 = vc1.createViewCriteriaRow();
    vcrow1.setAttribute("CustProfileCustAccountId", custActId);
    vcrow1.setAttribute("CustProfileSiteUseId", siteUseId);
    vcrow1.setAttribute("CustProfileStandardTerms", "> -1");
 
    def rowset1 = custProfilePVO.findByViewCriteria(vc1, -1);
    def profile = rowset1.first();
    if (profile != null) {
 
        termId = profile.getAttribute("CustProfileStandardTerms");
        header.setAttribute("ShippingInstructions", "TERM=" + termId);
        logger.logSevere("Term Id from CustomerFinancialProfilesPVO : ", termId);
    }
    else {
        vc1 = custProfilePVO.createViewCriteria();
        vcrow1 = vc1.createViewCriteriaRow();
        vcrow1.setAttribute("CustProfileCustAccountId", custActId);
        vcrow1.setAttribute("CustProfileSiteUseId", "is null");
        vcrow1.setAttribute("CustProfileStandardTerms", "> -1");
         
        rowset1 = custProfilePVO.findByViewCriteria(vc1, -1);
        profile = rowset1.first();
        if (profile != null) {
 
            termId = profile.getAttribute("CustProfileStandardTerms");
            header.setAttribute("ShippingInstructions", "TERM=" + termId);
            logger.logSevere("Term Id from CustomerFinancialProfilesPVO : ", termId);
        }
        else {
            header.setAttribute("ShippingInstructions", termId);
            throw new ValidationException("No Payment Term found for the BillToCustomer 2 :: "+siteUseId);
        }
    }
    return termId;
}
 
Object gettermName(Long termID) {
    def raTermPVO =
        context.getViewObject("oracle.apps.financials.receivables.publicView.TrxPaymentTermPVO");
    def vc2 = raTermPVO.createViewCriteria();
    def vcrow2 = vc2.createViewCriteriaRow();
    vcrow2.setAttribute("TermId", termID);
    def rowset2 = raTermPVO.findByViewCriteria(vc2, -1);
    def termName = rowset2.first();
    def paymentName = termName.getAttribute("Name");
    header.setAttribute("PackingInstructions", paymentName);
    return paymentName;
}

Set the Default Value for the Payment Term Before You Submit the Sales Order

//preSubmit_PAYMENT_TERM_DEFAULTING//
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
 
 
//Return if not a test order based on PO number if
(!"TERMS".equals(header.getAttribute("CustomerPONumber")))
return;
List < Message > messages = new ArrayList <
Message > (); def logger = context.getLogger();
//def PName =
header.getAttribute("BillToCustomerName");
//def custActId = header.getAttribute("BillToCustomerIdentifier");
//def siteUseId =
header.getAttribute("BillToAccountSiteUseIdentifier");
def HeaderPayTerm =
header.getAttribute("PaymentTermCode");
 
def lines = header.getAttribute("Lines"); if
(!lines.hasNext()){ throw new ValidationException("More time is needed to
process the order"); } while (lines.hasNext()) {
def line = lines.next();
 
 
def custActId =
line.getAttribute("BillToCustomerIdentifier");
 
def siteUseId =
line.getAttribute("BillToAccountSiteUseIdentifier");
 
def linePayTerm =
line.getAttribute("PaymentTermCode");
 
def linetransactioncode =
line.getAttribute("TransactionCategoryCode");
 
 
//def termId = getBillToPartyIdTermId(PName);
def termId = getTermID(custActId, siteUseId);
def termName = gettermName(termId);
logger.logSevere("Term Name TrxPaymentTermPVO : ", termName);
if(HeaderPayTerm == null && linePayTerm == null && linetransactioncode !='RETURN') {
 
        if (termId != null){
            header.setAttribute("PaymentTerm", termName);
            line.setAttribute("PaymentTerm", termName);
        }
    }
}
 
Object getTermID(Long custActId, Long siteUseId) { def
termId; def logger = context.getLogger(); def custProfilePVO =
context.getViewObject("oracle.apps.financials.receivables.publicView.analytics.CustomerFinancialProfilesPVO");
 
def vc1 = custProfilePVO.createViewCriteria();
 
def vcrow1 = vc1.createViewCriteriaRow();
vcrow1.setAttribute("CustProfileCustAccountId", custActId);
//vcrow1.setAttribute("CustProfileSiteUseId", siteUseId);
vcrow1.setAttribute("CustProfileStandardTerms", "> -1");
 
//vcrow1.setAttribute("PartyId", partyId); def
rowset1 = custProfilePVO.findByViewCriteria(vc1, -1);
def profile =rowset1.first();
    if (profile != null) {
        termId =profile.getAttribute("CustProfileStandardTerms");
        logger.logSevere("Term Id from CustomerFinancialProfilesPVO: ", termId);
   }
   else throw new ValidationException("No Payment Term found for the BillToCustomer :: "+custActId); return termId; }
 
Object gettermName(Long termID) {
def raTermPVO = context.getViewObject("oracle.apps.financials.receivables.publicView.TrxPaymentTermPVO");
def vc2 = raTermPVO.createViewCriteria(); def vcrow2 =
vc2.createViewCriteriaRow(); vcrow2.setAttribute("TermId", termID);
def rowset2 = raTermPVO.findByViewCriteria(vc2, -1); def termName =
rowset2.first(); def paymentName = termName.getAttribute("Name")
return paymentName;
}

Set the Default Value of the Payment Term According to CustAccountId and Date Range

import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
 
List < Message > messages = new ArrayList < Message > ();
def logger = context.getLogger();
 
//def PName = header.getAttribute("BillToCustomerName");
//def custActId = header.getAttribute("BillToCustomerIdentifier");
//def siteUseId = header.getAttribute("BillToAccountSiteUseIdentifier");
 
def HeaderPayTerm = header.getAttribute("PaymentTermCode");
def lines = header.getAttribute("Lines");
if (!lines.hasNext()) {
 throw new ValidationException("More time is needed to process the order");
 //header.setAttribute("ShippingInstructions","More time is needed to process the order");
}
 
 
while (lines.hasNext()) {
 
 def line = lines.next();
 def custActId = line.getAttribute("BillToCustomerIdentifier");
 def siteUseId = line.getAttribute("BillToAccountSiteUseIdentifier");
 def linePayTerm = line.getAttribute("PaymentTermCode");
 def linetransactioncode = line.getAttribute("TransactionCategoryCode");
 
 //def termId = getBillToPartyIdTermId(PName);
 def termId = getTermID(custActId, siteUseId);
 def termName = gettermName(termId);
 logger.logSevere("Term Name TrxPaymentTermPVO : ", termName);
 if (HeaderPayTerm == null && linePayTerm == null && linetransactioncode != 'RETURN') {
  if (termId != null) {
   header.setAttribute("PaymentTerm", termName);
   line.setAttribute("PaymentTerm", termName);
  }
 }
}
 
 
Object getTermID(Long custActId, Long siteUseId) {
 def termId;
 def logger = context.getLogger();
 def custProfilePVO =
  context.getViewObject("oracle.apps.financials.receivables.publicView.analytics.CustomerPrfilePVO");
  
 java.sql.Date sqlDate = new java.sql.Date((new Date()).getTime());
  
 def vc1 = custProfilePVO.createViewCriteria();
 def vcrow1 = vc1.createViewCriteriaRow();
 vcrow1.setAttribute("CustomerProfileCustAccountId", custActId);
 vcrow1.setAttribute("CustomerProfileSiteUseId", siteUseId);
 vcrow1.setAttribute("CustomerProfileStandardTerms", "> -1");
 vcrow1.setAttribute("CustomerProfileEffectiveEndDate", ">= "+sqlDate);
 vcrow1.setAttribute("CustomerProfileEffectiveStartDate", " <= "+sqlDate);
  
 def rowset1 = custProfilePVO.findByViewCriteria(vc1, -1);
 def profile = rowset1.first();
 if (profile != null) {
 
  termId = profile.getAttribute("CustomerProfileStandardTerms");
  //header.setAttribute("ShippingInstructions", "TERM=" + termId);
  logger.logSevere("Term Id from CustomerFinancialProfilesPVO : ", termId);
 } else {
  vc1 = custProfilePVO.createViewCriteria();
  vcrow1 = vc1.createViewCriteriaRow();
  vcrow1.setAttribute("CustomerProfileCustAccountId", custActId);
  vcrow1.setAttribute("CustomerProfileSiteUseId", "is null");
  vcrow1.setAttribute("CustomerProfileStandardTerms", "> -1");
  vcrow1.setAttribute("CustomerProfileEffectiveEndDate", ">= "+sqlDate);
  vcrow1.setAttribute("CustomerProfileEffectiveStartDate", " <= "+sqlDate); 
 
  rowset1 = custProfilePVO.findByViewCriteria(vc1, -1);
  profile = rowset1.first();
  if (profile != null) {
 
   termId = profile.getAttribute("CustomerProfileStandardTerms");
   //header.setAttribute("ShippingInstructions", "TERM=" + termId);
   logger.logSevere("Term Id from CustomerFinancialProfilesPVO : ", termId);
  } else {
   //header.setAttribute("ShippingInstructions", termId);
   throw new ValidationException("No Payment Term found for the BillToCustomer 2 :: " + siteUseId);
  }
 }
 return termId;
}
 
Object gettermName(Long termID) {
 def raTermPVO =
  context.getViewObject("oracle.apps.financials.receivables.publicView.TrxPaymentTermPVO");
 def vc2 = raTermPVO.createViewCriteria();
 def vcrow2 = vc2.createViewCriteriaRow();
 vcrow2.setAttribute("TermId", termID);
 def rowset2 = raTermPVO.findByViewCriteria(vc2, -1);
 def termName = rowset2.first();
 def paymentName = termName.getAttribute("Name");
 header.setAttribute("PackingInstructions", paymentName);
 return paymentName;
}