You need to sign in to do that
Don't have an account?
instead of 3 soql need a method
Hi,
Please help me in writing the method instead of writing 3 soql statements.
i will pass the owner id it should return all the reporting to ids from salestree upto three levels.
trigger salesnotice on Opportunity (after update) {
map<string,string> stnmap=new map<string,string>();
map<Id,String>Reporting2Ids =new map<ID,String>();
for(Opportunity op:trigger.new) {
if(Trigger.IsUpdate && op.Stagename!=Trigger.oldMap.get(op.Id).Stagename &&(op.StageName=='Confirmed' || op.StageName==' Application' || op.StageName==' Endorsed Confirmed')){
stnmap.put(op.ownerid,op.id);
}
}
salestree(stnmap);
public static void salestree(map<String,String> x){
list<Sales__c> lstst= [select id,Subordinate__c,Subordinate__r.Email,Repo__c,Repo__r.Email from Sales__c where Subordinate__c IN : x.keyset()];
if(!lstst.isempty()){
for(Sales__c s:lstst){
Reporting2Ids.put(s.repo__c,s.Repo__r.Email);
}
}
list <Sales__c> lstst1= [select id,Repo__c,Repo__r.Email from Sales__c where Subordinate__c IN :Reporting2Ids.keyset()];
if(!lstst1.isempty()){
for(Sales__c s:lstst1){
Reporting2Ids.put(s.repo__c,s.Repo__r.Email);
}
}
list <Sales__c> lstst2= [select id,Repo__c,Repo__r.Email from Sales__c where Subordinate__c IN :Reporting2Ids.keyset()];
if(!lstst2.isempty()){
for(Sales__c s:lstst2){
Reporting2Ids.put(s.repo__c,s.Repo__r.Email);
}
}
}
List<string>s =new List<String>();
s=Reporting2Ids.values();
System.debug('**************************>>'+s);
}
Thanks In advance.
I'll answer this in two parts:
First, to directly answer your question, you could iterate and test like this:
Second, I don't think that will be the solution. In the email message area of your code, you are referencing two variables, Appname and stgName, which you haven't declared or assigned anywhere. I think what you might want to do is change your stnmap so that it holds the opportunity, like Map<String, Opportunity> stnmap = new Map<String, Opportunity>(); and stnmap.put(op.OwnerId, op);. That would then allow you to have access to the opportunities' info while you create the mail message in your loop and send the messages after the loop, like so:
All Answers
i think their is no other way
we can get
up to one level of child from parent
If you really want to use a method rather than the way you have it now, you would have to make it a static method and put it into a class (since triggers can't contain methods). Although you'd be making a SOQL query in a loop (albeit only 3 times), you could move it out into a method like so:
hi John
Thanks for the reply.could you help me in iterating the map.
this is my modified trigger.
trigger salestreenotification on Opportunity (after update) {
map<string,string> stnmap=new map<string,string>();
map<Id,String>Reporting2Ids =new map<ID,String>();
map<string,set<string>> owner_relmailids=new map<string,set<string>>();
map<string,set<string>> sub_owners=new map<string,set<string>>();
Map<String,String>sub=new map<String,String>();
List<Id>st=new list<Id>();
for(Opportunity op:trigger.new) {
if(Trigger.IsUpdate && op.Stagename!=Trigger.oldMap.get(op.Id).Stagename &&(op.StageName=='Confirmed' || op.StageName=='Partial Application' || op.StageName=='Admissions Endorsed Confirmed')){
stnmap.put(op.ownerid,op.id);
owner_relmailids.put(op.ownerid,new set<string>());
}
}
System.debug('<>>>>'+stnmap);
if(!stnmap.isEmpty()){
Set<String> ids = new Set<String>();
ids.addall(stnmap.keySet());
for (Integer i = 0; i < 3; i++) {
if(!ids.IsEmpty())
{
list <Sales__c> lstst= [select id,Subordinate__c,Subordinate__r.Email,Reporting_To__c,repo__r.Email from Sales__c where Subordinate__c IN : ids];
ids.clear();
for (Sales__c s :lstst) {
if(s.repo__c!=null){
Reporting2Ids.put(s.repo__c, s.repo__r.Email);
sub.put(s.Subordinate__c,s.repo__r.Email);
System.debug('---)))->'+sub);
ids.add(s.repo__c);
set<String> temp=sub_owners.containsKey(s.repo__c)?sub_owners.get(s.repo__c):new set<string>();
if(i!=0)
{
if(sub_owners.containsKey(s.Subordinate__c))
temp.addAll(sub_owners.get(s.Subordinate__c));
}
else
{
temp.add(s.Subordinate__c);
}
sub_owners.put(s.repo__c,temp);
for(string onrs:temp)
{
set<string> mids=owner_relmailids.containsKey(onrs)?owner_relmailids.get(onrs):new set<string>();
mids.add(s.repo__r.Email);
owner_relmailids.put(onrs,mids);
}
}
}
}
}
System.debug('---)))-->'+owner_relmailids);
}
List<string>s =new List<String>();
for(Integer d=0;d<owner_relmailids.size();d++){
}
System.debug('**************************>>'+s);
messaging.Singleemailmessage mail=new messaging.Singleemailmessage();
mail.setToAddresses(s);
mail.setSenderDisplayName('Hult');
mail.setSubject('Opportunity Stage changed to:'+stgName);
mail.setPlainTextBody('The Application record '+Appname+'stage name was been changed to:'+StgName);
try{
messaging.sendEmail(new messaging.Singleemailmessage[]{mail});
}
catch(DMLException e){
system.debug('ERROR SENDING EMAIL:'+e);
}
}
I need to compare the opportunity id which i kept in stnmap with the ids in owner_relmailids.
owner_relmailids is contains opportunity owner id and related emails.
and then if both are same then need to send email to the related emails.
i was getting error incompatiable type in iteration.
Could you help me.
I'll answer this in two parts:
First, to directly answer your question, you could iterate and test like this:
Second, I don't think that will be the solution. In the email message area of your code, you are referencing two variables, Appname and stgName, which you haven't declared or assigned anywhere. I think what you might want to do is change your stnmap so that it holds the opportunity, like Map<String, Opportunity> stnmap = new Map<String, Opportunity>(); and stnmap.put(op.OwnerId, op);. That would then allow you to have access to the opportunities' info while you create the mail message in your loop and send the messages after the loop, like so:
Thanks a lot for guiding me in right direction and in finding solution.