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;
//get the customer PO number, order number, and the buying party id from the order header of the sales order you're saving.
String customerPONumber = header.getAttribute("CustomerPONumber");
String buyingPartyIdentifier = header.getAttribute("BuyingPartyIdentifier");
String OrderNumber = header.getAttribute("OrderNumber");

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

//Convert the PO number to upper case.
customerPONumber = customerPONumber.toUpperCase()
//Use the HeaderPVO to run a query according to customer PO number and sold to party's ID. 
//Use a view criteria to set 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);
vc.add(vcrow);

//Use a view criteria to find one row. Even if we find one row, we know that we already have an order with the same PO number and bill to site ID
def rowset = vo.findByViewCriteria(vc, 1);

if (rowset.hasNext()) {
    //We found a sales order for the bill to site and the order number.
    //Now test to see if we alrady saved this sales order or if this is a revision.
    def vcSameOrder = vo.createViewCriteria();
    def vcSameOrderrow = vc.createViewCriteriaRow();
    vcSameOrderrow.setAttribute("CustomerPoNumber", customerPONumber);
    vcSameOrderrow.setAttribute("SoldToPartyId", buyingPartyIdentifier);
    vcSameOrderrow.setAttribute("OrderNumber", OrderNumber);
    vcSameOrder.add(vcSameOrderrow);
    def rowsetSameOrder = vo.findByViewCriteria(vcSameOrder, 1);
    if (rowsetSameOrder.hasNext()) {
    //We found a sales order that has the same order number and PO number as the order that we're already working on. this is a valid case. The order found is a revision or a previously saved order.
        header.setAttribute("CustomerPONumber", customerPONumber);
    } else
    //We found a different sales order for a different order number.
    //Convert the customerPO number to upper case.
    {
        throw new ValidationException("An order with the Purchase Order Number for this Customer already exists " + customerPONumber + " already Exists");
    }
} else
//We didn't find a sales order that has the same the bill to site id and po number, so we can save it.
//Covert the customerPO number to upper case.
{
    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;