Creating a simple Apex trigger that works – but I suspect it is inefficient. Can you guys help?

Like other have said, it's a bad idea to have business logic in a trigger, so your trigger should be something simpler like below:

trigger OpportunityTrigger on Opportunity (before update) {
    if (trigger.isBefore) {
        if (trigger.isUpdate) {
            OpportunityTriggerHandler.isBeforeUpate(trigger.new);
        }
    }
}

The actual business logic can be executed in a trigger handler, which you can also see below.

public OpportunityTriggerHandler {
    public static void isBeforeUpdate(List<Opportunity> opps) {
        validateBusinessNeed(opps);
    }

    public static void validateBusinessNeed(List<Opportunity> opps) {
        List<Id> oppIds = new List<Id>();
        List<Date> productDates = new List<Date>();

        for (Opportunity o : opps) {
            oppIds.add(o.Id);
            productDates.add(o.Product_Date__c);
        }

        List<Opportunity> openNonProfitOpps = [SELECT
                                                  Id
                                                  FROM Opportunity
                                                  WHERE Business_Need__c = 'Non-Profit'
                                                  AND StageName = 'Open'
                                                  AND Product_Date__c IN :productDates
                                                  AND Id IN :oppIds];
        if (openNonProfitOpps.size() > 0) {
            o.addError('Error message goes here');
        }
    }
}

It is a very bad idea to put query inside of loops. It's a very easy way to see a "Too many SOQL queries" error, so you should typically do something like I've done above. In this case, since it seems like you only care that there are any open non-profit opps, a list is fine, but you could also use the query to create a map. You could then iterate over the opps passed from the trigger handler and compare them with the ones in the map created by the SOQL query.

/r/salesforce Thread