Thursday, May 17, 2012

Salesforce - Apex Primitive Data Type for currency fields

The following apex code from another developer (outside my current employer thankfully) was a bit puzzling when I first encountered it:

public OpportunityLineItem workingUnitPrice {set; get;}

// ...

public FooBar() {
    workingUnitPrice = new OpportunityLineItem();
}

// Later, in method bodies etc...

workingUnitPrice.UnitPrice = 1.23;

An instance of OpportunityLineItem was created for the property in the constructor and then only the UnitPrice property was ever assigned to and bound from pages. I believe the intention here was to use a field of type currency.

According to the Currency Field Type docs:

Currency fields contain currency values, such as the ExpectedRevenue field in a Campaign, and are defined as type double.

But under Primitive Data Types - Decimal:

A number that includes a decimal point. Decimal is an arbitrary precision number. Currency fields are automatically assigned the type Decimal.

I've gone with the later and set the scale to 2 on a decimal.

private decimal internalWorkingUnitPrice;
public decimal workingUnitPrice {
 get {
  return internalWorkingUnitPrice;
 }
 set {
  if(value!= null) {
    // Set Scale to match currency
    internalWorkingUnitPrice = value.setScale(2, System.RoundingMode.HALF_UP);
  } else {
    internalWorkingUnitPrice = value;
  }
 }
}

Any related page reference needed to be switched from inputField to inputText or Salesforce gives the error:

Could not resolve the entity from  value binding '{!fooBar.workingUnitPrice}'.
 can only be used with SObject fields.

See also: