1

I am writting the trigger on Custom Object called 'Development Stages'. In object Development Stages there is one field called Status, when my Status is Completed My trigger should get Fired. Developmet Stages is a Detail Object of Building. Building is Parent of Development Stages and Flat. Flat has one field which is lookup to Account. So my Requirment is like when my Status of Development Stages is Completed it should send Email to Contact which is Associated with the Account of that Flat.

Data Model is like this

enter image description here

I have written the code in which i have also implemented the Calculation part also. So In the below trigger Mapping is not getting proper

    trigger DevelopementStageChange on Development_Stage__c (after update) {

         Set<ID> BuildingId = new Set<ID>();

        for(Development_Stage__c  objDevlop:Trigger.new)
        {
            if(objDevlop.Status__c == 'Completed')
            BuildingId.add(objDevlop.Building_Wing__c);
        } 


        List<Flat__c> FlatList = new List<Flat__c>();
        if(BuildingId != null){
            FlatList  = [SELECT id,Name,Owner__c,Flat_Total_Cost__c,Amount_Received__c FROM Flat__c WHERE Building_Wing__c IN:BuildingId AND Owner__c!=null];
        }
        system.debug('FlatList----------->'+FlatList);
        Set<ID> SetAccountID = new Set<ID>();
        for(Flat__c objFlat:FlatList){
            if(objFlat.Owner__c != null){
                SetAccountID.add(objFlat.Owner__c);
            }
        }

        List<Contact> ContactList = new List<Contact>();

        if(SetAccountID!= null){

            ContactList = [SELECT id,name,email,phone FROM contact WHERE accountId IN:SetAccountID];  
         }
         Set<ID> ContactID = new Set<ID>();
         if(ContactList.size()>0){
         SMSUtil util = new SMSUtil();
         String toNumber;
         List<String> ContactPhoneList = new List<String>(); Decimal RemainingValue;

         Decimal TotalPer;

         For(AggregateResult objAgg:[SELECT SUM(Total_Percentage__c)Total FROM Development_Stage__c WHERE Building_Wing__c IN:BuildingId  AND Status__c='Completed']){
                     TotalPer= Double.valueOf(objAgg.get('Total')); 
           }

          List<Messaging.SingleEmailMessage> lstEmailMsg = new List<Messaging.SingleEmailMessage>();
          system.debug('FlatList---------->'+FlatList.size());
            for(Development_Stage__c  objDevlop:Trigger.new){
                   if(objDevlop.Status__c == 'Completed'){

                       Decimal TotalFlat;
                       Decimal AmountRecieved ;
                       for(Flat__c objFlat:FlatList){

                      Messaging.SingleEmailMessage emailMsg = new Messaging.SingleEmailMessage();

                      List<String> emailIds = new List<String>();
                      system.debug('ContactList--------->'+ContactList);
                      for(Contact objCon:ContactList){
                         emailIds.add(objCon.email);
                         ContactID.add(objCon.id);
                        // ContactPhoneList.add(objCon.Phone);
                        toNumber = objCon.phone;

                      }

                      String body;
                      system.debug('Total Percentage---------->'+TotalPer);
                      List<String> EmailBody = new List<String>();

                      Decimal AdvancePaid = objFlat.Flat_Total_Cost__c * (TotalPer/100);
                      system.debug('AdvacnePaid---------->'+AdvancePaid);

                      system.debug('Amount Recieved ----->'+objFlat.Amount_Received__c);

                         if(objFlat.Amount_Received__c  <= AdvancePaid){
                              system.debug('In IF------>');
                              Decimal Pending = AdvancePaid - objFlat.Amount_Received__c- AdvancePaid;
                              body = 'Dear Customer'+' '+objDevlop.Name+' '+'has been completed and your pending amount is=:'+Pending ;  
                       }
                       else{
                             body = 'Dear Customer'+' '+objDevlop.Name+' '+'has been completed and NO Need to pay extra for this Stage';
                       }


                      EmailBody.add(body);

                      emailMsg.setToAddresses(emailIds);
                      emailMsg.setPlainTextBody(body);
                      emailMsg.SaveAsActivity = False;
                      lstEmailMsg.add(emailMsg);       
                   }

                 } 

             }

             system.debug('EmailMessage---->'+lstEmailMsg);
             if(lstEmailMsg.size()>0){
               //  Messaging.sendEmail(lstEmailMsg);
             }
         } 

 }
7
  • You appear to have cut off mid sentence. What's the problem, exactly?
    – Adrian Larson
    Oct 16, 2016 at 13:54
  • It is sending mail to all the owners . Like if i have 3 Accounts for 3 Different Flats so it is sending 3 emails to all the to the Same Account. Oct 16, 2016 at 13:58
  • You can click the "edit" button on the bottom left side of your post to fix your question. Oct 16, 2016 at 15:12
  • Of which flat? A building has many flats, but the development stage is only related to the building. Do you want to send an email to all contacts of accounts that own flats within a building that has a completed development stage?
    – Nick C
    Oct 16, 2016 at 15:22
  • Yes i want to send an email to all contacts of accounts that own flats within a building that has a completed development stage Oct 16, 2016 at 15:59

1 Answer 1

1

Your issue is that you pull back a complete contact list in this section:

    for(Flat__c objFlat:FlatList){
        if(objFlat.Owner__c != null){
            SetAccountID.add(objFlat.Owner__c);
        }
    }
    List<Contact> ContactList = new List<Contact>();

    if(SetAccountID!= null){

        ContactList = [SELECT id,name,email,phone FROM contact WHERE accountId IN:SetAccountID];  
     }

Then add all of them to each email:

List<String> emailIds = new List<String>();
                  system.debug('ContactList--------->'+ContactList);
                  for(Contact objCon:ContactList){
                     emailIds.add(objCon.email);
                     ContactID.add(objCon.id);
                    // ContactPhoneList.add(objCon.Phone);
    toNumber = objCon.phone;
}
...
emailMsg.setToAddresses(emailIds);

Probably the easiest way to do what you are trying to do is to use a child relationship query on Account rather than pulling back contacts. So, change the first section to:

Map<ID, Account> relatedAccounts = new Map<ID, Account>([select ID, (select ID, Email from Contact) from Account where ID in :setAccountIDs]);

Then in your section constructing the email messages:

List<String> emailIds = new List<String>();
List<ID> relatedAccountIds = new List<Account>();
for (Flat__c flat : FlatList)
{
    if (flat.Building_Wing__c == objDevelop.Building_Wing__c)
    {
        relatedAccountIds.add(flat.Owner__c);
    }
}
for (ID relID : relatedAccountIDs)
{
    for (Contact objCon:relatedAccounts.get(relID).Contacts)
    {
        emailIDs.add(objCon.Email);
    }
}

I'll be honest, I haven't looked to make sure this is exactly right - it would make it significantly easier to read your code and identify problems if you incorporated a Trigger Handler class and broke the logical parts of your code into methods. You may also want to define something like a Map<Building__c, List<Account>> where each Account in the List value has a relationship subquery to its list of contacts.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .