1

I have a before trigger that updates a lead field: Rate_Total__c. I would like help building in the following logic:

-The trigger should not run IF any user updates Rate_Total__c manually.

This would be easy enough, except if the user edits and saves the page a 2nd time (without manually updating Rate_Total__c), the trigger will fire and overwrite the once manually entered rate. I need a method to prevent this.

Once there is a manually entered rate, the trigger should never fire again on that lead.

Any help is much appreciated. Here is the trigger.

EDIT: The code below is the solution. I used a checkbox override system instead of the original idea.

trigger calcSum on Lead (before insert, before update) 
{
    Set<Date> dates = new Set<Date>();
    Set<String> property = new Set<String>();
    Map<Date, Decimal> cost = new Map<Date, Decimal>();
    Map<Date, String> undates = new Map<Date, String>();
    Lead[] validLeads = new Lead[0];

    for(Lead record: Trigger.new)
    {
        if (record.Override_Rate_Total__c == false)
        {
            record.Rate_total__c = 0;

                if(record.Arrival_Date__c != null && record.Departure_Date__c != null && record.Property__c != null) 
                {
                    validLeads.add(record);
                    Date tempDate = record.Arrival_Date__c;                //Store Lead Arrival Date
                    String tempProperty = record.Property__c;              //Store Lead Property
                    property.add(tempProperty);                            //Add Lead Property to property SET

                    while(tempDate < record.Departure_Date__c)             //While Lead Arrival Date is less than Lead Departure Date, Add the date to the dates SET and cycle 1 day forward.
                    {
                        dates.add(tempDate);                               
                        tempDate = tempDate.addDays(1);
                    }
                }
        }        
    }

    for(Property_Rate__c record:[SELECT Property__c, Rate__c,Date__c, Status__c FROM Property_Rate__c WHERE Date__c IN :dates AND Property__c IN :property])    //Query Property rates for the property and between the dates
    {
        if (record.Status__c == 'Available' && record.Rate__c != null)                        //If the Property Rate is available and the rate is not NULL...
        {                                                                                                                                                   
            cost.put(record.Date__c, record.Rate__c);                                        //Map date-rate relationship and add to cost MAP
        }
        else                                                                                                 //Otherwise...
        {
            undates.put(record.Date__c, record.Status__c);                                   //Add to Unavailability undates MAP
        }                                                                                                    
    }

    for(Lead record: validLeads)                                       //Main Trigger function
    {
        Date tempDate = record.Arrival_Date__c;                        //Store Lead arrival Date                                                                  

        while(tempDate < record.Departure_Date__c)                     //While Arrival Date is less than Departure Date...
        {
            Decimal dayRate = cost.get(tempDate);                      //Retreive Arrival Date from cost MAP...

            if(dayRate != null && undates.isEmpty())                   //If the Arrival Date is in cost MAP AND there aren't any unavailable dates in undates MAP...                
            {
                record.Rate_Total__c += cost.get(tempDate);            //Add Rate__c to Rate Total from cost MAP and cycle to the next day until Departure Date... Check Availability...
                record.Dates_Available__c = true;
            }
            else if (undates.size() > 0)                                             
            {
                cost.clear();                                                      //If the above is NOT true, CLEAR cost MAP. Or Arrival Date more than Departure Date... Uncheck Availability...
                record.Dates_Available__c = false;
            }


            tempDate = tempDate.addDays(1);                            
        }
    }
}
3
  • 1
    You should check out the Selector library, it will make your life way easier.
    – Adrian Larson
    Aug 19, 2015 at 17:52
  • @AdrianLarson Wow that does look convenient! Do you have any advice in regards to the manual-over-riding over the trigger though? That is the part I am really having trouble with. Aug 19, 2015 at 17:57
  • that's just how cloud architecture works...both contexts would apply the same logic though, no?
    – Adrian Larson
    Aug 19, 2015 at 18:00

2 Answers 2

1

The code below was my solution. I used a check-box override system instead of the original idea. Works just as well and is easy to train staff on!

trigger calcSum on Lead (before insert, before update) 
{
    Set<Date> dates = new Set<Date>();
    Set<String> property = new Set<String>();
    Map<Date, Decimal> cost = new Map<Date, Decimal>();
    Map<Date, String> undates = new Map<Date, String>();
    Lead[] validLeads = new Lead[0];

    for(Lead record: Trigger.new)
    {
        if (record.Override_Rate_Total__c == false)
        {
            record.Rate_total__c = 0;

                if(record.Arrival_Date__c != null && record.Departure_Date__c != null && record.Property__c != null) 
                {
                    validLeads.add(record);
                    Date tempDate = record.Arrival_Date__c;                //Store Lead Arrival Date
                    String tempProperty = record.Property__c;              //Store Lead Property
                    property.add(tempProperty);                            //Add Lead Property to property SET

                    while(tempDate < record.Departure_Date__c)             //While Lead Arrival Date is less than Lead Departure Date, Add the date to the dates SET and cycle 1 day forward.
                    {
                        dates.add(tempDate);                               
                        tempDate = tempDate.addDays(1);
                    }
                }
        }        
    }

    for(Property_Rate__c record:[SELECT Property__c, Rate__c,Date__c, Status__c FROM Property_Rate__c WHERE Date__c IN :dates AND Property__c IN :property])    //Query Property rates for the property and between the dates
    {
        if (record.Status__c == 'Available' && record.Rate__c != null)                        //If the Property Rate is available and the rate is not NULL...
        {                                                                                                                                                   
            cost.put(record.Date__c, record.Rate__c);                                        //Map date-rate relationship and add to cost MAP
        }
        else                                                                                                 //Otherwise...
        {
            undates.put(record.Date__c, record.Status__c);                                   //Add to Unavailability undates MAP
        }                                                                                                    
    }

    for(Lead record: validLeads)                                       //Main Trigger function
    {
        Date tempDate = record.Arrival_Date__c;                        //Store Lead arrival Date                                                                  

        while(tempDate < record.Departure_Date__c)                     //While Arrival Date is less than Departure Date...
        {
            Decimal dayRate = cost.get(tempDate);                      //Retreive Arrival Date from cost MAP...

            if(dayRate != null && undates.isEmpty())                   //If the Arrival Date is in cost MAP AND there aren't any unavailable dates in undates MAP...                
            {
                record.Rate_Total__c += cost.get(tempDate);            //Add Rate__c to Rate Total from cost MAP and cycle to the next day until Departure Date... Check Availability...
                record.Dates_Available__c = true;
            }
            else if (undates.size() > 0)                                             
            {
                cost.clear();                                                      //If the above is NOT true, CLEAR cost MAP. Or Arrival Date more than Departure Date... Uncheck Availability...
                record.Dates_Available__c = false;
            }


            tempDate = tempDate.addDays(1);                            
        }
    }
}
0

You could create a Date Rate Updated field and only set it when the Rate is manually entered by a user, then use that in your trigger to see if it was manually set or not.

11
  • Thank you for your answer. Could you elaborate? How will the trigger recognize if the entry was made manually by a user, or automatically entered by the trigger itself? Aug 19, 2015 at 20:15
  • @AlexBrigham Compare the trigger.old value to the trigger.new value and if it's changed then stamp it.
    – Jenny B
    Aug 19, 2015 at 20:17
  • This was my instinct as well. This won't work because the result of the trigger is a field update to Rate_Total__c. So the trigger can't tell the difference between when trigger.old was manually entered, and when it was entered by the trigger. I think I will have to explore some work-arounds Aug 19, 2015 at 20:23
  • @AlexBrigham but you would check this before the rest of the trigger ran and not run that part of the trigger since it will be stamped already. Then future runs will also see it stamped.
    – Jenny B
    Aug 19, 2015 at 20:25
  • The issue is that if the Trigger itself changes the value, it would still notice the change from Trigger.old to Trigger.new, and stamp it, Disabling itself upon the second run. Correct me if I'm mistaken, of course! Aug 20, 2015 at 19:31

You must log in to answer this question.

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