![SFDC Ninja](/img/default-banner.jpg)
- Видео 75
- Просмотров 470 471
SFDC Ninja
Добавлен 4 дек 2022
Apex Triggers - 61 (NTT Data Interview Scenario)
Apex Triggers - 61 (NTT Data Interview Scenario)
Просмотров: 261
Видео
Apex Triggers - 60 (Trigger Interview Scenario)
Просмотров 607День назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 59 (Infosys Interview Scenario)
Просмотров 1,3 тыс.Месяц назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 58 (Trigger Interview Scenario)
Просмотров 1,4 тыс.Месяц назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 57 (Trigger Interview Scenario)
Просмотров 1 тыс.Месяц назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 56 (Trigger Interview Scenario)
Просмотров 1,2 тыс.2 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 55 (Trigger Interview Scenario)
Просмотров 1,3 тыс.2 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 54 (Infosys Interview Scenario)
Просмотров 2,1 тыс.3 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 53 (Trigger Interview Scenario)
Просмотров 1,9 тыс.3 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 52 (IBM Interview Scenario)
Просмотров 2 тыс.3 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 51 (NTT Data Interview Scenario)
Просмотров 2,6 тыс.4 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 50 (NTT Data Interview Scenario)
Просмотров 2,2 тыс.4 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 49 (Trigger Interview Scenario)
Просмотров 1,6 тыс.4 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Apex Triggers - 48 (Trigger Interview Scenario)
Просмотров 1,8 тыс.4 месяца назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Salesforce Queueable Apex Interview Questions
Просмотров 2 тыс.5 месяцев назад
Revolutionize your Salesforce experience with Titan's powerful products Create and automate custom document templates directly from Salesforce - titandxp.com/pricing/titan-docs/ Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/pricing/titan-sign/ Create, automate, and track custom web forms directly from Salesforce - titandxp.com/pricing/titan-forms/...
Salesforce Future Apex Interview Questions
Просмотров 2,1 тыс.5 месяцев назад
Salesforce Future Apex Interview Questions
Salesforce Batch Apex Interview Questions
Просмотров 6 тыс.5 месяцев назад
Salesforce Batch Apex Interview Questions
Apex Triggers - 47 (Accenture Interview Scenario)
Просмотров 7 тыс.6 месяцев назад
Apex Triggers - 47 (Accenture Interview Scenario)
Apex Triggers - 46 (Deloitte Interview Scenario)
Просмотров 6 тыс.7 месяцев назад
Apex Triggers - 46 (Deloitte Interview Scenario)
Apex Triggers - 45 (Infosys Interview Scenario)
Просмотров 4,9 тыс.7 месяцев назад
Apex Triggers - 45 (Infosys Interview Scenario)
Apex Triggers - 44 (EY Interview Scenario)
Просмотров 3,9 тыс.7 месяцев назад
Apex Triggers - 44 (EY Interview Scenario)
Apex Triggers - 43 (Infosys Interview Scenario)
Просмотров 3,9 тыс.7 месяцев назад
Apex Triggers - 43 (Infosys Interview Scenario)
Apex Triggers - 42 (Trigger Interview Question)
Просмотров 1,9 тыс.7 месяцев назад
Apex Triggers - 42 (Trigger Interview Question)
Apex Triggers - 41 (Trigger Interview Question)
Просмотров 2,4 тыс.8 месяцев назад
Apex Triggers - 41 (Trigger Interview Question)
LWC Scenario - 4 (Search Functionality in Lightning Datatable)
Просмотров 1,3 тыс.9 месяцев назад
LWC Scenario - 4 (Search Functionality in Lightning Datatable)
LWC Scenario - 3 (Lightning Record Picker)
Просмотров 1,3 тыс.10 месяцев назад
LWC Scenario - 3 (Lightning Record Picker)
LWC Scenario - 2 (Server Side Sorting in Lightning Datatable)
Просмотров 1,2 тыс.10 месяцев назад
LWC Scenario - 2 (Server Side Sorting in Lightning Datatable)
LWC Scenario - 1 (Client Side Sorting in Lightning Datatable)
Просмотров 3,9 тыс.10 месяцев назад
LWC Scenario - 1 (Client Side Sorting in Lightning Datatable)
Apex Test Class - 5 (Testing Wrapper Class)
Просмотров 1,1 тыс.11 месяцев назад
Apex Test Class - 5 (Testing Wrapper Class)
Nice explanation
Curious ..do you like practice the scenario before hand before creating video out of it ?
Great video but the solution is wrong. It will not handle the case when multiple managers are associated to the same team. Also it is a bad practice to use picklist values as a key for a map. The key should also be a unique field like ID or Name.
Scenario: Whenever the Opportunity field "Type" gets updated then check the Opportunity's Account - if there is a Contact present with the same "Type" value as the Opportunity, then insert a new OpportunityContactRole and delete the existing OpportunityContactRole (for that Opportunity). In the Opportunity's Account - if there is no Contact present with the same "Type" value as the Opportunity then throw an error . Trigger OppTrigger on Opportunity(After Update ){ TriggerHandler.updateMethod(Trigger.new, Trigger.oldMap ); } public class TriggerHandler{ public static void updateMethod(List<Opportunity> oppList, Map<Id, Opportunity > oldMap ){ Map<Id, Opportunity> accIdVsOpp = new Map<Id, Opportunity>(); Set<Id> oppIds = new Set<Id>(); for(Opportunity opp : oppList ){ if(oldMap != null && opp.Type__c != null && oldMap.get(opp.Id).Type__c != opp.Type__c && opp.AccountId != null){ accIdVsOpp.put(opp.AccountId, opp); oppIds.add(opp.Id); } } Map<Id, Contact> oppIdVsCon = new Map<Id, Contact>(); if(!accIdVsOpp.isEmpty() ){ for(Contact con : [Select Id, Type__c From Contact Where AccountId In: accIdVsOpp.keyset() ]){ if(con.Type__c == accIdVsOpp.get(con.AccountId).Type ){ oppIdVsCon.put(accIdVsOpp.get(con.AccountId).Id, con ); } } } List<OpportunityContactRole> ocrListToInsert = new List<OpportunityContactRole>(); if(!oppIdVsCon.isEmpty() ){ for(Opportunity opp : oppList){ if(oppIdVsCon.containsKey(opp.Id) ){ //insert new OpportunityContactRole OpportunityContactRole ocr = new OpportunityContactRole(); ocr.ContactId = oppIdVsCon.get(opp.Id).Id; ocr.OpportunityId = opp.Id; ocrListToInsert.add(ocr); }else{ //show error opp.addError('There is no contact present with the type '+ opp.Type+'.') ; } } } if(ocrListToInsert.size() > 0 ){ List<OpportunityContactRole> ocrListExisting = [Select Id From OpportunityContactRole Where OpportunityId In: oppIds] ; delete ocrListExisting; insert ocrListToInsert; } } } Here is my code snippet of the problem. The question scenario was a bit tricky for me to understand so I have slightly modified the verbiage to make it a bit more simpler.
Thankyou for the great Videos, Very helpful🙌 Here is my Code (works for Bulk inserts and potentially reduces the number of iterations since i tried to take Distinct combinations of Team__c and ManagerId) public class UserManagerAssign { public void UserManagerAssignMethod(List<User> newUserList){ Set<String> teamName = new Set<String>(); Set<Id> userIds = new Set<Id>(); for(User u : newUserList){ if(u.Team__c!=null && u.Assign_Manager__c==true){ teamName.add(u.Team__c); a userIds.add(u.Id); } } List<AggregateResult> userManagerList = [Select ManagerID mngr,Team__c team ,count(Id) from User where Team__c in :teamName and ManagerId!=null group by ManagerId,Team__c]; Map<String,Id> managerTeamMap = new Map<String,Id>(); for(AggregateResult agg : userManagerList){ if(!managerTeamMap.containskey((String)agg.get('team'))){ managerTeamMap.put((String)agg.get('team'),(Id)agg.get('mngr')); } } for(User u : newUserList){ if(u.Team__c!=null && u.Assign_Manager__c==true){ if(managerTeamMap.containsKey(u.Team__c)){ u.ManagerId = managerTeamMap.get(u.Team__c); } else{ u.addError('No Manager present for this team'); } } } } }
how you calculate the last_stage_change ? why you didnt show that ?
I am directly creating the task records inside my contact for-loop, there is no need for iterating over the case list twice. Here is my code snippet : trigger CaseTrigger on Case(After Update){ TriggerHandler.updateMethod(trigger.new, trigger.oldMap ); } public class TriggerHandler{ public static void updateMethod(List<Case> caseList , Map<Id, Case> oldMap ){ Map<Id, Case> accIdVsCase = new Map<Id, Case>(); for(Case cs : caseList ){ Case oldCase = oldMap.get(cs.Id); if(oldCase.Escalation_Required__c != cs.Escalation_Required__c && cs.Escalation_Required__c && cs.AccountId != null){ accIdVsCase.put(cs.AccountId, cs); } } List<Task> taskList = new List<Task>(); if(!accIdVsCase.isEmpty() ){ for(Contact con : [Select Id, Primary_Contact__c From Contact Where AccountId In: accIdVsCase.keyset() And Primary_Contact__c = True]){ Task t = new Task(); t.Subject = 'Follow up task'; t.WhoId = con.Id; t.Status = 'Not Started'; t.Priority = 'High'; t.Description = 'follow up task created '+ system.now(); taskList.add(t); } } if(taskList.size() > 0 ){ insert taskList; } } }
Here is Another Approach (No nested Loop, Dynamic Comparison ) public class ContactTypeValidation { public void ContactTypeValidationMethod(List<Contact> newConList, Map<Id,Contact> oldConMap){ Set<id> accId = new Set<Id>(); for(Contact c: newConList){ if(oldConMap!=null){ if(oldConMap.get(c.Id).Contact_Type__c!=c.Contact_Type__c){ accId.add(c.AccountId); } if(oldConMap.get(c.Id).AccountId!=c.AccountId){ accId.add(c.AccountId); } } accId.add(c.AccountId); } Map<Id,Account> accMap = new Map<Id,Account>([Select id,Record_Type__c from Account where Id in :accId]); for(Contact c: newConList){ if(c.Contact_Type__c==null){ c.Contact_Type__c = accMap.get(c.AccountId).Record_Type__c; } else{ if(c.Contact_Type__c != accMap.get(c.AccountId).Record_Type__c){ c.addError('Contact Type should be same as Account Record Type that is '+accMap.get(c.AccountId).Record_Type__c); } } } } }
I have developed the apex class in a differnt way, can you please check whether it is correct or not public class Scenario48Handler { public static void method(List<Contact> conList){ Set<ID> accIDs = new Set<ID>(); for(Contact con : conList){ if(con.accountid!=null){ accIds.add(con.accountId); } } List<Opportunity> oppList = new List<Opportunity>(); if(accIds.size()>0){ Map<ID,Account> accMap = new Map<Id,Account>([select id,description from Account where id IN:accIds]); List<AggregateResult> aggr = [select sum(amount) total,accountid ac from Opportunity where accountid IN:accIds group by accountiD]; if(aggr.size()>0){ for(AggregateResult a : aggr){ if(accMap.containsKey((id)a.get('ac'))){ accMap.get((id)a.get('ac')).description = ' Total Amount : '+(Decimal)a.get('total'); } } } else{ for(id acc : accMap.keyset()){ Opportunity opp = new Opportunity(); opp.accountid = acc; opp.CloseDate = Date.today(); opp.StageName='Prospecting'; opp.name='Test OPp'; opplist.add(opp); } } if(opplist.size()>0){ insert oppList; } if(accMap.size()>0){ update accMap.values(); } } } }
Nice explanation 🎉
Curious ...we couldn't do this via reporting snapshot ? or custom formula field ?
trigger CaseTrigger on Case (after insert) { Map<Id,String> casenumberMap=new Map<Id,String>(); for(Case c:Trigger.new){ if(c.AccountId!=null){ casenumberMap.put(c.AccountId,c.CaseNumber); } } if(!casenumberMap.isEmpty()){ List<Account> accList=new List<Account>(); for(Id k:casenumberMap.keySet()){ Account acc=new Account(); acc.id=k; acc.latest_case_number__c=casenumberMap.get(k); accList.add(acc); } if(!accList.isEmpty()){ update accList; } } } simple solution for this question!
What if there are more than 1 contact associated with a type?
can we get all scenarios in a pdf , TIA
Sure I will create an excel sheet for sure
Hi Guys, I have gone through the comments and try to give my input. So, please find the updated code here which will work for If Account phone is null and on false update on Account means If we are changing other fields instead of Create_Contact__c. Note: I have not handled it for duplicate Contact creation. On again and again Checking the checkbox field, this will create new Contact associated with the same account. trigger CreateContactAssAccount on Account (after insert, after update) { List<Contact> conList = new List<Contact>(); for(Account acc : trigger.New){ if(acc.Create_Contact__c == true && (trigger.isInsert || (trigger.isUpdate && acc.Create_Contact__c != trigger.oldMap.get(acc.Id).Create_Contact__c))){ Contact con = new Contact(); con.FirstName = 'Trigger'; con.LastName = acc.Name; con.Phone = acc.Phone != null ? acc.Phone : ''; con.AccountId = acc.Id; conList.add(con); } } if(!conList.isEmpty()) insert conList; }
sorry for increasing the like count from 69 to 70😂😂....good scenario though👍👍
small request - also add for how many years of experience these triggers are for. Nice content btw
I did it with the Aggregate query, here's the code : CODE : ============================================== public static void afterInsert(List<Contact> newList){ List<Opportunity> oppListToInsert = new List<Opportunity>(); List<Account> accListtoUpdate = new List<Account>(); set<id> accIdset = new set<id>(); Map<Id,Decimal> accIdWithTotalSum = new Map<Id,Decimal>(); for(Contact newCon : newList){ if(newCon.accountid!=null){ accIdset.add(newCon.accountid); } } List<AggregateResult> agrList = [Select accountId, SUM(Amount) totalsum From Opportunity where accountId in: accIdset group by accountId]; for(AggregateResult agr : agrList){ if(!accIdWithTotalSum.containsKey((Id)agr.get('accountId'))){ accIdWithTotalSum.put((Id)agr.get('accountId'),(Decimal)agr.get('totalsum')); } } for(Id accId : accIdset){ if(!accIdWithTotalSum.containskey(accId)){ Opportunity opp = new Opportunity(); opp.accountId = accId; opp.stagename = 'Prospecting'; opp.name = 'Test opp'; opp.CloseDate = system.today().addDays(7); oppListToInsert.add(opp); Account acc = new Account(); acc.Id = accId; acc.description = String.valueOf(opp.Amount); accListtoUpdate.add(acc); }else{ Account acc = new Account(); acc.Id = accId; acc.description = String.valueOf(accIdWithTotalSum.get(accId)); accListtoUpdate.add(acc); } } if(!oppListToInsert.isEmpty()){ insert oppListToInsert; } if(!accListtoUpdate.isEmpty()){ update accListtoUpdate; } }
Will this trigger works on Bulk insert or Update , for example when we are loading data via data import or data loader? At the end of the for loop over extistingRecords , errorMessage will be set to a single value -->either phone,email or email and phone. so when we Iterate over trigger.new, for every record will it give same error? or it will change specific to record? Can you please clarify?
I've tried trigger AccountTrigger on Account(after update){ if(Trigger.isAfter && Trigger.isUpdate){ Map<Id, DateTime> accMap = new Map<Id, DateTime>(); Map<Id, List<Contact>> accMapToCon = new Map<Id, List<Contact>>(); List<Messaging.SingleEmailMessage> emailList = new List<Messaging.SingleEmailMessage>(); for(Account acc : Trigger.new){ accMap.put(acc.Id, Trigger.oldMap.get(acc.Id).LastModifiedDate); } System.debug(accMap); for(Contact con :[Select Id, LastModifiedDate, Name,AccountId, Account.Owner.Email from Contact Where AccountId IN: accMap.keySet()]){ if(con.LastModifiedDate >= accMap.get(con.AccountId) && !accMapToCon.containsKey(con.AccountId)){ accMapToCon.put(con.AccountId, new List<Contact>{con}); }else if(con.LastModifiedDate >= accMap.get(con.AccountId) && accMapToCon.containsKey(con.AccountId)){ accMapToCon.get(con.AccountId).add(con); } } for(Id accId: accMapToCon.keySet()){ Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); email.setToAddresses(new List<String>{accMapToCon.get(accId)[0].Account.Owner.Email}); email.setPlainTextBody('the acc '+ accId+' has been modified and these contacts has been modified '+accMapToCon.get(accId)); emailList.add(email); } Messaging.sendEmail(emailList); } }
I've tried: trigger CaseDeletion on Case (after delete) { if(Trigger.isDelete && Trigger.isAfter) { List<Case> deletedCase = Trigger.old; Set<Id> accountIds = new Set<Id>(); if(!deletedCase.isEmpty()){ for(Case caseRec : deletedCase){ accountIds.add(caseRec.AccountId); } } Map<Id, Account> accMap = new Map<Id, Account>([Select id, Owner.Email,OwnerId from Account where Id IN: accountIds]); List <Messaging.SingleEmailMessage> emailList = new List<Messaging.SingleEmailMessage>(); List<Task> taskList = new List<Task>(); for(Case caseRec: deletedCase){ Task taskRec = new Task(); taskRec.OwnerId = accMap.get(caseRec.AccountId).OwnerId; taskRec.Status = 'Not Started'; taskRec.Subject = 'Case Deleted '+caseRec.CaseNumber; taskRec.WhatId = caseRec.AccountId; taskList.add(taskRec); Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); email.setToAddresses(new List<String>{accMap.get(caseRec.AccountId).Owner.Email}); email.setSubject('An email from Salesforce'); email.setPlainTextBody('This email has been sent through Apex'); emailList.add(email); } insert taskList; Messaging.sendEmail(emailList); } }
I've tried: trigger ContactHandler on Contact ( after insert, after update) { if(Trigger.IsAfter && (Trigger.isInsert || Trigger.isUpdate)){ Map<Id,Contact> newConMap = Trigger.newMap; Map<Id,Contact> oldConMap = Trigger.oldMap; Map<Id,String> accountIdsMapPhone = new Map<Id,String>(); for(Contact con : newConMap.values()){ if((oldConMap==null || oldConMap.get(con.Id).Phone != con.Phone)){ accountIdsMapPhone.put(con.AccountId,con.Phone); } } List<Account> acclistToUpdate = new List<Account>(); List<Contact> conlistToUpdate = new List<contact>(); for(Account acc: [Select Id, Phone from Account where Id IN: accountIdsMapPhone.keySet()]){ if(acc.phone != accountIdsMapPhone.get(acc.Id)){ acc.phone = accountIdsMapPhone.get(acc.Id); acclistToUpdate.add(acc); } } for(Contact con : [Select id, Phone,AccountId from Contact where AccountId In: accountIdsMapPhone.keySet()]){ if(con.Phone != accountIdsMapPhone.get(con.AccountId)){ con.Phone = accountIdsMapPhone.get(con.AccountId); conlistToUpdate.add(con); } } if(!acclistToUpdate.isEmpty()){ update acclistToUpdate; } if(!conlistToUpdate.isEmpty()){ update conlistToUpdate; } } }
I've tried: trigger OpportunityHandler on Opportunity ( after insert, after update) { if(Trigger.IsAfter && (Trigger.isInsert || Trigger.isUpdate)){ Set<Id> accIds = new Set<Id>(); List<Account> accList = new List<Account>(); for(Opportunity opp: Trigger.new){ if(Trigger.oldMap == null || opp.Amount != Trigger.oldMap.get(opp.Id).Amount){ accIds.add(opp.AccountId); } } for(Account acc : [Select Id,Description,(Select id,Amount from Opportunities order by Amount desc) from Account where Id IN: accIds]){ if(acc.Opportunities.size()>1){ acc.Description = 'The 2nd Highest amount from Opportunities is '+acc.Opportunities[1].Amount; accList.add(acc); } } if(accList.size()>0){ update accList; } } }
Helpful videos. But can you please add helper class for all the scenarios
public static void updateContactName(List<Account> accList){ if(!accList.isEmpty()){ List<Contact> conList = new List<Contact>(); set<Id> accids = new Set<Id>(); for(Account acc: accList){ Contact con = new Contact(); con.AccountId = acc.id; con.LastName = acc.Name+' triggerAccount4'; conList.add(con); accids.add(acc.Id); } if(!conList.isEmpty()){ insert conList; } if(!accids.isEmpty()){ List<Account> newAccList = [Select Id, client_contact__c, (Select AccountId, name From Contacts) from Account where Id IN: accids]; List<Account> updatedList = new List<Account>(); for(Account acc: newAccList){ if(!acc.contacts.isEmpty()){ acc.client_contact__c = acc.Contacts[0].Name; updatedList.add(acc); } } if(!updatedList.isEmpty()){ update updatedList; } } } }
is this triggers for freshers or 2+ years experience?
Do we really need line 30 31? As new case is inserted
Hi, might be i am new for this but please check line 30 31 else part. Don't think there should be else if(op. Amount change) Then only add accid. Otherwise anyfield update trigger will be executed Infact in every event.
only for insert operation public static void createtaskOnPrimaryContact(List<Case> lstCs) { set<id> accIds=new set<id>(); List<Task> tkToInsert=new List<Task>(); if(!lstCs.isempty()) { for(Case newcs:lstCs) { if(newcs.accountid != null && newcs.Create_Task__c == true) { accIds.add(newcs.accountid); } } } if(!accIds.isempty()) { List<Contact> lstCon=[select id, name, accountid, primary_contact__C from contact where accountid in:accIds and primary_contact__C=true]; for(Contact con:lstCon) { Task tk=new task(); tk.Status='New'; tk.Priority='High'; tk.Subject='Account details need to be send'; tk.WhoId=con.id; tkToInsert.add(tk); } } if(!tkToInsert.isempty()) { insert tkToInsert; } }
Apex trigger 7 - what if account does not have phone number? Should we consider to create contact? Or need to filter those account from trigger.new whose phone is blank
Please check the updated code in the comment section.
Hi, can you pls share the code.
sir , can we acheive this requirement with the help of set
what about after insert or before delete? I can introduce a new trigger or delete
Hi bro, I have seen plenty of videos regarding trigger, but you nailed it bro, really thanks for your teaching bro.
Trigger:trigger contactTrigger on Contact (after insert) { if(trigger.isafter) { if(trigger.isinsert) { ContactTrgHelper.createOpp(Trigger.new); } } } Handler class: public class ContactTrgHelper { public static void createOpp(List<Contact> lstcon) { set<Id> accIds=new set<Id>(); if(!lstcon.isempty()) { for(Contact newcon:lstcon) { if(newcon.AccountId != null) { accIds.add(newcon.AccountId); } } } if(!accIds.isempty()) { map<id, decimal> mapOfCon=new map<id, decimal>(); List<Account> accToupdate=new List<Account>(); List<Opportunity> oppToInsert=new List<Opportunity>(); for(Aggregateresult agr:[select Accountid acid, sum(Amount) totalAmnt from Opportunity where Accountid in:accIds group by accountid]) { mapOfCon.put((Id)agr.get('acid'), (decimal)agr.get('totalAmnt')); } for(Contact ncon:lstcon) { if(mapOfCon.containskey(ncon.AccountId)) { Account accrec=new Account(); accrec.id=ncon.AccountId; accrec.Total_Opportunity_Amount__c=mapOfCon.get(ncon.AccountId); accToupdate.add(accrec); } else { Opportunity opprec=new Opportunity(); opprec.Name='Test Opp'; opprec.StageName='Prospecting'; opprec.CloseDate=system.today()+30; opprec.AccountId=ncon.AccountId; oppToInsert.add(opprec); } } if(!accToupdate.isempty()) { update accToupdate; } if(!oppToInsert.isempty()) { Insert oppToInsert; } } } }
What's the difference between : database.getQuerylocator and datatable.querylocator. Because in Salesforce documentation the governor limit for records retrieved by database.getquerylocator is 10 thousand but you told it's 50 million. Wanted clarity for it
Great Content! Try this approach! Set<Id> accIds = new Set<Id>(); for (Case c : oldCases.values()) { if (c.AccountId != null) { accIds.add(c.AccountId); } } if (accIds.size() > 0) { List<Account> accList = [SELECT Id, Owner.Email, Owner.Name FROM Account WHERE Id IN :accIds]; List<Task> taskList = new List<Task>(); List<Messaging.SingleEmailMessage> emailList = new List<Messaging.SingleEmailMessage>(); for (Account a : accList) { taskList.add( new Task( Subject = 'Followup Task while deleting Case on Account', Status = 'In Progress', // WhoId = con.Id, WhatId = a.Id ) ); Messaging.SingleEmailMessage ms = new Messaging.SingleEmailMessage(); ms.setToAddresses(new List<String>{a.Owner.Email}); ms.setPlainTextBody(a.Owner.Name); ms.setSubject('Case is deleted from these Account and Task is being created in respect of this!'); emailList.add(ms); } if (taskList.size() > 0) { try { insert taskList; } catch (Exception e) { System.debug('Exception occured while inserting the task --> '+e.getMessage()); } } if (emailList.size() > 0) { try { Messaging.sendEmail(emailList); } catch (Exception e) { System.debug('Error while sending mails'+e); } } }
Hi 2 things I wanted to ask.. 1. Can we handle this in before delete context 2. And I saw u iterated over deleted caselist and created tasks and email. Here can we iterate over account list right? I am just trying to understand if there is any problem in my approach Please let me know
Hi Sir could you please write a trigger on Account object whenever Account getting updated we need to send an email to the account owner also send contacts data only those created between last update and current update of account
Hi just wanted to know do u need null check
public static void preventDuplicateRecord(List<Account> accList){ // Collect unique account names (normalized to lowercase) Set<String> newAccNames = new Set<String>(); for (Account acc : accList) { if (acc.Name != null) { newAccNames.add(acc.Name.toLowerCase()); } } // Query existing accounts with names in the set List<Account> existingAccounts = [ SELECT Id, Name FROM Account WHERE Name IN :newAccNames ]; // Collect existing account names and their IDs Set<String> existingAccNames = new Set<String>(); Map<String, Id> existingNameToIdMap = new Map<String, Id>(); for (Account acc : existingAccounts) { existingAccNames.add(acc.Name.toLowerCase()); existingNameToIdMap.put(acc.Name.toLowerCase(), acc.Id); } // Flag duplicate records for (Account acc : accList) { if (acc.Name != null) { String normalizedName = acc.Name.toLowerCase(); // Check if the name exists and if it's not the same as the current record if (existingAccNames.contains(acc.Name.toLowerCase()) && !existingNameToIdMap.get(acc.Name.toLowerCase()).equals(acc.Id)) { acc.addError('Duplicate Account Name detected: ' + acc.Name); } } } }
You are trying to insert 4 Account records, all with the same name, and that name does not currently exist in the database. Will it allow Insertion ?
The following code will not allow /*Trigger Scenario: Write a trigger to prevent duplicate accounts based on name whenever an Account is inserted or updated. Scenario is to validate records before they are saved to database. so we use before trigger. context variables to access runtime contexts are Trigger.isInsert and Trigger.isUpdate*/ trigger AccountTrigger on Account(before insert,before update){ //set to collect Account Name from triggering records. List<String> accNames=new List<String>(); //accessing run time context if(Trigger.isBefore){ if(Trigger.isInsert){ //iterating over triggering records for(Account acc:Trigger.new){ accNames.add(acc.Name); } } if(Trigger.isUpdate){ //iterating over triggering records for(Account acc:Trigger.new){ //checking whether the account's Name is changed or not if(acc.Name != Trigger.oldMap.get(acc.Id).Name){ accNames.add(acc.Name); } } } } List<Account> accList=[SELECT Id,Name FROM Account WHERE Name IN:accNames]; set<String> accNameSetToCheckDups=new set<String>(); //Map to get number of accounts with same name Map<String,Integer> accNamesCountwithName=new Map<String,Integer>(); //iterating over accNames if(!accNames.isEmpty()){ for(String acctName:accNames){ if(!accNamesCountwithName.containsKey(acctName)){ accNamesCountwithName.put(acctName,0); }else { Integer count=accNamesCountwithName.get(acctName)+1; accNamesCountwithName.put(acctName,count); } } } //iterating over accList to collect existing names if(!accList.isEmpty()){ for(Account acc:accList){ accNameSetToCheckDups.add(acc.Name); } } //iterating over Triggering records to prevent duplicates if(!accNameSetToCheckDups.isEmpty() || accNamesCountwithName.keySet() !=null ){ //if triggering records has the same name more than one (If we are inserting /updating with same name at a time) for(Account acc:Trigger.new){ if(accNamesCountwithName.get(acc.Name)>1 || accNameSetToCheckDups.contains(acc.Name)){ acc.addError('Account already exists with the same name'); } } } }
@@JShorts511 thank you
Nice Explanation
but an opportunity might have multiple Tasks ?
Thanks for making amazing content, keep it up bro :) Try this approach, Map<Id, String> phoneToIdMap = new Map<Id, String>(); for (Contact c : newContacts) { if (c.Phone != null && c.Phone != oldContacts.get(c.Id).Phone && c.AccountId != null) { phoneToIdMap.put(c.AccountId, c.Phone); } } if (phoneToIdMap.size() > 0) { List<Contact> conList = [SELECT Id, AccountId, Phone FROM Contact WHERE AccountId IN :phoneToIdMap.keySet()]; List<SObject> updateList = new List<SObject>(); Map<Id, Account> accMap = new Map<Id, Account>(); //we take map because if we directly insert acc in above list it gives duplicate Ids found error! for (Contact c : conList) { c.Phone = phoneToIdMap.get(c.AccountId); updateList.add(c); accMap.put( c.AccountId, new Account( Id = c.AccountId, Phone = phoneToIdMap.get(c.AccountId) ) ); } if (accMap.size() > 0) { updateList.addAll(accMap.values()); } if (updateList.size() > 0) { try { update updateList; } catch (Exception e) { System.debug('Exception occured in updating list --> '+e.getMessage()); } } }
Hi can anyone tell me why I'm not getting any changes in account object even tho I have done all the steps just like video .! 😮
Hi can you please share your code
Hi SFDC ninja: I have a doubt, Instead of adding to Map. Directly in line 25 we can null check accountId and create instance of Account there itself and update account. Works right ? Great work by the way, Your classes are very useful 🙏
I think we can also use account list and fetching related contacts and updating phone through map , its works for me actually in a simple way
can you please share that code
I used a diff approach , class: public with sharing class phoneAccConsHandler { //whenever a contact phone gets updated, it's parent account phone should get updated, also all of the account's other contacts phone also should get updated with the same phone number. public static void afterUpdate(List<contact> newCons,Map<id,contact> oldConMap){ set<id> accIds=new Set<id>(); Map<id,string> accidPhoneMap=new Map<id,string>(); for(Contact con:newCons){ if(con.accountId!=null && con.Phone!=null && oldConMap==null){ accIds.add(con.accountId); accidPhoneMap.put(con.accountId,con.phone); }else if(con.accountId!=null && con.Phone!=null && oldConMap.get(con.id).phone!=con.phone || oldConMap.get(con.id).accountId!=con.accountId){ accIds.add(con.accountId); accIds.add(oldConMap.get(con.id).accountId); accidPhoneMap.put(con.accountId,con.phone); accidPhoneMap.put(oldConMap.get(con.id).accountId,con.phone); } } //update account Phone List<account> Accounts=new List<account>(); for(Account acc:[select id,phone from account where id in:accIds]){ acc.phone=accidPhoneMap.get(acc.id); Accounts.add(acc); } If(Accounts.size()!=0){ update Accounts; } //list all contact's of that account: List<contact> allConsToBeUpdated=new List<contact>(); List<contact> allCons=[Select id,accountId,Phone from Contact where accountId in:accIds]; for(Contact con:allCons){ con.phone=accidPhoneMap.get(con.accountId); allConsToBeUpdated.add(con); } if(allConsToBeUpdated.size()!=0){ update allConsToBeUpdated; } } }
pls upload the codes