Extend Order Headers

Use these code examples to help you create order management extensions that manipulate data on the sales order header.

Many 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 Use Proven Coding Techniques.

To add and delete an attachment on an order header, see Extend Attachments.

Get Pricing Details for Order Header

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 payments = header.getAttribute("OrderTotals");
while (payments.hasNext()) {
    def payment = payments.next();
    messages.add(new Message(Message.MessageType.ERROR, "TotalAmount is " + payment.getAttribute("TotalAmount")));
    messages.add(new Message(Message.MessageType.ERROR, "OrderTotalId is " + payment.getAttribute("OrderTotalId")));
    messages.add(new Message(Message.MessageType.ERROR, "TotalCode is " + payment.getAttribute("TotalCode")));
    messages.add(new Message(Message.MessageType.ERROR, "CurrencyCode is " + payment.getAttribute("CurrencyCode")));
    messages.add(new Message(Message.MessageType.ERROR, "DisplayName is " + payment.getAttribute("DisplayName")));
    messages.add(new Message(Message.MessageType.ERROR, "TotalGroup is " + payment.getAttribute("TotalGroup")));
    messages.add(new Message(Message.MessageType.ERROR, "PrimaryFlag is " + payment.getAttribute("PrimaryFlag")));

    messages.add(new Message(Message.MessageType.ERROR, "EstimatedFlag is " + payment.getAttribute("EstimatedFlag")));
    messages.add(new Message(Message.MessageType.ERROR, "CreatedBy is " + payment.getAttribute("CreatedBy")));


    messages.add(new Message(Message.MessageType.ERROR, "HeaderId is " + payment.getAttribute("HeaderId")));
    messages.add(new Message(Message.MessageType.ERROR, "ObjectVersionNumber is " + payment.getAttribute("ObjectVersionNumber")));


}

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

Set the Billing Transaction Type According to Order Type

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

String orderTypeCode = header.getAttribute("TransactionTypeCode");
def billingTxnTypeId = null;

//Message msg = new Message(Message.MessageType.WARNING, "Order Type: " + orderTypeCode);
//throw new ValidationException(msg);


//Case statement that tests the order type and calls function to get billing transaction type.

switch (orderTypeCode) {
    case ["AUTO RETURN - SHIP", "AUTO RETURN - SHIP", "AUTO RETURN - MXT SHIP", "Mosoi_test"]:
        billingTxnTypeId = getBillingTxnTypeId("MOTO_INVOICE");
        //msg = new Message(Message.MessageType.WARNING, "First Case " + billingTxnTypeId );
        break;
    case ["UnreferencedRMA"]:
        billingTxnTypeId = getBillingTxnTypeId("Invoice");
        //msg = new Message(Message.MessageType.WARNING, "Second Case " + billingTxnTypeId );
        break;
    default:
        billingTxnTypeId = null;
        //msg = new Message(Message.MessageType.WARNING, "Default " + billingTxnTypeId );
        break;
}

//throw new ValidationException(msg);

//update all order lines with the Billing Transaction Type.

def lines = header.getAttribute("Lines"); //get the lines row set
while (lines.hasNext()) { //if there are more order lines
    def line = lines.next();
    line.setAttribute("BillingTransactionTypeIdentifier", billingTxnTypeId);
}


//Function to get Billing Transaction Type

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();

    //Only return Billing Transaction Type for the common set that you must change.

    vcrow.setAttribute("Name", billingTxnTypeName);
    vcrow.setAttribute("SetName", "Common Set");

    //Run the view object query to find a matching row.
    def rowset = txnTypePVO.findByViewCriteriaWithBindVars(vc, 1, new String[0], new Object[0]);

    //See if we have a matching row.
    def row = rowset.first();

    Long txnTypeId = (Long) row.getAttribute("CustTrxTypeSeqId");

    return txnTypeId;
}

Set Payment Term on Order Header

Set the default value to use for the payment term on the order header.

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 HeaderPayTerm = header.getAttribute("PaymentTerm");
def PName = header.getAttribute("BillToCustomerName");
def AId = header.getAttribute("BillToCustomerIdentifier");


def lines = header.getAttribute("Lines");
while (lines.hasNext()) {
    def line = lines.next();
    def linePayTerm = line.getAttribute("PaymentTerm");
    def linetransactioncode = line.getAttribute("TransactionCategoryCode")
    def partyId = getBillToPartyId(PName);
    def termId = gettermID(AId, partyId);
    def termName = gettermName(termId);

    if (HeaderPayTerm == null && linePayTerm == null && linetransactioncode != 'RETURN') {
        if (termName != null)
            header.setAttribute("PaymentTerm", termName.getAttribute("Name"));
    }
}

Object getBillToPartyId(String partyName) {
    def partyId;
    def logger = context.getLogger();
    def custPVO =
        context.getViewObject("oracle.apps.cdm.foundation.parties.publicView.core.PartyPVO");
    def vc = custPVO.createViewCriteria();
    def vcrow = vc.createViewCriteriaRow();
    vcrow.setAttribute("PartyName", partyName);
    def rowset = custPVO.findByViewCriteria(vc, -1);
    def partyIdRowSet = rowset.first();
    if (partyIdRowSet != null)
        partyId = partyIdRowSet.getAttribute("PartyId");
    logger.logSevere("party id for Bill To customer", partyId);
    return partyId;
}


Object gettermID(Long AId, Long partyId) {
    def termId;
    def logger = context.getLogger();
    def custProfilePVO =
        context.getViewObject("oracle.apps.financials.receivables.publicView.analytics.CustomerProfilePVO");
    def vc1 = custProfilePVO.createViewCriteria();
    def vcrow1 = vc1.createViewCriteriaRow();
    vcrow1.setAttribute("CustAcctProfileCustAccountId", AId);
    vcrow1.setAttribute("CustFinProfileSiteUseId", null);
    vcrow1.setAttribute("CustAcctProfilePartyId", partyId);
    def rowset1 = custProfilePVO.findByViewCriteria(vc1, -1);
    def profile = rowset1.first();
    if (profile != null)
        termId = profile.getAttribute("CustProfileStandardTerms");
    logger.logSevere("Term Id from customer profile VO", termId);
    return termId;
}

Object gettermName(Long termID) {
    def raTermPVO =
        ontext.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();
    return termName;
}

Set Extensible Flexfield On Order Header

Set an attribute to the current date and time. Use an extensible flexfield on the order header.

import oracle.apps.scm.doo.common.extensions.ValidationException;
def poNumber = header.getAttribute("CustomerPONumber");
//throw new ValidationException("An order with the Purchase Order Number " + poNumber + " already exists.");

if (poNumber == null || !poNumber.startsWith("SetDateEffAttributeOnSubmit")) return;

Date now = new Date();

//throw new ValidationException("An order with the Purchase Order Number " + now + " already exists.");
def complianceDetails = header.getOrCreateContextRow("ComplianceDetails");

complianceDetails.setAttribute("compliancedatetime", now);

Set Extensible Flexfield Values for Hazardous Items

If the HazardousMaterialFlag attribute equals Y, then set the value for attributes that use extensible flexfields on the order header and order lines.

import oracle.apps.scm.doo.common.extensions.ValidationException;
def poNumber = header.getAttribute("CustomerPONumber");

if (poNumber == null) return;

if (!poNumber.startsWith("SetEFFAttributeOnSave")) return;

def lines = header.getAttribute("Lines");
while (lines.hasNext()) {
    def line = lines.next();
    def inventoryItemId = line.getAttribute("ProductIdentifier");
    def orgId = line.getAttribute("InventoryOrganizationIdentifier");
    def item = getItem(inventoryItemId, orgId);

    String hazardous = item.getAttribute("HazardousMaterialFlag");

    //throw new ValidationException("Item Hazardous Material Flag is    "  + hazardous);

    if ("Y".equals(hazardous)) {
        //get tow for fulfill line context PackShipInstruction
        def packShipInstruction = line.getOrCreateContextRow("PackShipInstruction");
        packShipInstruction.setAttribute("shippinginstruction", "Hazardous Handling Required.");
    }
}


Date now = new Date();

def complianceDetails = header.getOrCreateContextRow("ComplianceDetails");
complianceDetails.setAttribute("compliancedatetime", now);
complianceDetails.setAttribute("compliancereason", "This is a compliance reason.");

Object getItem(Long itemId, Long orgId) {
    def itemPVO = context.getViewObject("oracle.apps.scm.productModel.items.publicView.ItemPVO");
    def vc = itemPVO.createViewCriteria();
    def vcrow = vc.createViewCriteriaRow();
    vcrow.setAttribute("InventoryItemId", itemId);
    vcrow.setAttribute("OrganizationId", orgId);
    vc.add(vcrow);

    def rowset = itemPVO.findByViewCriteriaWithBindVars(vc, -1, new String[0], new String[0]);
    def item = rowset.first();

    return item;

}

Validate That Ship-to Site Belongs to Business Unit on Order Header

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

def VARShipToPartySiteIdentifier = header.getAttribute("ShipToPartySiteIdentifier");
def VARBusinessUnitIdentifier = header.getAttribute("BusinessUnitIdentifier");
def ShipToPartySite = getShipTo(VARShipToPartySiteIdentifier);
def RETShipToSetId = ShipToPartySite.getAttribute("SetId")
def VARBusinesseUnitSetId = 0

//Test each combination of the business unit and assignment set. Use this SQL:
//SELECT haotl.NAME ,
//haotl.organization_id,
//fsa.SET_ID
//FROM fusion.FND_SETID_ASSIGNMENTS fsa,
//fusion.HR_ORGANIZATION_UNITS_F_TL haotl
//WHERE reference_group_name LIKE 'HZ_CUSTOMER_ACCOUNT_SITE'
//AND determinant_value = haotl.organization_id
//AND haotl.NAME LIKE '&Business_Unit_Name%'
//AND haotl.LANGUAGE = USERENV('LANG')

//

if (300000017871360. equals(VARBusinessUnitIdentifier)) {
    VARBusinesseUnitSetId = 300000000002582;
}

if ((VARBusinesseUnitSetId).equals(RETShipToSetId)) {} else {
    //You can modify this validation error to match your business needs. This example includes details about the setIDs.
    Throw new ValidationException("BU Set Id does not match Customer Ship to SET ID - BU Set ID is " + VARBusinesseUnitSetId + " Ship to Set ID is :" + RETShipToSetId)
}

Object getShipTo(Long ShipToSiteId) {
    def ShipToPVO = context.getViewObject("oracle.apps.hed.campusCommunity.shared.shoppingCart.publicModel.view.AccountSitePVO");
    def vc = ShipToPVO.createViewCriteria();
    def vcrow = vc.createViewCriteriaRow();
    vcrow.setAttribute("PartySiteId", ShipToSiteId);
    def rowset = ShipToPVO.findByViewCriteria(vc, -1);
    def ShipTo = rowset.first();
    return ShipTo;
}

Validate Sales Credits for Salesperson from Order Header

Get the sales credit percent, then validate that Order Management allocates a percent greater than x to each salesperson.

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


def poNumber = header.getAttribute("CustomerPONumber");

if (poNumber != null && poNumber.startsWith("PMC TEST")) {
    //def tokens = [EVENT_CODE: "Jason Carrier", EVENT_CRITERIA: "20"];
    //throw new ValidationException("ORA_MANAGE_EXTENSIONS", "DOO_CMN_ETP_INVALID_EVENT_DTLS", tokens);
}


def salesCredits = header.getAttribute("SalesCredits"); //Get the row set for sales credits that are specified on the order header.

while (salesCredits.hasNext()) {
    def salesCredit = salesCredits.next();
    if ("1".equals(salesCredit.getAttribute("SalesCreditTypeCode"))) {
        //we are dealing with revenue percent
        def percent = salesCredit.getAttribute("Percent");

        if (percent < 30) {
            def tokens = [EVENT_CODE: salesCredit.getAttribute("Salesperson"), EVENT_CRITERIA: percent];
            throw new ValidationException("ORA_MANAGE_EXTENSION", "DOO_CMN_ETP_INVALID_EVENT_DTLS", tokens);
        }
    }
}

Prevent Order Management from Deleting the Order Header

import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
def reference = header.getAttribute("ReferenceHeaderId");
if (reference == null)
return;
def lines = header.getAttribute("Lines");

Prevent Duplicate Purchase Order Numbers on Order Header

Prevent Order Management from creating a duplicate of the purchase order number on the order header.

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

String customerPONumber = header.getAttribute("CustomerPONumber");
//If the PO number is empty, then there's nothing to validate.
if (customerPONumber == null) return;

customerPONumber = customerPONumber.toUpperCase();

//get the order number and the buying party id from the order header of the sales order that you're saving.
String buyingPartyIdentifier = header.getAttribute("BuyingPartyIdentifier");
String OrderNumber = header.getAttribute("OrderNumber");

//Use the HeaderPVO to run a query according to customer PO number and the sold to party's ID. 
//Use a view criteria to set the where clause.
def vo = context.getViewObject("oracle.apps.scm.doo.publicView.analytics.HeaderPVO");
def vc = vo.createViewCriteria();
def vcrow = vc.createViewCriteriaRow();
vcrow.setAttribute("CustomerPoNumber", customerPONumber);
vcrow.setAttribute("SoldToPartyId", buyingPartyIdentifier);
vcrow.setAttribute("OrderNumber", " != " + OrderNumber);

vc.add(vcrow);

def rowset = vo.findByViewCriteria(vc, 1);

if (rowset.hasNext()) {
    throw new ValidationException("An order with the Purchase Order Number for this Customer already exists " + customerPONumber + " already Exists");
}
header.setAttribute("CustomerPONumber", customerPONumber);

Get Details for Related Sales Orders

Get details about the relationship between the sales order and other related sales orders, such as the original order of a copied order or a return order.

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

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

List < Message > messages = new ArrayList < Message > ();
messages.add(new Message(Message.MessageType.ERROR, "HeaderId: " + header.getAttribute("HeaderId")));

def docReferences = header.getAttribute("DocumentReferences");

messages.add(new Message(Message.MessageType.ERROR, "Header Doc"));
while (docReferences.hasNext()) {

    def docRef = docReferences.next();
    messages.add(new Message(Message.MessageType.ERROR, "Header Doc Refs"));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalNumber: " + docRef.getAttribute("DocumentAdditionalNumber")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionaldentifier: " + docRef.getAttribute("DocumentAdditionaldentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentIdentifier: " + docRef.getAttribute("DocumentIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalLineNumber: " + docRef.getAttribute("DocumentAdditionalLineNumber")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalLineIdentifier" + docRef.getAttribute("DocumentAdditionalLineIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentLineIdentifier: " + docRef.getAttribute("DocumentLineIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentLineNumber: " + docRef.getAttribute("DocumentLineNumber")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentReferenceType: " + docRef.getAttribute("DocumentReferenceType")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalSubLineNumber: " + docRef.getAttribute("DocumentAdditionalSubLineNumber")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalSubLineIdentifier: " + docRef.getAttribute("DocumentAdditionalSubLineIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentSubLineIdentifier: " + docRef.getAttribute("DocumentSubLineIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentSubLineNumbe: " + docRef.getAttribute("DocumentSubLineNumber")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentNumber: " + docRef.getAttribute("DocumentNumber")));
    messages.add(new Message(Message.MessageType.ERROR, "FulfillLineIdentifier: " + docRef.getAttribute("FulfillLineIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "LineIdentifier: " + docRef.getAttribute("LineIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "OwnerTableId: " + docRef.getAttribute("OwnerTableId")));
    messages.add(new Message(Message.MessageType.ERROR, "OwnerTableName: " + docRef.getAttribute("OwnerTableName")));
    messages.add(new Message(Message.MessageType.ERROR, "TaskType: " + docRef.getAttribute("TaskType")));
    messages.add(new Message(Message.MessageType.ERROR, "DocumentSystemReferenceIdentifier: " + docRef.getAttribute("DocumentSystemReferenceIdentifier")));
    messages.add(new Message(Message.MessageType.ERROR, "HeaderId: " + docRef.getAttribute("HeaderId")));
}

def lines = header.getAttribute("Lines");
messages.add(new Message(Message.MessageType.ERROR, "get lines"));
while (lines.hasNext()) {
    messages.add(new Message(Message.MessageType.ERROR, "A line"));
    def line = lines.next();
    def lineDocReferences = line.getAttribute("DocumentReferences");
    while (lineDocReferences.hasNext()) {
        messages.add(new Message(Message.MessageType.ERROR, "has doc references"));
        def lineDocRef = lineDocReferences.next();
        messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalNumber: " + lineDocRef.getAttribute("DocumentAdditionalNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionaldentifier: " + lineDocRef.getAttribute("DocumentAdditionaldentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentIdentifier: " + lineDocRef.getAttribute("DocumentIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalLineNumber: " + lineDocRef.getAttribute("DocumentAdditionalLineNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalLineIdentifier" + lineDocRef.getAttribute("DocumentAdditionalLineIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentLineIdentifier: " + lineDocRef.getAttribute("DocumentLineIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentLineNumber: " + lineDocRef.getAttribute("DocumentLineNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentReferenceType: " + lineDocRef.getAttribute("DocumentReferenceType")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalSubLineNumber: " + lineDocRef.getAttribute("DocumentAdditionalSubLineNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentAdditionalSubLineIdentifier: " + lineDocRef.getAttribute("DocumentAdditionalSubLineIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentSubLineIdentifier: " + lineDocRef.getAttribute("DocumentSubLineIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentSubLineNumbe: " + lineDocRef.getAttribute("DocumentSubLineNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentNumber: " + lineDocRef.getAttribute("DocumentNumber")));
        messages.add(new Message(Message.MessageType.ERROR, "FulfillLineIdentifier: " + lineDocRef.getAttribute("FulfillLineIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "LineIdentifier: " + lineDocRef.getAttribute("LineIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "OwnerTableId: " + lineDocRef.getAttribute("OwnerTableId")));
        messages.add(new Message(Message.MessageType.ERROR, "OwnerTableName: " + lineDocRef.getAttribute("OwnerTableName")));
        messages.add(new Message(Message.MessageType.ERROR, "TaskType: " + lineDocRef.getAttribute("TaskType")));
        messages.add(new Message(Message.MessageType.ERROR, "DocumentSystemReferenceIdentifier: " + lineDocRef.getAttribute("DocumentSystemReferenceIdentifier")));
        messages.add(new Message(Message.MessageType.ERROR, "HeaderId: " + lineDocRef.getAttribute("HeaderId")));
    }
}

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