0

I've created a custom object for Leaves which allows the users under my org to apply for leaves. I've added three types of leaves such as Casual Leave, Sick Leave & Leave without Pay. I've used an Apex Trigger to check and limit the creation of only one record by one user per day but this Apex is creating a problem in org because it isn't allowing the users to apply for pre-planned leaves, i.e. if a user is applying for Sick Leave for the day he/she should also be allowed to apply for other leaves like Casual & Unpaid for different dates on the same day.

Fields I've used:

  • Start_Date__c (Date type)
  • End_Date__c (Date type)
  • Leave_Type__c (Picklist type)

I want to use a trigger dependent on the Start_Date__c & Leave_Type__c

The Apex Currently in use:

trigger LeaveRecordDuplicateTrigger on New_Casual_Leave__c (before insert) {
      for(New_Casual_Leave__c a:Trigger.new)
       {
        string uid = userinfo.getName();
         List<New_Casual_Leave__c> acc=[select Id, CreatedDate, Contact__r.Account.Name,   Start_Date__c, Leave_Type__c from New_Casual_Leave__c where (Contact__r.Account.Name = :uid AND CreatedDate = TODAY)];
             if(acc.size()>0)
             {
               a.adderror('One leave is already applied for the Day For ' + uid);
             }
       }  

} 

Please help me out with this.

3
  • Please add filter : Leave_Type__c =a.Leave_Type__c in your query
    – Ankuli
    Jun 9 '20 at 7:29
  • @Ankuli I should add to the List or in the define section of the query? Jun 9 '20 at 7:31
  • @Ankuli Tried the below query but got the following error: Error: Compile Error: Unexpected token 'a.Leave_Type__c'. at line 5 column 229 Jun 9 '20 at 9:37
2

You just need to bind the variable in your query as you did for uid

and Leave_Type__c = :a.Leave_Type__c

While that answers the question directly, I should point out some issues with the code as is:

  1. You should not put your SOQL query inside a FOR loop even if you're not working with many records right now.
  2. Naming a list of New_Casual_leave__c records as acc is confusing. Variable names should make sense.
  3. Doing all your logic directly in the trigger is not a best practice
  4. Your query is doing the following Contact__r.Account.Name = :uid where uid = userInfo.getName(). Are your account names user names? Would the Contact name be equal to the same name as well? They might be, but I want to point that out (code comments here would be helpful to future co-workers/developers).

Your org may be simple now where you might think it works now, but things change rapidly and it's much harder to go back and fix something than to get it right the first time.

I'd suggest looking at this answer with regards to my points above about bulkification and trigger practices.

In terms of your code, I'll just provide a snippet of what you could do (as an example) to limit the queries and just match on what you're looking for. This limits your SOQL query to only 1 occurrence. You could also use If statements to say both are equal (Account Name on Leave record and Leave Type) as opposed to contains in a set as I've done below

List<New_Casual_Leave__c> existingLeaveRecords = [SELECT Id,Contact__r.Account.Name, Leave_Type__c FROM New_Casual_Leave__c WHERE CreatedDate = TODAY];

//Can simply concatenate your two fields you're looking at instead of check if each is equal to the other. 
Set<String> matchingNameAndLeaveType = new Set<String>();
for(New_Casual_Leave__c leaveRec :existingLeaveRecords){
    matchingNameAndLeaveType.add(leaveRec.Contact__r.Account.Name + Leave_Type__c);
}

for(New_Casual_Leave__c newLeaveRecord : insertedLeaveRecords){
    String leaveNameAndType = newLeaveRecord.Contact__r.Account.Name + newLeaveRecord.Leave_Type__c;
    if(matchingNameAndLeaveType.contains(leaveNameAndType)){
        newLeaveRecord.addError('One leave is already applied for the day for ' + newLeaveRecord.Contact__r.Account.Name);
    }
}
0

Please add filter : Leave_Type__c =a.Leave_Type__c in your query by doing so, it will check if record which is going to create with Leave type already created or not. currently your code doesn't has filter on Leave Type and that's why its conflicting with other leave type.

    trigger LeaveRecordDuplicateTrigger on New_Casual_Leave__c (before insert) {
          for(New_Casual_Leave__c a:Trigger.new)
           {
            string uid = userinfo.getName();
             List<New_Casual_Leave__c> acc=[select Id, CreatedDate, Contact__r.Account.Name,   Start_Date__c, Leave_Type__c from New_Casual_Leave__c 
                                              where (Contact__r.Account.Name = :uid 
                                         AND CreatedDate = TODAY) 
                                        and Leave_Type__c =a.Leave_Type__c];
                 if(acc.size()>0)
                 {
                   a.adderror('One leave is already applied for the Day For ' + uid);
                 }
           }  

    }
2
  • Thank you for suggesting. Tried the query but showed the following error: Error: Compile Error: Unexpected token 'a.Leave_Type__c'. at line 5 column 229 Jun 9 '20 at 9:00
  • it means, field doesn't exist. Please add right field.
    – Ankuli
    Jun 16 '20 at 8:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.