You need to sign in to do that
Don't have an account?
chaitanya motupalli 13
Trigger to show an error message on Opportunity record
Hi, i have written trigger on opportunity while inset or update. this logic compare opp with already existed prodcuts on org. if it maches we are throughing an error message on opp record. but i am getting null pointer excpetion. please any help
trigger helloOppTrg on Opportunity (after insert,after update) {
list<Id>accIdlst = new list<Id>();
list<string>oppOrdernolst = new list<string>();
for (Opportunity objOpp : Trigger.new) {
oppOrdernolst.add(objOpp.OrderNumber__c);
accIdlst.add(objOpp.AccountId);
}
system.debug('opp order no entering'+oppOrdernolst);
system.debug('account id entering'+accIdlst);
list<Opportunity> oppwithaccount = new list<Opportunity>();
oppwithaccount = [SELECT Id,AccountId,OrderNumber__c,Account.Name FROM Opportunity WHERE AccountId=:accIdlst];
list<string>accname= new list<string>();
for(Opportunity acc:oppwithaccount){
accname.add(acc.Account.Name);
}
system.debug('account name'+accname);
list<Product2> matchProduct = new list<Product2>();
matchProduct = [SELECT Id, IsActive, ProductCode, Name FROM Product2
WHERE ProductCode =:oppOrdernolst AND Name =:accname];
system.debug('product records'+matchProduct);
for(Opportunity objOpp:oppwithaccount) {
system.debug('opp id top'+objOpp.id);
for(Product2 proloop : matchProduct) {
system.debug('inside second loop');
if(proloop.IsActive==false && proloop.ProductCode==objOpp.OrderNumber__c
&& proloop.Name==objOpp.Account.Name){
system.debug('inside third loop');
system.debug('opp id'+objOpp.id); // Id value is showing properly
Opportunity oppfromtriggernewmap = Trigger.newMap.get(objOpp.id); // but here it reurns null value
system.debug('just opp before error msg'+oppfromtriggernewmap); // Null
oppfromtriggernewmap.OrderNumber__c.addError('check is false so can not update/insert record MACHED');// Null pointer exception
}
}
}
}
trigger helloOppTrg on Opportunity (after insert,after update) {
list<Id>accIdlst = new list<Id>();
list<string>oppOrdernolst = new list<string>();
for (Opportunity objOpp : Trigger.new) {
oppOrdernolst.add(objOpp.OrderNumber__c);
accIdlst.add(objOpp.AccountId);
}
system.debug('opp order no entering'+oppOrdernolst);
system.debug('account id entering'+accIdlst);
list<Opportunity> oppwithaccount = new list<Opportunity>();
oppwithaccount = [SELECT Id,AccountId,OrderNumber__c,Account.Name FROM Opportunity WHERE AccountId=:accIdlst];
list<string>accname= new list<string>();
for(Opportunity acc:oppwithaccount){
accname.add(acc.Account.Name);
}
system.debug('account name'+accname);
list<Product2> matchProduct = new list<Product2>();
matchProduct = [SELECT Id, IsActive, ProductCode, Name FROM Product2
WHERE ProductCode =:oppOrdernolst AND Name =:accname];
system.debug('product records'+matchProduct);
for(Opportunity objOpp:oppwithaccount) {
system.debug('opp id top'+objOpp.id);
for(Product2 proloop : matchProduct) {
system.debug('inside second loop');
if(proloop.IsActive==false && proloop.ProductCode==objOpp.OrderNumber__c
&& proloop.Name==objOpp.Account.Name){
system.debug('inside third loop');
system.debug('opp id'+objOpp.id); // Id value is showing properly
Opportunity oppfromtriggernewmap = Trigger.newMap.get(objOpp.id); // but here it reurns null value
system.debug('just opp before error msg'+oppfromtriggernewmap); // Null
oppfromtriggernewmap.OrderNumber__c.addError('check is false so can not update/insert record MACHED');// Null pointer exception
}
}
}
}
Thanks for reply. your thought worked but i i made change in SOQL from "Trigger.newMap" to "Trigger.new" since i am getting error message saything 'IN operator must be used with an iterable expression' So final answer is
All Answers
if the account has some existing opportunity that also will come in the below query. But it will not present in the Trigger.NewMap(which is the newly created or edited records). So that in the for loop trigger.newmap giving null.
oppwithaccount = [SELECT Id,AccountId,OrderNumber__c,Account.Name FROM Opportunity WHERE AccountId=:accIdlst];
In the above query add one more condition to check the Trigger.New Opps only.
oppwithaccount = [SELECT Id,AccountId,OrderNumber__c,Account.Name FROM Opportunity WHERE AccountId=:accIdlst and Id IN: Trigger.NewMap];
Thanks,
Maharajan.C
Thanks for reply. your thought worked but i i made change in SOQL from "Trigger.newMap" to "Trigger.new" since i am getting error message saything 'IN operator must be used with an iterable expression' So final answer is
First of all Thanks Maharajan, for helping out.
The following question is for both of you. Anyone can help reply.
I am little confuse with the code as it is written and what you are asking, I think it can be simplified, may be I am missing something.
- Looks like your end goal is to look at the flag IsActive of that product for which opportunity OrderNumber (ProdcutCode) is either getting inserted or updated?
- Isn't the trigger should be either on before update or before insert becuase after insert and after update means, it is done?
Will appreciate your reply so I understand for my knowledge1)Yes you are right
2)We are using Opportunity Id in this trigger so we must user after. If you use before system dont generate Opportunity Id.
Note: though system gerenate opportunity ID in the process it wont get saved into system permanently unless trigger runs properly with out any error messsages.
I know that but your following message is referencing which record? I think Opportunity, if that is the case the record is already updated or inserted, it didn't get in align with the message, how you prevented that to happen.
check is false so can not update/insert record MACHED
Any thoughts?