Determining the Object Type of a Row

When writing a global helper function, you may find it useful to accept a business object data row as an argument.

Inside your function, if you need to determine the object type of the row passed in, use the objectName() function.

For example, this might be useful if you need to create a new row of the same type as the row passed in, copying selected data from the existing row.

// Global Function:
// ---------------
//    Object duplicateRow(existingRow Object, 
//                        fieldNamesToCopy List)

// Find the name of the object for the existingRow
def rowObjectName = objectName(existingRow)

// In order to create a new row of the same type, we
// need a new view object for the right business object
// whose name we just determined above.
def vo = newView(rowObjectName)

// Setup a map to hold any attribute names whose values
// we want to copy from the existing ro
def attrs = [:]

// If any fieldNamesToCopy were specified, prepare a 
// map containing the field names and values from the
// existing row to use while creating the new row.
// Groovy elegantly handles the case where the 
// fieldNamesToCopy might is null, keep code simple.
for (fieldName in fieldNamesToCopy)
{
   attrs[fieldName] = existingRow[fieldName]
}

// Now create and return a new row using that view object
// passing in the map of fields whose values we've been
// asked to copy from the existing row.
return vo.createAndInitRowFromMap(attrs)

Once you define the duplicateRow() global function, you can use it anywhere in your application where you need to duplicate an existing row, optionally copying along one or more attributes from an existing row. For example, as shown below, you can write the code in a Before Update trigger on an Order_c custom object that duplicates the existing Order_c object, copying just the fields CustomerId_c and PrimaryShippingAddress_c into the newly-created order:

// Before Update trigger on Order_c
// Call an object function to determine any backordered items
def backorderedItems = determineBackorderedItems()
if (backorderedItems)
{
   // Use adf.source to pass this current Order_c object
   def newOrder = adf.util.duplicateRow(adf.source,
                                        ['CustomerId_c',
                                         'PrimaryShippingAddress_c'])
   // Call an object function to add backordered items
   // to the newly-created order.
   newOrder.addItems(backorderedItems)
   // Call an object function to remove backordered items
   // from the current order
   removeItems(backorderedItems)
}

Of course, you can also pass any other Order_c row as the first argument. In the example below, we've used a queryRow() global helper function to find the current customer's most recent shipped order that contains a specific product id, and pass that order if found to the duplicateRow() function.

// Assume custId variable holds current customer id
//    and prodId variable holds current product id
def recentOrder = adf.util.queryRow(
                     select: 'CustomerId_c,PrimaryShippingAddress_c',
                       from: 'Order_c',
                      where: """
                        CustomerId_c = :CurCust
                    and OrderStatus_c = 'SHIPPED'
                    and OrderLinesCollection_c.ProductId_c = :CurProd
                             """,
                    orderBy: 'OrderDate_c desc',
                      binds: [CurCust: custId, CurProd: prodId])
if (recentOrder) {
   // Pass the recent order we found above into duplicateRow()
   def newOrder = adf.util.duplicateRow(recentOrder,
                                        ['CustomerId_c',
                                         'PrimaryShippingAddress_c'])
   // etc.  
}