Update Lookup Value by Trigger - triggers

I have a custom object(custom_object__c) which contain lookup with a user,
and I have a lookup to the custom_object__c from Opportunity, now I need to fill the custom_object__c lookup if the user lookup field present in the custom_object__c is equal to Opportunity Owner and Opportunity Stage equals Prospecting.
My code below:
trigger Update_Approver_Target on Opportunity (before insert, before Update) {
Set<id> appIds = new Set<id>();
Map<id, Approver_Target__c> appsMap = new Map<id, Approver_Target__c>([SELECT Name, User__c FROM Approver_Target__c WHERE Id IN :appIds]);
for (Opportunity opp : Trigger.new)
appIds.add(opp.Approver_Target__c);
for (Opportunity opp : Trigger.new) {
System.debug('Opportunity: '+appsMap.get(opp.Approver_Target__c).User__c);
if(opp.OwnerId == opp.Approver_Target__r.User__c && opp.StageName == 'Prospecting'){
opp.Approver_Target__c = opp.Approver_Target__r.Name;
}
else{
opp.Approver_Target__c = '';
}
}
}

Related

Apex Trigger (before insert): Update the Company Name, During the Creation of a New Lead Record, with the Value in a Custom Lookup Field

Using an Apex Trigger, I am attempting to update the Company field, during the creation of a new lead, with the value which the user selected from a custom lookup field on the same object. So, the user clicks new on the lead tab to create a new lead. enters the first name, last name and other details. Instead of typing in the company name, the user then searches for the company name in the lookup field, compName__c, and selects it from the list. What I would like to accomplish is when the the user clicks save, the value in the compName field is copied to the Company field on the new record, then the new record is created.
Here is what I have done thus far;...
trigger UpdateLeadCompany on Lead (before insert) {
Set<Id> AN = New Set<Id>();
For (Lead LeadComp : Trigger.New)
{
IF(LeadComp.compName__c != null)
{
AN.add(LeadComp.compName__c);
}
}
Map<Id, Agency__c> y = [SELECT Name, compName__c FROM compName__c WHERE Id IN :AN];
For(Lead CompNameUpdate : Trigger.New)
{
Company a = y get(CompNameUpdate.compName__c);
IF(a != null)
{
CompNameUpdate = a.compName__c;
}
}
}
Updated
Then your code should be like -
trigger UpdateLeadCompany on Lead (before insert) {
Set<Id> AN = New Set<Id>();
for(Lead leadObj : Trigger.New) {
IF(leadObj.compName__c != null) {
AN.add(leadObj.compName__c);
}
}
Map<Id, compName__c> y = [SELECT Name, compName__c FROM compName__c WHERE Id IN :AN];
For(Lead leadObj : Trigger.New) {
compName__c a = y.get(leadObj.compName__c);
IF(a != null) {
leadObj.Company = a.Name;
}
}
}

Not able to do re parenting in this question. If an opportunity is removed from an account then it should be removed from the Account lookup field

issue in re parenting, In this question i have to find the largest opportunity by amount and put into the Account lookup field which is working but when i am changing the account of an opportunity then it remains in the account look up field. can someone please correct it, if i am wrong
public class TopOpportunityClass{
public static boolean flag = true;
public static void onTopOpportunity(List<Opportunity> opport){
if(flag==true){
List<Opportunity> uptOpp = new List<Opportunity>();
Set<Id> accIds = new Set<Id>();
for(Opportunity opp : opport){
if(opp.AccountId != null){
accIds.add(opp.AccountId);
}
}
Map<Id, List<Opportunity>> accOpportMap = new Map<Id, List<Opportunity>>();
List<Account> accUpdateList = new List<Account>();
for(Opportunity obj : [SELECT id,name, amount,accountId
FROM Opportunity
WHERE accountId IN :accIds ORDER BY amount DESC nulls last]){
List<Opportunity> oppList;
if(accOpportMap.containsKey(obj.accountId)){
oppList = accOpportMap.get(obj.accountId);
}else{
oppList = new List<Opportunity>();
}
oppList.add(obj);
accOpportMap.put(obj.accountId, oppList);
}
for(Id accId : accOpportMap.keySet()){
if(accOpportMap.get(accId).size() > 1 ){
opportunity opp1 = new opportunity(id = accOpportMap.get(accId)[1].id , isTopOpportunityCheck__c = false);
uptOpp.add(opp1);
accUpdateList.add(new Account(id = accId, isTopOpportunity__c = accOpportMap.get(accId)[0].id));
opportunity opp = new opportunity(id = accOpportMap.get(accId)[0].id , isTopOpportunityCheck__c = true);
uptOpp.add(opp);
}else if(accOpportMap.get(accId).size() == 1 ){
accUpdateList.add(new Account(id = accId, isTopOpportunity__c = accOpportMap.get(accId)[0].id));
opportunity opp = new opportunity(id = accOpportMap.get(accId)[0].id , isTopOpportunityCheck__c = true);
uptOpp.add(opp);
}else if(accOpportMap.get(accId).size() == 0){
accUpdateList.add(new Account(isTopOpportunity__c = NULL, id = NULL));
}
flag = false;
}
if(!accUpdateList.isEmpty()){
update accUpdateList;
update uptOpp;
}
}
}
}
//trigger
trigger OpportunityTrigger on Opportunity (after insert, after update){
if(Trigger.isAfter){
TopOpportunityClass.onTopOpportunity(Trigger.new);
}
}
You are running after update, so you're getting the new values in each sObject. If you want to affect the old Account assigned to some reparented Opportunity, you need to also look at the value in Trigger.old or Trigger.oldMap.
The way to do this would be to add a check here:
for(Opportunity opp : opport){
if(opp.AccountId != null){
accIds.add(opp.AccountId);
}
}
to find a reparented Opportunity (opp.AccountId != Trigger.oldMap.get(opp.Id).AccountId) and affect that Account as well.
There's a separate issue further below: this logical branch is clearly wrong.
}else if(accOpportMap.get(accId).size() == 0){
accUpdateList.add(new Account(isTopOpportunity__c = NULL, id = NULL));
}
You can't update an Account whose Id is null, and that will produce an exception.
You also need to reset flag to true after performing updates, or your trigger will have some very confusing and difficult-to-debug edge cases when multiple DML operations are performed in a single transaction.

Trigger on a certain Account Record Type

So i have written a trigger that works perfectly fine and does exactly what i want it to do, but the thing is that it does the job on all the account, and i want it to work only on one record type of the accounts.
Can someone tell me what to add to my trigger so i can make it work only on one record type?
The following is my handler class:
public class AP03_OpportunityLineItem {
public static void preventmultipleOpportunityLineItems(List<OpportunityLineItem> listOppLineItems){
Set<Id>opportunityIds = new Set<Id>();
// get all parent IDs
for(OpportunityLineItem oli : listOppLineItems)
{
//Condition to pick certain records
opportunityIds.add(oli.OpportunityId);
}
// query for related Opportunity Line Items
Map<Id, Opportunity> mapOpportunities = new Map<Id, Opportunity>([SELECT ID,
(SELECT ID
FROM OpportunityLineItems)
FROM Opportunity
WHERE ID IN :opportunityIds]);
// opp counter of new records
Map<Id, Integer> mapOppCounter = new Map<Id, Integer>();
for(OpportunityLineItem oli : listOppLineItems)
{
if(mapOppCounter.containsKey(oli.OpportunityId))
{
mapOppCounter.put(oli.OpportunityId, mapOppCounter.get(oli.OpportunityId)+1);
}
else
{
mapOppCounter.put(oli.OpportunityId, 1);
}
}
//loop to add error if condition violated
for(OpportunityLineItem olitems : listOppLineItems)
{
if(mapOpportunities.get(olitems.OpportunityId).OpportunityLineItems.size()+mapOppCounter.get(olitems.OpportunityId)>1 || olitems.Quantity > 1)
{
olitems.addError('Ce client peut seulement loué un seul véhicule.');
}
}
}
}
The following is my PAD class:
public class PAD
{
public static String bypassTrigger; //List of bypassed triggers
public static final User user;
static {
user = [Select BypassApex__c
from User
where Id=:UserInfo.getUserId()];
bypassTrigger = ';'+ user.BypassApex__c+ ';';
System.debug('>>>>> PAD constructor : END <<<<<'+bypassTrigger);
}
/**
* Method used for the class PAD
* #param c object of type JonctionServicePrestation__c
* #return boolean
*/
public static boolean canTrigger(string Name){
return (bypassTrigger.indexof(';' + Name + ';') == -1);
}
}
And the following is my Trigger:
trigger OpportunityLineItemBeforeInsert on OpportunityLineItem (before insert) {
if(PAD.canTrigger('AP03_OpportunityLineItem')){
AP03_OpportunityLineItem.preventmultipleOpportunityLineItems(Trigger.new);
}
}
You would need to loop through your opportunitiesproducts and build a list of opportunity Id, then query the Opportunity whose Accounts in the list with the record type you want to match, and build a set of the ids that match the specified record type then check if the set contains the accountId of the opportunity being process to know if the skip or process it.
Set<Id> recordTypeOpp = new Set<ID>();
SET<Id> opportunityIds = new Set<Id>();
Id recordTypeIdYouWant = Schema.SObjectType.Account.getRecordTypeInfosByName().get('Record Type Name').getRecordTypeId();
for(OpportunityLineItem item : listOppLineItems){
opportunityIds.add(item.OpportunityId);
}
for(Opportunity item : [SELECT Id FROM Opportunity WHERE opportunityIds IN :opportunityIds and Account.RecordTypeId = :recordTypeIdYouWant]){
recordTypeOpp.add(item.Id);
}
for(OpportunityLineItem olitems : listOppLineItems)
{
if(recordTypeOpp.contains(olitems.OpportunityId)){
//do processing
}
else {
continue;
}
}

Trigger on contentdocumentlink on insert, makes checkbox true on account

Trying to write a trigger on contentdocumentlink, which fires on insert and check a check box to true on account, but code doesn't seems to work.
Also getting compile error.
public with sharing class contentDocumentLinkTriggerHandler {
public static void processOnInsert(list<ContentDocumentLink> newList) {
list<ContentDocumentLink> contentList = new list<ContentDocumentLink>();
set<id> accId = new set<id>();
map<id,list<ContentDocumentLink>> parentContentMap = new map<id,list<ContentDocumentLink>>();
set<id> contId = new set<id>();
for(ContentDocumentLink nt : newList){
if(nt.linkedentityid.getSobjectType() == Account.SObjectType){
accId.add(nt.linkedentityid);
}
if(nt.linkedentityid.getSobjectType() == Contact.SObjectType){
contId.add(nt.linkedentityid);
}
if(parentContentMap.containsKey(nt.linkedentityid))
parentContentMap.get(nt.linkedentityid).add(nt);
else
parentContentMap.put(nt.linkedentityid,new list<ContentDocumentLink>{nt});
}
if(!accId.isEmpty()){
//login for acc
for(Account acc : [SELECT id,checkFiles__c FROM Account WHERE id IN : accId]){
if(parentContentMap.containsKey(acc.id)){
acc.checkFiles__c == true;// compile error
}
}
}
}
}

"CONTACT" record should be CONVERT back to the "LEAD" record when ACCOUNT NAME in contact is deleted

Whenever the Account on Contact record changes, the contact should be converted back to a Lead. I have mapping fields from contact to lead. Is this possible ? How to achieve this ?
I'm trying to do it by writing a trigger:
trigger insertLead on Contact (before update,before delete) {
Set<Id> aId = new Set<Id>();
Lead myLead = new Lead();
for (Contact opp : Trigger.new ) {
aId.add(opp.AccountId);
List<Account> acc = [select Name from Account where Id in:aId];
List<Contact> con = [select LastName,FirstName from Contact where accountId = :aId];
for(Account a: acc){
myLead.Company = a.Name;
}
for(Contact c: con)
{
myLead.LastName = c.LastName;
myLead.FirstName = c.FirstName;
}
insert myLead;
}
This is the error:
Error:Apex trigger insertLead caused an unexpected exception,
contact your administrator: insertLead: execution of BeforeUpdate
caused by: System.DmlException: Insert failed. First exception
on row 0; first error: REQUIRED_FIELD_MISSING, Required fields
are missing: [Company]: [Company]: Trigger.insertLead: line 15, column 1
I have checked and your trigger is working fine for Update on Contact.
To work for delete add below condition.
trigger insertLead on Contact (before update,before delete) {
Set<Id> aId = new Set<Id>();
Lead myLead = new Lead();
if (Trigger.isUpdate)
{
for (Contact opp : Trigger.new ) {
aId.add(opp.AccountId);
List<Account> acc = [select Name from Account where Id in:aId];
List<Contact> con = [select LastName,FirstName from Contact where AccountId = :aId];
for(Account a: acc){
myLead.Company = a.Name;
}
for(Contact c: con)
{
myLead.LastName = c.LastName;
myLead.FirstName = c.FirstName;
}
insert myLead;
}
else if(if (Trigger.isDelete)
{
for (Contact opp : Trigger.old ) {
aId.add(opp.AccountId);
List<Account> acc = [select Name from Account where Id in:aId];
List<Contact> con = [select LastName,FirstName from Contact where AccountId = :aId];
for(Account a: acc){
myLead.Company = a.Name;
}
for(Contact c: con)
{
myLead.LastName = c.LastName;
myLead.FirstName = c.FirstName;
}
insert myLead;
}
}
}
Regards,
Naveen
SSE
http://www.autorabit.com