ChartHop by ChartHop
Carrot (CQL)
CQL in Approval Chains
cql in approval chains reference guide approval chains in charthop control who needs to sign off on a scenario before it's merged carrot expressions are used in two places the "only include stage if" condition on a stage (to control whether the stage fires at all) and the approver definition itself (to route to the right person dynamically) this guide covers both how approval chain cql is evaluated before building conditional logic, it helps to understand how charthop evaluates these expressions conditional stage expressions are evaluated against each change in the scenario, not the scenario as a whole — unless you use scenariochanges, which operates at the scenario level the best way to test a change before / change after expression is to use it as a filter on the scenario changes tab if it returns results there, it will fire in the approval chain if a stage's approver resolves to nobody and no fallback approver is set, the chain will stall always configure a fallback approver for any stage that uses dynamic routing stage approver options when setting up a stage, the stage approvers field supports several modes option what it does manager routes to the direct manager of the job being changed grand manager routes to the manager's manager specific person routes to a named individual — always fires for that person person field routes to whoever is in a custom person type field (e g , hiring manager, talent partner) multiple stages, one per manager in the chain creates a dynamic stage for every manager in the hierarchy, all the way up — each approves in sequence custom cql expression define your own routing logic if you use a person field as the approver and the field is blank on a given job, the fallback approver will be used instead conditional stage expressions these go in the "only include stage if" field the stage only fires when the expression evaluates to true trigger only if a specific field changed change before base != change after base works for any field combine multiple fields with || (change before base != change after base) || (change before fieldcode1 != change after fieldcode1) trigger only if manager changed change before manager != change after manager trigger only if a specific person submits the scenario name 'first last' set the condition type to custom and use name with the person's full name this is the confirmed working pattern for submitter based routing scenariochanges expressions scenariochanges operates at the scenario level rather than per change use it when the approval decision should be based on the combined contents of the scenario rather than any individual change these are called approval group inclusion expressions in the platform trigger based on total cost impact across all changes scenariochanges sum{change cost} > 500000 use when you want approval based on the total cost of all changes combined example require vp approval when the combined salary impact of all changes exceeds $500,000 replace the number with your org's threshold trigger if any change in the scenario affects a specific condition scenariochanges any{department='engineering'} use when you want approval if at least one change matches a condition example include the engineering director as an approver whenever any change in the batch affects an engineering employee — even if the rest of the scenario touches other departments trigger only if every change in the scenario matches a condition scenariochanges all{department='engineering'} use when you want approval only if every change matches a condition example route to a specialized engineering approval chain only when the entire batch contains engineering changes skip it if the scenario is mixed across departments combine scenario content with submitter identity scenariochanges all{department='engineering'} && title='ceo' use when you want to combine a condition about the changes with a condition about who is submitting the request example only include this approval stage when all changes are in engineering and the person submitting the request is the ceo this lets you create different approval flows based on both what's changing and who's requesting it common approval chain patterns route to a talent partner or custom role via a person field create a custom person type field (e g , talentpartner) on the job in the approval stage, set stage approvers to that person field charthop will route to whoever is in that field for each job — different jobs can route to different people automatically set a fallback approver for jobs where the field is blank this is one of the most common ways teams handle talent partner or hrbp approval routing without hardcoding names send approvals up the entire manager chain in the stage approvers dropdown, select "multiple stages, one per manager in the manager chain" charthop will dynamically create one approval stage per manager level, from the direct manager up to the top of the org each approves in sequence this feature was built specifically for customers who need every manager in the hierarchy to sign off before a scenario is merged route differently based on department create separate conditional stages, each with its own "only include stage if" condition stage 1 (engineering director) change after department='engineering'stage 2 (finance lead) change after department='finance' stage 3 (final approver) always fires each stage only fires for changes in the relevant department the final stage can be set without a condition so it always fires as the last step regardless of department require approval only above a cost threshold scenariochanges sum{change cost} > 100000 add this as a conditional stage for senior leadership changes below the threshold skip the stage entirely and route only through the standard chain key things to know test before you configure use the expression as a filter on the scenario changes tab first if it returns the changes you expect, it will behave the same way in the approval chain fallback approver matters any stage that uses dynamic routing — person fields, custom cql, manager chain — should have a fallback approver configured if the expression resolves to nobody, the chain falls to the fallback if there's no fallback, the chain stalls one scenario, one approval chain a single scenario routes through one approval chain you can build a lot of conditional logic within that chain, but you can't branch a scenario into two separate chains simultaneously approvers can edit during their stage once it's their turn in the chain, approvers can edit the scenario before approving or rejecting once they act, the scenario is locked for that stage the changes tab is your best debugging tool if a conditional stage isn't firing as expected, check whether your expression returns results there if it doesn't, the expression syntax or field reference needs adjustment
