ShowAll Questionssorted byDate Posted
MohanaGopal

# Roundig Decimal Problem

Hi..

I got this from

Code:
```decimal tax=0;
public decimal getTax()
{
return tax.divide(1,2,system.roundingmode.up);
}```

If tax value is 12.232343 then

I got a answer 12.23 (That is I  need )

But if tax value is 0 then

I have to display 0.00 in a PDF instead of  0.0

How to achieve this....

JimRae

You can do both in one trigger using the trigger variables "isInsert" and "isUpdate".

Something like this (untested):

trigger Product_Before_Insert_Update on Product2 (after insert, after update) { sObject s = [select ID from Pricebook2 where IsStandard = TRUE]; List<pricebookentry> newPBEs = new List<pricebookentry>(); //hold all new PBEs and insert in one statement Set<ID> currProdIDs = new Set<ID>(); //hold all of the product ids so you can search for existing PBEs Map<ID,double> newunitPrice = new Map<ID,double>(); //This will hold the new unit price to update the PBE for (Product2 newProduct: Trigger.new) { if(Trigger.isInsert){ double unitPrice = ((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5; newPBEs.add(new PricebookEntry(Pricebook2Id=s.ID,Product2Id=newProduct.ID, UnitPrice=unitprice, IsActive=TRUE, UseStandardPrice=FALSE)); } if(Trigger.isUpdate){ currProdIDs.add(newProduct.ID); newunitPrice.put(newProduct.ID,((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5); } } try{ insert newPBEs; }catch(DMLException d){ system.assert('\n\nERROR Inserting new PBEs:'+d.getDMLMessage(0)); } //find all of the current PBE's to update List<pricebookentry> updPBEs = new List<pricebookentry>([select id,product2ID,unitPrice,pricebook2id from pricebookentry where pricebook2id=:s.id and product2id in:currProdIDs]); for(pricebookentry pbe:updPBEs){ pbe.unitprice=newunitPrice.get(pbe.product2ID); } try{ update updPBEs; }catch(DMLException d1){ system.assert('\n\nERROR Updating PBEs:'+d1.getDMLMessage(0)); } }

JimRae

Code:
```decimal tax=0.00;
public decimal getTax()
{
return tax.divide(1,2,system.roundingmode.up)>0 ? tax.divide(1,2,system.roundingmode.up) : decimal.valueOf(0.00).setScale(2);
}
system.debug('\n\n'+getTax());```

MohanaGopal
Hi.. Jim..

Still I am not gettting correct output when I use ur code...

Even I try this code.. Its also return 0.0

Code:
```public decimal getTax()
{
return decimal.valueOf(0.00).setScale(2);
}
```

Thanks for ur reply once again....

iceberg4u
Actually we had the same problem.We needed 0.00 values so to do that we had to use Strings.Couldnt find any other way.
bikla78

Do you know how I can round this result to the nearest \$5.00

`double unitPrice = newProduct.payrate__c / .90 * 2.5 + 5;`
so if payrAte was \$50.00,

(50 / .90) * 2.5 + 5  =   \$143.8

final result  = \$140.00

JimRae

double unitPrice = ((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5;

if you wanted to do the nearest 10, you would divide by 10 round and then multiply by 10.

bikla78

Jim,

It worked as plan. Also, do you know how I could include logic in here so the trigger would fire on an update as well? I am trying to auto-insert a pricebookentry record when a product record is created and auto-calculated the pricebookentry.unitprice from the product2.payrate__c....i get an error when i try to update it

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, This price definition already exists in this price book: Trigger.Product_Before_Insert_Update: line 12, column 1

`trigger Product_Before_Insert_Update on Product2 (after insert, after update) {sObject s = [select ID from Pricebook2 where IsStandard = TRUE];for (Product2 newProduct: Trigger.new) {double unitPrice = ((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5;PricebookEntry z = new PricebookEntry(Pricebook2Id=s.ID,Product2Id=newProduct.ID, UnitPrice=unitprice, IsActive=TRUE, UseStandardPrice=FALSE);insert z;}}`

JimRae

I don't think you want to insert a new PBE on an update, the PBE would already exist, you might want to update the price, if there was a change.

Message Edited by JimRae on 10-02-2009 09:43 AM
bikla78
Do I have to create seperate update trigger that performs this logic or is there a way to build the logic into this trigger.
JimRae

You can do both in one trigger using the trigger variables "isInsert" and "isUpdate".

Something like this (untested):

trigger Product_Before_Insert_Update on Product2 (after insert, after update) { sObject s = [select ID from Pricebook2 where IsStandard = TRUE]; List<pricebookentry> newPBEs = new List<pricebookentry>(); //hold all new PBEs and insert in one statement Set<ID> currProdIDs = new Set<ID>(); //hold all of the product ids so you can search for existing PBEs Map<ID,double> newunitPrice = new Map<ID,double>(); //This will hold the new unit price to update the PBE for (Product2 newProduct: Trigger.new) { if(Trigger.isInsert){ double unitPrice = ((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5; newPBEs.add(new PricebookEntry(Pricebook2Id=s.ID,Product2Id=newProduct.ID, UnitPrice=unitprice, IsActive=TRUE, UseStandardPrice=FALSE)); } if(Trigger.isUpdate){ currProdIDs.add(newProduct.ID); newunitPrice.put(newProduct.ID,((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5); } } try{ insert newPBEs; }catch(DMLException d){ system.assert('\n\nERROR Inserting new PBEs:'+d.getDMLMessage(0)); } //find all of the current PBE's to update List<pricebookentry> updPBEs = new List<pricebookentry>([select id,product2ID,unitPrice,pricebook2id from pricebookentry where pricebook2id=:s.id and product2id in:currProdIDs]); for(pricebookentry pbe:updPBEs){ pbe.unitprice=newunitPrice.get(pbe.product2ID); } try{ update updPBEs; }catch(DMLException d1){ system.assert('\n\nERROR Updating PBEs:'+d1.getDMLMessage(0)); } }

This was selected as the best answer
bikla78

Hi Jim,

Hw can I get this formula to always round up.

double unitPrice = ((newProduct.payrate__c / .90 * 2.5 + 5)/5).round()*5;

for example

newProduct.payrate__c = \$40.00

40/.90 *2.5 + 5 =  \$116.1 , after rounding up it would be \$120.00. The system is round down and showing \$115.00

JimRae

If you can use a decimal instead of a double, you can specify your own rounding mode.

Decimal payrate = 40; Decimal unitPrice = ((payrate / .90 * 2.5 + 5).divide(5,0,System.RoundingMode.UP))*5; system.debug('\n\nUNIT PRICE = '+unitPrice);

In this example, I am taking the payrate (you had as a field), dividing it by .90 multiplying by 2.5 and adding 5.

I am taking the result of this and dividing it by 5, with 0 decimal places and rounding up.  Then I take the result and multiply that by 5.

the result for this example is 120.

You can read more about the diference between decimal and double, as well as about the rounding mode in the Apex developers guide.

bikla78

Jim,

I can see your dividing the result by 5 in this function but how did you come up with the 5? Couldn;t you also use 6, 7, 8 etc..and mutiply it by the same number?Also what does the 0 mean in this roundingup function.

I looked in the  APEX documentation but it doesn't explain the parameters clearly

divide(5,0,System.RoundingMode.UP))

Message Edited by bikla78 on 10-13-2009 02:40 PM
JimRae

The 5 allows you to round to the nearest 5, if you used 6 it would be a multiple of 6, etc.

The 0 in  the divide method means scale of zero (zero decimal places).

The ceiling mode you asked about works similar to up, except it moves to the next interval away from zero.  So for a positive number, it works identically to UP, for a negative number it is the opposite of UP.

for example:

2.1 UP = 3

2.1 CEILING = 3

-2.1 UP = -2

-2.1 CEILING = -3

bikla78
Got it. Thank you Jim