Skip to content

Class Name: PricebookEntryTriggerHandler

Last Updated: 2025-10-22 Source Code: https://github.com/AANP-IT/I2C.Salesforce.Metadata/blob/STAGING/force-app/main/default/classes/PricebookEntryTriggerHandler.cls

API Name: PricebookEntryTriggerHandler Type: Trigger Handler (Change Data Capture) Test Coverage: RenewalPriceUpdateTest

Business Purpose

The PricebookEntryTriggerHandler listens to PricebookEntry Change Events and automatically updates subscription renewal prices when product prices change. This ensures: - Subscription renewal prices stay synchronized with current product prices - Historical price tracking via Previous_Price__c field - Automatic price updates without manual intervention

Class Overview

  • Author: Ryan O'Sullivan
  • Created: 2024-12-20
  • Test Class: RenewalPriceUpdateTest
  • Scope/Sharing: with sharing - Respects record-level security
  • Extends: TriggerHandler
  • Event Type: Platform Event (PriceBookEntryChangeEvent)
  • Supported Events: afterInsert only (change events)

Public Methods

afterInsert

protected override void afterInsert(Map<Id, SObject> newRecordsMap)

Purpose: Processes PricebookEntry change events to update subscription renewal prices.

Business Logic: 1. Adjust PricebookEntries (line 10): Extracts actual PricebookEntry records from change events 2. Update Renewals (line 11): Calls RenewalPriceUpdate to sync subscription prices 3. Update Previous Price (line 12): Stores new price in Previous_Price__c field

Private Methods

adjustPriceBookEntries

private List<PricebookEntry> adjustPriceBookEntries(List<PriceBookEntryChangeEvent> changeEvents)

Purpose: Converts change events to actual PricebookEntry records.

Business Logic: 1. Extracts record IDs from change event headers (line 18) 2. Maps IDs to new unit prices (line 20) 3. Queries actual PricebookEntry records (lines 24-28)

Issues/Concerns: - ⚠️ Unused Map: pricebookEntryIdToNewPrice built but never used - Query doesn't use the price map - Method could be simplified

updatePriceBookEntries

private void updatePriceBookEntries(List<PricebookEntry> pricebookEntries)

Purpose: Updates Previous_Price__c field when prices change.

Business Logic: 1. Compares Previous_Price__c to current UnitPrice (line 36) 2. Updates Previous_Price__c to match current UnitPrice (line 37) 3. Performs bulk update (line 43)

Issues/Concerns: - 🚨 CRITICAL BUG (line 43): Updates pricebookEntries instead of entriesToUpdate - Will update ALL pricebook entries, not just changed ones - Wastes DML rows

Correct Implementation:

if(!entriesToUpdate.isEmpty()){
    update entriesToUpdate; // Not pricebookEntries!
}

Dependencies

Salesforce Objects

  • PricebookEntry (Standard Object)
  • Fields: Id, UnitPrice, Previous_Price__c
  • Event: PriceBookEntryChangeEvent

Other Classes

  • TriggerHandler: Base trigger framework
  • RenewalPriceUpdate: Updates subscription renewal prices

Design Patterns

  1. Change Data Capture: Uses Platform Events for async processing
  2. Event-Driven Architecture: Responds to price changes automatically
  3. Separation of Concerns: Delegates renewal updates to specialized class

Governor Limits Considerations

Current Impact

  • SOQL Queries: 1 per event batch
  • DML Statements: 1 (Previous_Price__c update)
  • Event Processing: Auto-scaled by Salesforce

Scalability

  • Bulk Processing: Handles multiple change events per batch
  • 🚨 Bug Impact: Updates all entries, not just changed (wastes DML rows)

Test Class Requirements

See RenewalPriceUpdateTest (test class exists)

Pre-Go-Live Concerns

🚨 CRITICAL

  • Wrong Variable Updated (line 43): Updates wrong list
  • Fix: update entriesToUpdate;
  • High priority bug fix needed

MEDIUM

  • Unused Map (line 16): pricebookEntryIdToNewPrice never used
  • Remove or utilize for optimization

Changes & History

Date Author Description
2024-12-20 Ryan O'Sullivan Initial implementation for renewal price sync

Documentation Status: ✅ Complete Code Review Status: 🚨 CRITICAL - Line 43 bug must be fixed Test Coverage: RenewalPriceUpdateTest exists