Trigger Name: BuyerGroupPricebookTrigger¶
Last Updated: 2025-10-22 Source Code: https://github.com/AANP-IT/I2C.Salesforce.Metadata/blob/STAGING/force-app/main/default/triggers/BuyerGroupPricebookTrigger.trigger
API Name: BuyerGroupPricebookTrigger Object: BuyerGroupPricebook Pattern: Logic-Free Handler Pattern
Business Purpose¶
This trigger maintains product visibility for buyer groups by automatically updating Product2 records when BuyerGroupPricebook associations are created or modified. It ensures that products associated with specific pricebooks become visible to the corresponding buyer groups for B2B Commerce operations, enabling proper catalog segmentation across different customer segments.
Trigger Events¶
This trigger fires on the following events: - ☐ Before Insert - ☐ Before Update - ☐ Before Delete - ☑️ After Insert - ☑️ After Update - ☐ After Delete - ☐ After Undelete
Trigger Handler¶
Handler Class: BuyerGroupPricebookHelper.cls Pattern: Logic-Free - Trigger only routes to helper class Entry Point: Direct helper method call after insert/update
trigger BuyerGroupPricebookTrigger on BuyerGroupPricebook (after insert, after update) {
if (Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)) {
BuyerGroupPricebookHelper.updateVisibleBuyerGroups(Trigger.new);
}
}
Process Flow by Event¶
After Insert¶
Purpose: Add new buyer group visibility to products when pricebook assignments are created
Business Logic: 1. Extract pricebook IDs and buyer group IDs from new BuyerGroupPricebook records (only active records) 2. Query PricebookEntry records for these pricebooks to find associated products 3. Map products to their buyer groups across all pricebook associations 4. Query existing Product2 records to get current VisibleToBuyerGroups__c values 5. Merge new buyer group IDs with existing IDs (comma-separated) 6. Update Product2 records with expanded buyer group visibility
Methods Called:
- BuyerGroupPricebookHelper.updateVisibleBuyerGroups(List<BuyerGroupPricebook> bgpbList)
Related Records Updated: - Product2 records with updated VisibleToBuyerGroups__c field
After Update¶
Purpose: Update product visibility when buyer group pricebook assignments are modified
Conditional Logic: - Fires When: Any field changes on BuyerGroupPricebook records - Only Processes: Records where IsActive = true AND both Pricebook2Id and BuyerGroupId are not null
Business Logic: 1. Same process as After Insert - recalculates product visibility 2. Merges with existing buyer group IDs already on products 3. Updates Product2 records accordingly
Methods Called:
- BuyerGroupPricebookHelper.updateVisibleBuyerGroups(List<BuyerGroupPricebook> bgpbList)
Key Business Rules¶
Validation Rules¶
- Only active BuyerGroupPricebook records (IsActive = true) are processed
- Both Pricebook2Id and BuyerGroupId must be populated
- Buyer group IDs are stored as comma-separated strings on Product2
Field Updates¶
Product2.VisibleToBuyerGroups__c: Comma-separated list of buyer group IDs that can see the product
Related Record Operations¶
- Product2 records updated based on PricebookEntry associations
- Multiple pricebooks can contribute buyer groups to the same product
- Existing buyer groups are preserved (additive only, no removal)
Bulkification & Governor Limits¶
Bulkified: Yes Max Records Handled: Up to 200 BuyerGroupPricebook records SOQL Queries: 2 per transaction (PricebookEntry query, Product2 query) DML Operations: 1 per transaction (Product2 update)
Bulkification Strategy¶
- Collects all pricebook IDs and buyer group IDs into Sets
- Single SOQL query for all PricebookEntry records across all pricebooks
- Single SOQL query for all Product2 records needing updates
- Single DML operation to update all Product2 records
- All processing uses maps and sets for efficient lookup
Governor Limit Considerations¶
- SOQL: 2 queries per transaction regardless of record count
- DML: 1 DML statement updating potentially many Product2 records
- CPU Time: String parsing and manipulation for comma-separated IDs could be intensive
- Heap Size: Large numbers of products/buyer groups could impact heap
Recursion Prevention¶
Strategy: None explicitly implemented
Implementation: - No static variables or recursion flags - Trigger only fires on BuyerGroupPricebook, updates Product2 - Product2 trigger (if exists) would not update BuyerGroupPricebook
Scenarios: - Low recursion risk since updates are cross-object (BuyerGroupPricebook -> Product2) - Product2 triggers should not update BuyerGroupPricebook records
Execution Order & Dependencies¶
Order of Execution Impact¶
- After Insert/Update: Runs after validation rules and before async processes
- Product2 updates happen synchronously in same transaction
Dependent Triggers¶
- ProductTrigger: May be impacted by Product2 updates from this trigger
- Risk: ProductTrigger could perform additional operations when VisibleToBuyerGroups__c changes
Dependent Processes¶
- B2B Commerce catalog visibility
- Product catalog filtering in storefronts
- Any workflows/flows on Product2 object
Error Handling¶
Strategy: No explicit error handling
User Experience: - Success: BuyerGroupPricebook saves, Product2 updates happen synchronously - Validation Error: Standard Salesforce error messages - System Error: Full transaction rollback, error shown to user
Logging: - No logging implemented - Errors only visible in standard Salesforce error messages
Rollback Behavior: - Full transaction rollback on any error - BuyerGroupPricebook records not saved if Product2 updates fail
Dependencies¶
Apex Classes¶
BuyerGroupPricebookHelper: Contains all business logic
Salesforce Objects¶
BuyerGroupPricebook: Primary object being triggeredPricebook2: Referenced for pricebook associationsPricebookEntry: Queried to find product associationsProduct2: Updated with buyer group visibilityBuyerGroup: Referenced via IDs
Custom Settings/Metadata¶
- None currently implemented
External Systems¶
- B2B Commerce Cloud (visibility rules consumed by storefront)
Testing¶
Test Class: BuyerGroupPricebookHelperTest.cls Coverage: Unknown
Test Scenarios: - Single BuyerGroupPricebook insert - Bulk BuyerGroupPricebook insert (200 records) - Update existing BuyerGroupPricebook - Multiple pricebooks with same products - Multiple buyer groups per product - Inactive BuyerGroupPricebook records (should be skipped) - Products with existing VisibleToBuyerGroups__c values - String parsing with comma-separated IDs
Performance Considerations¶
Average Execution Time: Unknown Max Records Processed: 200 BuyerGroupPricebook records affecting potentially thousands of products Async Processing: None - all synchronous
Optimization Opportunities: - Consider async processing for large product updates - Add caching for frequently accessed pricebook/product associations - Implement batch processing for extremely large catalogs - Add field change detection to only process when relevant fields change
Changes & History¶
- Author: Original implementation (team maintained)
- Pattern: Simple logic-free trigger with helper class
Pre-Go-Live Concerns¶
CRITICAL - Fix Before Go-Live¶
- No Error Handling: Any exception in helper class will cause full transaction rollback with no logging
- String Parsing Vulnerability: Parsing comma-separated IDs assumes well-formed data; malformed data could cause exceptions
- Data Integrity: No validation that parsed IDs are valid 18-character Salesforce IDs
HIGH - Address Soon After Go-Live¶
- Additive Only Logic: Buyer groups are added but never removed when pricebook associations are deleted. Need delete trigger or cleanup logic
- No Null Checks: Missing defensive null checks on Product2.VisibleToBuyerGroups__c could cause NullPointerException
- Field Length Limits: VisibleToBuyerGroups__c could exceed field length limit with many buyer groups
- Performance: Synchronous Product2 updates could cause timeout with large catalogs
MEDIUM - Future Enhancement¶
- No Trigger Framework: Could benefit from TriggerHandler framework pattern
- No Trigger Settings: Add Custom Metadata to enable/disable trigger
- No Logging: Implement Custom Object logging for troubleshooting
- Missing Before Delete: Should handle removal of buyer group associations
LOW - Monitor¶
- CPU Time: String manipulation and set operations with large datasets
- Test Coverage: Verify comprehensive test coverage exists
- Documentation: Helper class methods need better inline documentation
Maintenance Notes¶
Complexity: Medium Recommended Review Schedule: Quarterly
Key Maintainer Notes: - This trigger is additive only - does NOT remove buyer groups when associations are deleted - VisibleToBuyerGroups__c is a comma-separated string field - consider changing to proper relationship - No recursion prevention since cross-object updates (BuyerGroupPricebook -> Product2) - All logic is in BuyerGroupPricebookHelper class - trigger is just a router - Always test with bulk operations (200+ records) and large product catalogs - Monitor Product2 trigger to ensure it doesn't cause cascading issues
Deactivation Instructions: Add conditional at start of trigger:
// Check custom metadata for bypass
if (TriggerSettings__mdt.getInstance('BuyerGroupPricebook')?.Disabled__c == true) {
return;
}
Data Load Considerations: - Disable trigger during bulk pricebook loads - Pre-calculate VisibleToBuyerGroups__c values for bulk insert - Re-enable trigger after data load completes