Reputation: 33
I have the following use case and have trouble to write a correct trigger for it
On object Account we save our patients. Every patient has a connected general practitioner (GP). The general practitioners are saved in object Contact. Sometimes a GP is retiring, a new GP takes over the general practice so al connected patients to that GP must change to the new GP.
I made in Salesforce in object Contact 2 fields, GPChange__c (boolean) and NewGP__c (lookup field on contact). When a user set the boolean field to true and fill in the new GP, the Apex trigger must be run and collect all accounts(patients) connected to the 'retired' GP and update the field GeneralPracticioner__c on account with the id from NewGP__C.
This is how far i come, it will run and collect, but doesn't update the field. Can anyone plz help me?
trigger trgnewGP on Contact (before update) {
for (Contact mycontact : Trigger.new) {
if (mycontact.GPChange__c = true && mycontact.NewGP__c != null){
list <account> gps = [SELECT GeneralPracticioner__c from account
where GeneralPracticioner__c =: mycontact.id];
for(Account acc : gps){
if (gps.size() > 0) {
acc.GeneralPracticioner__c = mycontact.NewGP__c;
} }
}
}
}
Upvotes: 1
Views: 9823
Reputation: 1405
There are some issues in that code:
if (mycontact.GPChange__c = true ...
- Beware: you are assigning true
to GPChange__c
. Keep in mind that there is no need to write checkboxField == true
, it already resolves to a Boolean.In order to pull out the query, you need to collect the Id of the retired GP.
Then you can retrieve the account records that need to be updated and set GeneralPracticioner__c
using Trigger.NewMap.
trigger trgnewGP on Contact (before update) {
List<Id> retiredGpIds = new List<Id>();
for (Contact gp : Trigger.new) {
if (gp.GPChange__c && gp.NewGP__c != null) {
retiredGpIds.add(gp.Id);
}
}
if (!retiredGpIds.isEmpty()) {
List<Account> patients = [SELECT GeneralPracticioner__c from Account WHERE GeneralPracticioner__c IN :retiredGpIds];
for (Account acc : patients) {
acc.GeneralPracticioner__c = Trigger.NewMap.get(acc.GeneralPracticioner__c).NewGP__c;
}
update patients;
}
}
Since there are no update to Contact records, I would run this trigger in after update
.
Update:
The weird thing, when i try to use Dataloader [...] it works perfect and doesn't have any apex CPU errors.
Dataloader uses bulk api, which run in asynchronous context, therefore they have higher CPU Limit: 60s vs 10s.
I would suggest to extract the logic of that trigger in a future
method in a trigger handler class.
It should look like:
@future
public static void updateGeneralPracticioner(List<Id> retiredGpIds) {
Map<Id, Contact> gpMap = new Map<Id, Contact>([SELECT Id, NewGP__c FROM Contact WHERE Id IN :retiredGpIds);
List<Account> patients = [SELECT GeneralPracticioner__c from Account WHERE GeneralPracticioner__c IN :retiredGpIds];
for (Account acc : patients) {
acc.GeneralPracticioner__c = gpMap.get(acc.GeneralPracticioner__c).NewGP__c;
}
update patients;
}
The trigger:
trigger trgnewGP on Contact (after update) {
List<Id> retiredGpIds = new List<Id>();
for (Contact gp : Trigger.new) {
if (gp.GPChange__c && gp.NewGP__c != null) {
retiredGpIds.add(gp.Id);
}
}
if (!retiredGpIds.isEmpty()) {
ContactTriggerHandler.updateGeneralPracticioner(retiredGpIds);
}
}
Upvotes: 2
Reputation: 33
@RubenDG
The script does the job, very nice. But when the are more results >~100 records, I get a APEX CPU time limit. There are also other processes on object account, but not heavy ones. Disabled for the test some other WF rules or processes related to Account, but still get the CPU limit. I think the max updated patients never exceed more then 1500... In other words. No general practitioner has more then 1500 patients. So that isn't a lot.
The weird thing, when i try to use Dataloader or Workbench and do an update(1200 records) on field GeneralPracticioner__c on Account, it works perfect and doesn't have any apex CPU errors.
What would you advice. Write a handler class that is async? Of make the trigger asyc(is that even possible?)
Upvotes: 1