function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
chubsubchubsub 

Moving trigger logic into an apex class

Is there a way to move trigger logic into an apex class?  I want to add a few lines into a current trigger that references an apex class that does the logic.  I'm running into trouble when trying to replicate the trigger in a class, mainly when I get to the Trigger.new method, can this be called into an apex class, as well as the Trigger.oldmap?

 

Here is the logic in the trigger, which works fine, it creates a record into a related list if a field changes.

 

Any advise?  Will the logic be possible to put into a class and how would I use the trigger.oldmap and Trigger.New methods?

 

Below is the trigger and then below this is the class I am trying to move it too:

 

trigger FieldChangeTrigger on QuoteLineItem (after update) {

 

List <QLI_History_Tracking__c> history = new List <QLI_History_Tracking__c>();

for (QuoteLineItem qli : Trigger.new) {

if(qli.UnitPrice != Null && qli.UnitPrice != trigger.oldMap.get(qli.Id).UnitPrice)
{
history.add(new QLI_History_Tracking__c (
Quote_Line_Item__c = qli.Id,
Sales_Price_From__c = trigger.oldMap.get(qli.Id).UnitPrice,
Sales_Price_To__c = qli.UnitPrice
));
}

if(history.size() >0)
{
insert history;
}

}

 

 

 

Here is what I will be changing the trigger into:

 


trigger FieldChangeTrigger on QuoteLineItem (after update) {

//need to copy all relevant fields so they will always pick up previous values when one is changed
//object wil be called pricing history

if(Trigger.isUpdate && Trigger.isAfter){

managePricingHistory.afterupdate(Trigger.New);

}

 

 

 

An then the above trigger will reference this class

 

public with sharing class managePricingHistory {


public static list<QuoteLineItem> afterUpdate(list<QuoteLineItem> qli) {

List <QLI_History_Tracking__c> history = new List <QLI_History_Tracking__c>();

 

for (QuoteLineItem qlit : Trigger.new) {  

// I'm getting an error message here that says "Loop variable must be of type SObject


}

if(history.size() >0)
{
insert history;
}

return qli;
}

}

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Andy BoettcherAndy Boettcher

oldMap and newMap are just Maps - you can define two Maps (Map<Id, YourObject> in your destination class and just set those new variables to be oldMap and newMap.

 

<Destination Class>

Map<Id, Account> mapNew = new Map<Id,Account>();

Map<Id, Account> mapOld = new Map<Id, Account>();

 

<trigger>

destinationClass clsDest = new destinationClass();

clsDest.mapNew = trigger.newMap

clsDest.mapOld = trigger.oldMap

 

-Andy

All Answers

salesforce expertsalesforce expert

that is good practice to separate the code from trigger. things will be manageable if you create class and methods!

 

 

public with sharing class managePricingHistory {

 

public List<QuoteLineItem> QLI {get; set;}

 

public void managePricingHistory (List<QuoteLineItem> Quote1) {

  QLI = Quote1;

}

 

public static list<QuoteLineItem> afterUpdate(list<QuoteLineItem> qli) {

List <QLI_History_Tracking__c> history = new List <QLI_History_Tracking__c>();

 

for (QuoteLineItem qlit : QLI) {  

// I'm getting an error message here that says "Loop variable must be of type SObject


}

if(history.size() >0)
{
insert history;
}

return qli;
}

}

 

let me know if this helps you! otherwise i will try to give my working model!

 

 

 

-baskaran

chubsubchubsub

Thanks SF expert, I added your code and it didn't produce errors at first, then when I added these lines, I get the following error message:  Initial term of field expression must be a concrete SObject: List <QuoteLineItem>

 

Any way to add this kind of logic into the class? 

 

if(qli.UnitPrice != Null && qli.UnitPrice != trigger.oldMap.get(qli.Id).UnitPrice)
{
history.add(new QLI_History_Tracking__c (
Quote_Line_Item__c = qli.Id,
Sales_Price_From__c = trigger.oldMap.get(qli.Id).UnitPrice,
Sales_Price_To__c = qli.UnitPrice
));

Vinod TomarVinod Tomar

I am also facing the same issue. Can anybody please help us?

chubsubchubsub

Vinod, I don't think it's possible to move the oldMap, newMap logic into a class judging from this post written a few months ago:

 

http://boards.developerforce.com/t5/Apex-Code-Development/oldMap-and-newMap-in-Class/m-p/337247#M59751

 

 

Andy BoettcherAndy Boettcher

oldMap and newMap are just Maps - you can define two Maps (Map<Id, YourObject> in your destination class and just set those new variables to be oldMap and newMap.

 

<Destination Class>

Map<Id, Account> mapNew = new Map<Id,Account>();

Map<Id, Account> mapOld = new Map<Id, Account>();

 

<trigger>

destinationClass clsDest = new destinationClass();

clsDest.mapNew = trigger.newMap

clsDest.mapOld = trigger.oldMap

 

-Andy

This was selected as the best answer