Apex trigger for update / insert Term of Delivery record based on Opportunity Product
trigger updateTermOfDelivery on Opportunity (after insert, after update) {
for (Opportunity opp : Trigger.new) {
//delete old record first
List<Term_of_Delivery__c> terms = [SELECT Id FROM Term_of_Delivery__c
WHERE Opportunity__c = :opp.Id];
if (terms.size() > 0) {
delete terms;
}
//get all products from opportunity
List<OpportunityLineitem> products = [SELECT Id, Frequency__c, Quantity, TotalPrice, ServiceDate, Name, UnitPrice
FROM OpportunityLineitem
WHERE OpportunityId = :opp.Id];
List<Term_of_Delivery__c> termsToInsert = new List<Term_of_Delivery__c>();
Integer seq = 1;
//loop the term of delivery based on frequency each product
for (OpportunityLineitem oli : products) {
Decimal freq = 0;
if (oli.Frequency__c != null) {
freq = oli.Frequency__c;
}
if (freq > 0) {
Decimal qtyTod = (oli.Quantity / freq).setScale(0);
//Decimal amountTod = (oli.TotalPrice / freq).setScale(2);
Date baseDate = oli.ServiceDate != null ? oli.ServiceDate : opp.CloseDate;
Decimal tempSumQty = 0;
for (Integer i=1; i<=freq; i++) {
if (i == 1 && seq == 1) {
Term_of_Delivery__c tod = new Term_of_Delivery__c();
tod.Sequence__c = seq;
tod.Opportunity__c = opp.Id;
tod.Date__c = baseDate;
tod.Product__c = oli.Name;
tod.Quantity__c = qtyTod;
tod.Amount__c = (oli.UnitPrice * qtyTod);
tod.Sales_Price__c = oli.UnitPrice;
tod.Sequence_Per_Product__c = i;
tod.Frequency_Per_Product__c = freq;
tod.Total_Qty_Per_Product__c = oli.Quantity;
termsToInsert.add(tod);
}
else if (i != freq) {
Term_of_Delivery__c tod = new Term_of_Delivery__c();
tod.Sequence__c = seq;
tod.Opportunity__c = opp.Id;
tod.Date__c = baseDate.addMonths(seq-1);
tod.Product__c = oli.Name;
tod.Quantity__c = qtyTod;
tod.Amount__c = (oli.UnitPrice * qtyTod);
tod.Sales_Price__c = oli.UnitPrice;
tod.Sequence_Per_Product__c = i;
tod.Frequency_Per_Product__c = freq;
tod.Total_Qty_Per_Product__c = oli.Quantity;
termsToInsert.add(tod);
}
else {
Term_of_Delivery__c tod = new Term_of_Delivery__c();
tod.Sequence__c = seq;
tod.Opportunity__c = opp.Id;
tod.Date__c = baseDate.addMonths(seq-1);
tod.Product__c = oli.Name;
tod.Quantity__c = (oli.Quantity - tempSumQty);
tod.Amount__c = (oli.UnitPrice * (oli.Quantity - tempSumQty));
tod.Last_Sequence__c = true;
tod.Sales_Price__c = oli.UnitPrice;
tod.Sequence_Per_Product__c = i;
tod.Frequency_Per_Product__c = freq;
tod.Total_Qty_Per_Product__c = oli.Quantity;
termsToInsert.add(tod);
}
tempSumQty += qtyTod;
seq++;
}
}
}
insert termsToInsert;
}
}