Where You need to write Apex that automatically assigns high-value Opportunities to a specific queue when their amount exceeds a dynamic threshold stored in a Custom Setting. How would you handle this?

Automatically Assign High-Value Opportunities to a Queue Using Apex and Custom Settings
In Salesforce, business requirements often evolve over time. One common requirement in sales processes is to route high-value Opportunities to a special team or queue for closer monitoring and faster handling. Hard-coding monetary thresholds in Apex is never recommended because it requires code changes and deployments whenever business rules change.
A Custom Setting–driven approach solves this problem by allowing administrators to update thresholds dynamically without touching code.
This article explains how to design and implement an Apex solution that automatically assigns high-value Opportunities to a specific Queue when their Amount exceeds a configurable threshold stored in a Custom Setting.
1. Problem Statement
You need to implement logic such that:
- When an Opportunity is created or updated
- If the Amount exceeds a dynamic threshold
- And the threshold value is stored in a Custom Setting
- Then the Opportunity Owner should be reassigned to a Queue
- The solution must be:
- Bulk-safe
- Scalable
- Maintainable
- Admin-configurable
- Fully testable
2. High-Level Design Approach
The recommended design uses the Trigger + Handler pattern, which separates logic from triggers and ensures scalability.
Components Involved
| Component | Purpose |
|---|---|
| Custom Setting | Stores the dynamic threshold |
| Queue | Owner for high-value Opportunities |
| Apex Trigger | Executes logic on insert/update |
| Handler Class | Contains business logic |
| Utility Class | Fetches queue ID efficiently |
| Test Class | Ensures correctness and coverage |
3. Why Use a Custom Setting?
A Custom Setting allows Salesforce administrators to change configuration values without deploying code.
Benefits
- No hard-coding of thresholds
- Business-friendly configuration
- Supports org-wide or profile-level overrides
- Faster change management
Type Selection
Hierarchy Custom Setting is recommended because:
- It allows overrides at the Org, Profile, or User level
- It offers flexibility for future enhancements
4. Custom Setting Configuration
Custom Setting Details
- Name:
Opportunity_Config__c - Type: Hierarchy
Fields
| Field Name | Data Type |
|---|---|
High_Value_Threshold__c | Currency (or Number) |
Example value:
High_Value_Threshold__c = 500000
JavaScriptThis means any Opportunity with an Amount ≥ 500,000 is considered high value.
5. Queue Setup
Steps to Create Queue
- Navigate to Setup → Queues
- Create a new Queue:
- Label: High Value Opportunities
- API Name:
High_Value_Opportunities - Supported Object: Opportunity
- Add users or roles as members
The queue’s Group Id will be used as the OwnerId for Opportunities.
6. Trigger Design Considerations
Why Use a before Trigger?
- Ownership changes can be done before insert/update
- No additional DML is required
- Better performance and governor-limit safety
Trigger Events Needed
before insert→ New Opportunitiesbefore update→ Amount changes that cross the threshold
7. Apex Trigger
trigger OpportunityTrigger on Opportunity (before insert, before update) {
if (Trigger.isBefore) {
OpportunityTriggerHandler.assignHighValueOpportunities(
Trigger.new,
Trigger.oldMap
);
}
}
JavaScriptWhy Keep Triggers Thin?
- Triggers should only delegate work
- Logic belongs in handler classes
- Easier maintenance and testing
8. Trigger Handler Class
This class contains the core business logic.
Key Responsibilities
- Read threshold from Custom Setting
- Identify Opportunities exceeding the threshold
- Assign them to the queue
- Ensure logic is bulk-safe
Apex Code
public class OpportunityTriggerHandler {
public static void assignHighValueOpportunities(
List<Opportunity> newOpps,
Map<Id, Opportunity> oldOppMap
) {
// Fetch org-level Custom Setting
Opportunity_Config__c config =
Opportunity_Config__c.getOrgDefaults();
// Safety check
if (config == null || config.High_Value_Threshold__c == null) {
return;
}
Decimal threshold = config.High_Value_Threshold__c;
// Fetch Queue Id
Id queueId = OpportunityQueueUtil.getHighValueQueueId();
if (queueId == null) {
return;
}
for (Opportunity opp : newOpps) {
Boolean isInsert = (oldOppMap == null);
Boolean amountChanged = !isInsert &&
opp.Amount != oldOppMap.get(opp.Id).Amount;
if (
opp.Amount != null &&
opp.Amount >= threshold &&
(isInsert || amountChanged)
) {
opp.OwnerId = queueId;
}
}
}
}
JavaScript9. Queue Utility Class
Fetching the Queue Id repeatedly inside loops can cause governor-limit issues. A utility class with caching avoids this.
public class OpportunityQueueUtil {
private static Id cachedQueueId;
public static Id getHighValueQueueId() {
if (cachedQueueId != null) {
return cachedQueueId;
}
Group queue = [
SELECT Id
FROM Group
WHERE Type = 'Queue'
AND Name = 'High Value Opportunities'
LIMIT 1
];
cachedQueueId = queue.Id;
return cachedQueueId;
}
}
JavaScriptWhy Cache the Queue Id?
- Prevents repeated SOQL calls
- Improves performance in bulk operations
- Follows Salesforce best practices
10. Governor Limit Safety
This solution is governor-limit safe because:
- Only one SOQL query is used
- No DML inside loops
- Logic operates on lists
beforetrigger avoids extra updates
11. Handling Updates Correctly
The logic ensures reassignment only when:
- The Opportunity is newly inserted or
- The Amount has changed and now exceeds the threshold
This prevents unnecessary reassignment when unrelated fields are updated.
12. Unit Testing Strategy
Why Testing Is Critical
- Salesforce requires 75% code coverage
- Tests ensure business rules work correctly
- Protects against regressions
Test Class Implementation
@IsTest
public class OpportunityTriggerTest {
@IsTest
static void testHighValueOpportunityAssignment() {
// Create Custom Setting
Opportunity_Config__c config = new Opportunity_Config__c(
High_Value_Threshold__c = 100000
);
insert config;
// Create Queue
Group queue = new Group(
Name = 'High Value Opportunities',
Type = 'Queue'
);
insert queue;
// Map Queue to Opportunity
QueueSobject qObj = new QueueSobject(
QueueId = queue.Id,
SobjectType = 'Opportunity'
);
insert qObj;
// Create Opportunity
Opportunity opp = new Opportunity(
Name = 'Enterprise Deal',
StageName = 'Prospecting',
CloseDate = Date.today().addDays(30),
Amount = 200000
);
insert opp;
// Verify Owner
Opportunity insertedOpp =
[SELECT OwnerId FROM Opportunity WHERE Id = :opp.Id];
System.assertEquals(queue.Id, insertedOpp.OwnerId);
}
}
JavaScript13. Best Practices Followed
✔ Trigger-handler separation
✔ Dynamic configuration using Custom Settings
✔ Bulk-safe logic
✔ No hard-coded IDs
✔ Efficient SOQL usage
✔ Clear, readable code
✔ Full unit test coverage
14. Possible Enhancements
Use Custom Metadata Instead of Custom Settings
- Better for deployment across orgs
- Version-controlled
- Recommended for enterprise solutions
Add Stage-Based Conditions
- Assign only when Stage = “Negotiation” or “Proposal”
Add Bypass Flag
- Allow admins to temporarily disable automation
Audit Logging
- Store reassignment details in a custom log object
15. Why This Solution Is Interview-Ready
This approach demonstrates:
- Deep understanding of Salesforce architecture
- Knowledge of governor limits
- Clean Apex design patterns
- Admin-friendly configuration
- Enterprise-level scalability
Related Posts

How to Automatically create a follow-up Task when a Lead is converted

How You need to update a related child record whenever a parent record’s status changes, but only if the status is “Closed Won.” How would you design this in Apex?
