ApexSensei

Drills › Automate with triggers

Block deleting Accounts with open deals

Automate with triggers · Advanced · 20 min · Runs in your Salesforce Developer org · Apex Path

Scenario. Sales ops keeps losing pipeline when someone deletes an Account that still has live deals. A delete should only work once every deal on the Account is closed.

Write a before delete trigger that uses Trigger.oldMap and one query to stop Accounts with open Opportunities from being deleted.

What you will learn

A delete trigger has no Trigger.new. The records being deleted are in Trigger.old, and Trigger.oldMap maps each Id to its record. In before delete, addError on a record in Trigger.old stops that one delete.

for (Account row : Trigger.old) {
    row.addError('Not allowed.');
}

Gotcha. IsClosed is true for won and for lost deals, so IsClosed = false means open. Query once for all the Accounts, not once per Account.

The task

Write the body of the Account trigger so an Account that still has an open Opportunity cannot be deleted.

Examples:

  • an Account with an open Opportunity → the delete fails with This Account has open Opportunities and cannot be deleted.
  • an Account with only closed Opportunities, or none → deletes as normal
  • 200 Accounts deleted with Database.delete(accounts, false) → only the ones with open deals stay

Requirements:

  1. Keep the before delete event from the starter.
  2. Run one query, outside any loop, for Opportunities WHERE AccountId IN :Trigger.oldMap.keySet() AND IsClosed = false.
  3. Put each open Opportunity's AccountId in the accountsWithOpenDeals Set.
  4. Loop over Trigger.old and call addError('This Account has open Opportunities and cannot be deleted.') once on each Account in the Set.
  5. Leave every other Account alone so it deletes.

Starter code

trigger AS_34784F4B6BCF_AccountDelete on Account (before delete) {
    Set<Id> accountsWithOpenDeals = new Set<Id>();
    for (Account account : Trigger.old) {
    }
}

When it passes

An Account with an open Opportunity gets exactly one error with the exact message and stays in the org. Accounts with only closed Opportunities, or none, delete. A mixed 200-Account delete blocks exactly the right ones and uses the same number of queries as 2 Accounts.

Try this drill free

You write the Apex yourself. ApexSensei runs it and tells you what passed and what did not.

‹ Stop recursive Account updates · Keep a Contact count on Account ›