function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Somasundaram S 1Somasundaram S 1 

do my code covered governor limit

I have a parent object and child object and am updating the sum of child records to a field in parent
do my below code cover governor limit please advise. 
trigger quantityleft on Sample_Transaction__c (after insert,after update,after delete,after undelete) {
    List<Sample_Lot__c> list_Account= new List<Sample_Lot__c>();
    set<Id> set_Opportunity = new set<Id>();
     if(Trigger.isInsert || Trigger.isUndelete){
        for(Sample_Transaction__c objOpp: trigger.new){
        
        if(objOpp.Completed_Transaction__c == true){
         set_Opportunity.add(objOpp.Parent_id__c);
           }
    }
    }
    
    if(Trigger.isUpdate){
        for(Sample_Transaction__c objOpp: trigger.new){
        
        if(objOpp.Completed_Transaction__c == true){
         set_Opportunity.add(objOpp.Parent_id__c);
           }
  }
    
    
    }
    
    if(Trigger.isdelete){
        for(Sample_Transaction__c objOpp: trigger.old){
        
        if(objOpp.Completed_Transaction__c == true){
         set_Opportunity.add(objOpp.Parent_id__c);
           }
  
    }
    
    }

    if(!set_Opportunity.isEmpty()){
    
    
    
                 Decimal Sum;
       Sum=0;

  for(Sample_Transaction__c sample_transaction : [SELECT id,Sample_Lot_ID__c, Transaction_Quantity__c FROM Sample_Transaction__c WHERE Parent_id__c = : set_Opportunity

]){
            
            Sum+= sample_transaction.Transaction_Quantity__c;
  
    
    for(Sample_Lot__c objAccount : [SELECT Id, Quantity_Left__c FROM Sample_Lot__c WHERE Id = : sample_transaction.Sample_Lot_ID__c]){

 

            objAccount.Quantity_left__c = Sum ;

            list_Account.add(objAccount);

 update objAccount ;

        }
        
 }
}

    
}

 
Shruti SShruti S
SOQLs should never be written inside a for loop (Line 49). You can take the help of Maps to avoid that. Also UPDATE statements should never be inside a for loop (Line 57). Instead you should collect the updated records into a list and finally update the list outside the for loops.
Here is the corrected code - 
trigger quantityleft on Sample_Transaction__c ( after INSERT, after UPDATE, after DELETE, after UNDELETE ) {
    List<Sample_Lot__c> list_Account= new List<Sample_Lot__c>();

    Set<Id> set_Opportunity = new Set<Id>();

    if( Trigger.isInsert || Trigger.isUndelete ){
        for( Sample_Transaction__c objOpp: Trigger.new ) {
            if( objOpp.Completed_Transaction__c == TRUE ){
                set_Opportunity.add( objOpp.Parent_id__c );
            }
        }
    }
    
    if( Trigger.isUpdate ) {
        for( Sample_Transaction__c objOpp: Trigger.new ) {
            if( objOpp.Completed_Transaction__c == TRUE ) {
                set_Opportunity.add( objOpp.Parent_id__c );
            }
        }
    }
    
    if( Trigger.isdelete ) {
        for( Sample_Transaction__c objOpp: Trigger.old ) {
            if( objOpp.Completed_Transaction__c == TRUE ) {
                set_Opportunity.add( objOpp.Parent_id__c );
            }
  
        }
    }

    List<Sample_Transaction__c> sampleTransactionRecords = new List<Sample_Transaction__c>();
    sampleTransactionRecords = [
        SELECT  Id
                ,Sample_Lot_ID__c
                ,Transaction_Quantity__c 
        FROM    Sample_Transaction__c 
        WHERE   Parent_id__c = :set_Opportunity
    ];

    List<String> sampleLotIds = new List<String>();
    for( Sample_Transaction__c sampleTransaction : sampleTransactionRecords ) {
        sampleLotIds.add( sampleTransaction.Sample_Lot_ID__c );
    }

    List<Sample_Lot__c> sampleLotRecords = new List<Sample_Lot__c>();
    sampleLotRecords = [
        SELECT  Id
                ,Name
                ,Quantity_Left__c
        FROM    Sample_Lot__c
        WHERE   Id IN :sampleLotIds
    ];

    Map<String,Sample_Lot__c> mapOfSampleLots = new Map<String,Sample_Lot__c>();
    for( Sample_Lot__c sampleLot : sampleLotRecords ) {
        mapOfSampleLots.put( sampleLot.Id, sampleLot );
    }

    
    if( !set_Opportunity.isEmpty() ) {
        List<Sample_Lot__c> sampleLotsToUpdate = new List<Sample_Lot__c>();

        Decimal Sum = 0;

        for( Sample_Transaction__c sample_transaction : sampleTransactionRecords ) {
            Sum += sample_transaction.Transaction_Quantity__c;

            Sample_Lot__c sampleLot = mapOfSampleLots.get( sample_transaction.Sample_Lot_ID__c );

            sampleLot.Quantity_left__c = Sum;

            sampleLotsToUpdate.add( sampleLot );
        }

        UPDATE sampleLotsToUpdate;
    }
}
Somasundaram S 1Somasundaram S 1
Hi Sruthi
               Thanks for modify the code i got below error in line no 75 , any idea for this error, my previous code didnt 
through this error
Apex trigger quantityleft1 caused an unexpected exception, contact your administrator: quantityleft1: execution of AfterUpdate caused by: System.ListException: Duplicate id in list: a0h0E0000004ZVlQAM: Trigger.quantityleft1: line 75, column 1
Somasundaram S 1Somasundaram S 1
Sruthi
            I solved the issue , i have only one sample lot and modfied the code to get only one sample lot it solved the issue thanks a lot for your pateint and help am new to code , please advise me how to start test class . 
 
Shruti SShruti S
I am curious to know. How did we fix it?
Somasundaram S 1Somasundaram S 1
thanks a lot for your interest and check my post at week end really appreciate your curiousity , please look the below code , i tested in all scenario and its working fine , please let me know if you find any bug in this code , my concern is it should not be in governor limit in future , thanks again for your effort 
I have one more interesting in test class i will post it after you look this below coce 
 
trigger quantityleft1 on Sample_Transaction__c ( after INSERT, after UPDATE, after DELETE, after UNDELETE ) {
   List<Sample_Lot__c> list_lot= new List<Sample_Lot__c>();
     Set<Id> set_transaction = new Set<Id>();
     if( Trigger.isInsert || Trigger.isUndelete ){
        for( Sample_Transaction__c objOpp: Trigger.new ) {
            if( objOpp.Completed_Transaction__c == TRUE ){
                set_transaction.add( objOpp.Parent_id__c );
            }
        }
    }
 

    if( Trigger.isUpdate ) {

        for( Sample_Transaction__c objOpp: Trigger.new ) {

            if( objOpp.Completed_Transaction__c == TRUE ) {

                set_transaction.add( objOpp.Parent_id__c );

            }

        }

    }
 

    if( Trigger.isdelete ) {

       for( Sample_Transaction__c objOpp: Trigger.old ) {

            if( objOpp.Completed_Transaction__c == TRUE ) {

                set_transaction.add( objOpp.Parent_id__c );
            }
          }
    }
    List<Sample_Transaction__c> sampleTransactionRecords = new List<Sample_Transaction__c>();
    sampleTransactionRecords = [
        SELECT  Id
                ,Sample_Lot_ID__c

                ,Transaction_Quantity__c,
                Completed_Transaction__c

        FROM    Sample_Transaction__c

        WHERE   Parent_id__c = :set_transaction

    ];
    List<String> sampleLotIds = new List<String>();
    for( Sample_Transaction__c sampleTransaction : sampleTransactionRecords ) {
        sampleLotIds.add( sampleTransaction.Sample_Lot_ID__c );
    }
    List<Sample_Lot__c> sampleLotRecords = new List<Sample_Lot__c>();
    sampleLotRecords = [
        SELECT  Id
                ,Name
                ,Quantity_Left__c
        FROM    Sample_Lot__c
        WHERE   Id IN :set_transaction

    ];


    Map<String,Sample_Lot__c> mapOfSampleLots = new Map<String,Sample_Lot__c>();

    for( Sample_Lot__c sampleLot : sampleLotRecords ) {

        mapOfSampleLots.put( sampleLot.Id, sampleLot );

    }
    

    if( !set_transaction.isEmpty() ) {

        List<Sample_Lot__c> sampleLotsToUpdate = new List<Sample_Lot__c>();

        Decimal Sum = 0;
        for( Sample_Transaction__c sample_transaction : sampleTransactionRecords ) {
         if( sample_transaction.Completed_Transaction__c == TRUE ) {

            Sum += sample_transaction.Transaction_Quantity__c;

 
}
        }

 for( Sample_Lot__c samplelots : sampleLotRecords ) {

         samplelots.Quantity_left__c=Sum;


    }


        UPDATE sampleLotRecords;

    }

}

 
Shruti SShruti S
Looking at your latest code, I feel that this was not what you had done initially. The requirement seems to have changed. Could you please tell me what exactly is the requirement in simple words?
Somasundaram S 1Somasundaram S 1
i have a parent record and have collection of child records, if the child record completed transaction is true then i get the sum of transaction quanity and update in parent record quantity left.

I may be not mentioned the requirement clearly to you my apologies. 
Shruti SShruti S
That is fine. No problem.

Could you please get me the screenshot from the Schema Builder after selecting these 2 objects?
Somasundaram S 1Somasundaram S 1
pls fine the schema and am admin learning code very curious to know any specific reason for looking schema , i know it will help you to find the relationship other than this have anything in your mind to check it for code ? please adviseUser-added image
Somasundaram S 1Somasundaram S 1
Sruthi
             Apart from checking the code , could you please advise me about test case i wrote the below test class and when i run it shows it covered 82% but am not convinced, the trigger code has after update,after insert, after delete and after undelte , in all i just getting the id of child and parent then i am collectiing child record then getting sum and then updateing the parent field. 
in below test class i just inserted what are the record need for the code but it shows 82% code coverage , for prod move this is fine but my query is how come it covered 82& i didnt do anything for after update after delete undelete and also didnt get sum and update 
could you please advise me
thanks
soma

 
@isTest 
public class testquantityleft{
static testmethod void triggerTest(){
// create account
Account accountOb= new Account();
accountOb.Firstname='name';
accountOb.LastName='1';
accountOb.Credentials__c='MD';
accountOb.SLN__c='123';
accountOb.Specialty_1__c='heart';
Map <String,Schema.RecordTypeInfo> recordTypeMap = Account.sObjectType.getDescribe().getRecordTypeInfosByName();
//Account accountObj = new Account();
//accountObj.name = 'Test Record Type';
if(recordTypeMap.containsKey('Reckitt Person Account')) {
 accountOb.RecordTypeId= recordTypeMap.get('Reckitt Person Account').getRecordTypeId();
}
insert accountOb;
// create address
Address__c address = new Address__c();
address.Account__c = accountOb.id;
//Map <String,Schema.RecordTypeInfo> recordTypeMap1 = Address__c.sObjectType.getDescribe().getRecordTypeInfosByName();
//if(recordTypeMap1.containsKey('Reckitt Address')) {
 //address .RecordTypeId= recordTypeMap.get('Reckitt Address').getRecordTypeId();
//}
address.Name='somaaddress';
insert address;

// create product
Product__c prod = new Product__c();
prod.name ='test';
insert prod;
Sample_Lot__c lot=new Sample_Lot__c();
lot.Name='test lot';
lot.Product_ID__c=prod.id;
lot.Confirmed_Quantity__c=600;
lot.Quantity_Left__c=0;
insert lot;

// create sample transaction

Sample_Transaction__c stransac = new Sample_Transaction__c();
stransac.Account_ID__c = accountob.id;
stransac .Address_ID__c=address.id;
stransac .Quantity__c =100;
stransac .Product__c=prod.id;
stransac .Sample_Lot_ID__c=lot.id;
insert stransac ;
Sample_Transaction__c stransac1 = new Sample_Transaction__c();
stransac1.Account_ID__c = accountob.id;
stransac1 .Address_ID__c=address.id;
stransac1 .Quantity__c =100;
stransac1 .Product__c=prod.id;
stransac1 .Sample_Lot_ID__c=lot.id;
Map <String,Schema.RecordTypeInfo> recordTypeMap2 = Sample_Transaction__c.sObjectType.getDescribe().getRecordTypeInfosByName();
if(recordTypeMap2.containsKey('Reckitt Receipt')) {
 stransac1 .RecordTypeId= recordTypeMap2.get('Reckitt Receipt').getRecordTypeId();
}

insert stransac1 ;

}
}

 
Shruti SShruti S
I have gone through your code, I have few suggestions -
  • Insert assert statements
  • You have to test for both positive as well as negative cases
  • All the lines in the Apex code should be coverd in proper manner
  • Create a common Test Factory method to create records in the test class
Also please refer this link to know more about writing test classes - https://developer.salesforce.com/page/How_to_Write_Good_Unit_Tests