We're planning to use Salesforce Contract(or a custom object) to track signed(active) contracts with the customer. Business wants to see on account level if a customer has active contracts.

Designing the solution, I'm planning to implement a trigger that gets all the contracts checks if there's an active contract and sets checkbox hasContract on Account. The only edge case that a trigger can't handle is when no Account updates and no Contract updates happened

Example: Contract Start Date is 1/1/2018, End Date is 1/1/2019. Account.hasContract equals to true. Nor account or contract had any updates since 1/1/2018 until 1/1/2020. For the period from 1/1/2019 to 1/1/2020 the Business would see that the account has Contract, while in reality the contract ended 1/1/2019.

The only solution I could think about is to make a scheduled batch job that updates Account.hasContract field.

Question - is there any other way to handle the edge case? Maybe salesforce provides a standard solution that I just cannot find?


This is basically an example of a time-based rollup field (link is to my own article). There's several ways to handle these, but none of them are deeply satisfying.

The primary alternatives to the trigger + scheduled batch job implementation that you've already designed are two:

  • Using time-based Workflow Rules or Processes. The chief problem with this solution is that it doesn't scale very well. Because time-based actions are limited to processing 1,000 per hour, if your org has any kind of data volume, or has a relatively high concentration of records "turning over" in a particular timespan, your data may be wrong for a while until Salesforce catches up.

    I don't really recommend this solution to anyone except the very smallest orgs, because it doesn't scale and because it degrades silently as your data volume grows.

  • Using the third-party application Declarative Lookup Rollup Summaries. You can define a DLRS rollup to populate a field like "Number of Current Contracts", and use a workflow rule or trigger to set HasContract based on that field. Then run the rollup in both real-time mode and scheduled mode (once per day) to get those time-bound updates.

    All the standard caveats for using DLRS apply. If you're a large-volume org or have complex triggers or expensive transactions on the objects involved, you'll need to very carefully test this in a full-copy sandbox before deploying it.

Given that you've already designed the trigger, I might just opt for the scheduled batch class. It can be very simple: all you need to do is query for Accounts that have HasContract set with an anti-join against Contract, to find the ones needing to be unset, or have HasContract unset with a semi-join against Contract, to find the ones needing to be set. Then execute() just flips the value of the Boolean.

| improve this answer | |
  • Thank you. Time based Workflow wouldn't work if we assume the end date of the contract changes. But RollUp summary solution looks really neat, for the average org we've got. – Curious Squirell Apr 8 at 14:40

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.