You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Salesforce APEX私有函数返回0而非预期值求助

问题原因与解决方案

核心原因

你写的getSumRevenueOnSchedule函数通过SOQL查询数据库,但在Before Insert/Update触发器的执行上下文里,新创建或修改的OpportunityLineItemSchedule记录还未被持久化到数据库中:

  • 如果是Insert操作:数据库里完全没有这些新Schedule,SOQL返回空列表,总和自然是0。
  • 如果是Update操作:SOQL只能查到更新前的旧数据,拿不到当前触发上下文里的新Revenue值。

修复方案

必须把触发上下文里的newSchedules一起纳入计算,不能只依赖数据库查询。可以先将新记录按OpportunityLineItemId分组求和,再加上数据库中已存在的旧记录总和,得到完整的总金额。

修改后的代码示例:

public class OpportunityLineItemScheduleHandler {
    public static void handleBeforeInsertUpdate(List<OpportunityLineItemSchedule> newSchedules) {
        Set<Id> oppLineItemIds = new Set<Id>();
        Map<Id, OpportunityLineItem> oppLineItems = new Map<Id, OpportunityLineItem>();
        // 分组计算触发上下文里新Schedule的收入总和
        Map<Id, Decimal> newScheduleRevenueSum = new Map<Id, Decimal>();

        // 收集商机产品ID并累加新记录的收入
        for (OpportunityLineItemSchedule schedule : newSchedules) {
            oppLineItemIds.add(schedule.OpportunityLineItemId);
            Decimal currentRevenue = schedule.Revenue == null ? 0 : schedule.Revenue;
            if (newScheduleRevenueSum.containsKey(schedule.OpportunityLineItemId)) {
                newScheduleRevenueSum.put(schedule.OpportunityLineItemId, 
                    newScheduleRevenueSum.get(schedule.OpportunityLineItemId) + currentRevenue);
            } else {
                newScheduleRevenueSum.put(schedule.OpportunityLineItemId, currentRevenue);
            }
        }

        // 查询对应的商机产品记录
        oppLineItems.putAll([SELECT Id, Gross_Revenue_Calc__c
                             FROM OpportunityLineItem
                             WHERE Id IN :oppLineItemIds]);

        // 用聚合查询快速获取数据库中已存在的旧Schedule收入总和(排除当前触发的记录)
        Map<Id, AggregateResult> existingScheduleSumMap = new Map<Id, AggregateResult>([
            SELECT OpportunityLineItemId, SUM(Revenue) totalRevenue
            FROM OpportunityLineItemSchedule
            WHERE OpportunityLineItemId IN :oppLineItemIds
            AND Id NOT IN :newSchedules
            GROUP BY OpportunityLineItemId
        ]);

        for (OpportunityLineItemSchedule schedule : newSchedules) {
            OpportunityLineItem oppLineItem = oppLineItems.get(schedule.OpportunityLineItemId);
            if (oppLineItem == null) continue;

            // 计算完整收入总和:新记录总和 + 数据库旧记录总和
            Decimal totalRevenue = newScheduleRevenueSum.get(schedule.OpportunityLineItemId);
            AggregateResult existingSumResult = existingScheduleSumMap.get(schedule.OpportunityLineItemId);
            if (existingSumResult != null) {
                totalRevenue += (Decimal)existingSumResult.get('totalRevenue');
            }

            System.debug(totalRevenue);

            if (totalRevenue > oppLineItem.Gross_Revenue_Calc__c) {
                schedule.addError('产品计划收入总和不能超过商机产品的毛收入。');
            }
        }
    }
}

额外注意点

  • 用AggregateResult做SOQL聚合查询比循环遍历求和更高效,尤其适合数据量较大的场景。
  • 要判断Revenue字段是否为null,避免空指针异常。
  • Update场景下必须排除当前触发的记录ID,防止重复计算旧的Revenue值。

内容的提问来源于stack exchange,提问作者shafi jan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:20:05