Salesforce.com - 机会订单项的数量更改无效

发布于 2024-12-09 04:04:58 字数 4287 浏览 0 评论 0原文

这个错误已经困扰我两周了。我是 Apex 新手,所以这可能很容易。

我在机会更新后有一个触发器。

trigger triggerOpportunityCloseInstallDateChange on Opportunity (after update) 
{ 
    if(!Validator_cls.IsOpportunityScheduleUpdated())
    {
        Validator_cls.SetOpportunityScheduleUpdatedDone();
        OpportunitySchedule.BuildScheduleAndUpdateDates(trigger.new, true);
    }
}

我在它周围有一个包装器,以确保每次更新只调用一次。

当该触发器触发时,它应该更新行项目的计划日期,进而更新行项目的计划。

public static void BuildScheduleAndUpdateDates(List<Opportunity> OpportunityList, Boolean DoUpdateItems) 
{
    system.debug('***********OpportunitySchedule             : BuildScheduleAndUpdateDates HIT');
    Map<String, Opportunity> OppMap =  new Map<String, Opportunity>();
    List<OpportunityLineItem> ItemsToUpdate = new List<OpportunityLineItem>(); 
    List<String> IdList = new List<String>();

    for (Integer i = 0; i < OpportunityList.size(); i++)
    {
        IdList.add(OpportunityList[i].Id);
        OppMap.put(OpportunityList[i].Id, OpportunityList[i]);
    }

    List<OpportunityLineItem> lineItems = [Select o.Id, (Select OpportunityLineItemId From OpportunityLineItemSchedules), o.Opportunity.Id, o.Systems_Add_On__c, o.ServiceDate, o.Product_Family__c, o.Schedule_Length__c , o.Monthly_Quantity__c, o.Monthly_Amount__c, o.Quantity
                                            From OpportunityLineItem o
                                            where o.Opportunity.Id in:IdList];

        for (OpportunityLineItem item : lineItems)
        {   
            Opportunity opp_new = OppMap.get(item.Opportunity.Id);

            Boolean hasSchedule = OpportunityProductLineItems.DoesLineItemHaveSchedule(item.Id);

            if (opp_new.Term_Conversion__c != null)
            {   
                item.ServiceDate = opp_new.CloseDate;
            }
            else
            {
                if(item.Product_Family__c == 'Systems')
                {
                    if(item.Systems_Add_On__c == true)
                    {
                        item.ServiceDate = opp_new.Install_Date__c;
                        system.debug('***********BuildScheduleAndUpdateDates     : Systems With Systems Add On ' + item.ServiceDate);
                    }
                    else
                    {
                        item.ServiceDate = opp_new.Install_Date__c.addDays(30); 
                        system.debug('***********BuildScheduleAndUpdateDates     : Systems With NO Systems Add On ' + item.ServiceDate);
                    }
                }
                else if(hasSchedule)
                {
                    item.ServiceDate = opp_new.Install_Date__c.addDays(30); 
                    system.debug('***********BuildScheduleAndUpdateDates     : Has Schedule ' + item.ServiceDate);
                }
                else
                {
                    item.ServiceDate = opp_new.Install_Date__c;
                    system.debug('***********BuildScheduleAndUpdateDates     : No Schedule ' + item.ServiceDate);
                }
            }

            //item.Quantity = 1;
            ItemsToUpdate.add(item);
            if(hasSchedule && !DoUpdateItems)
            {
                ProcessSchedule(item);
            }
        } 

    if(DoUpdateItems)
    {
        update ItemsToUpdate;
    }    
    upsert schedulesToUpsert;

}

当我更新机会时,我收到此错误:

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger triggerOpportunityCloseInstallDateChange caused an unexpected exception, contact your administrator: triggerOpportunityCloseInstallDateChange: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 00kV0000002cHhTIAU; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: unknown (invalid quantity change on opportunity line item): [unknown]: Class.OpportunitySchedule.BuildScheduleAndUpdateDates: line 68, column 1

该错误对应于这一行

update ItemsToUpdate;

正如您在上面看到的,我没有更改该行项目的数量。我很困惑。如果我注释掉该行,一切都会正常(时间表已构建并更新)。

我什至输入了 item.Quantity = 1; 来看看是否可以手动设置数量。

这个错误是什么意思,我该如何克服它?

This error has been plaguing me for two weeks now. I'm new to Apex so it might be easy.

I have a trigger on After Opportunity Update.

trigger triggerOpportunityCloseInstallDateChange on Opportunity (after update) 
{ 
    if(!Validator_cls.IsOpportunityScheduleUpdated())
    {
        Validator_cls.SetOpportunityScheduleUpdatedDone();
        OpportunitySchedule.BuildScheduleAndUpdateDates(trigger.new, true);
    }
}

I have that wrapper around it to make sure it only gets called once per update.

When that trigger fires, it is supposed to update the schedule date on the line items, that in-turn updates the line items schedule.

public static void BuildScheduleAndUpdateDates(List<Opportunity> OpportunityList, Boolean DoUpdateItems) 
{
    system.debug('***********OpportunitySchedule             : BuildScheduleAndUpdateDates HIT');
    Map<String, Opportunity> OppMap =  new Map<String, Opportunity>();
    List<OpportunityLineItem> ItemsToUpdate = new List<OpportunityLineItem>(); 
    List<String> IdList = new List<String>();

    for (Integer i = 0; i < OpportunityList.size(); i++)
    {
        IdList.add(OpportunityList[i].Id);
        OppMap.put(OpportunityList[i].Id, OpportunityList[i]);
    }

    List<OpportunityLineItem> lineItems = [Select o.Id, (Select OpportunityLineItemId From OpportunityLineItemSchedules), o.Opportunity.Id, o.Systems_Add_On__c, o.ServiceDate, o.Product_Family__c, o.Schedule_Length__c , o.Monthly_Quantity__c, o.Monthly_Amount__c, o.Quantity
                                            From OpportunityLineItem o
                                            where o.Opportunity.Id in:IdList];

        for (OpportunityLineItem item : lineItems)
        {   
            Opportunity opp_new = OppMap.get(item.Opportunity.Id);

            Boolean hasSchedule = OpportunityProductLineItems.DoesLineItemHaveSchedule(item.Id);

            if (opp_new.Term_Conversion__c != null)
            {   
                item.ServiceDate = opp_new.CloseDate;
            }
            else
            {
                if(item.Product_Family__c == 'Systems')
                {
                    if(item.Systems_Add_On__c == true)
                    {
                        item.ServiceDate = opp_new.Install_Date__c;
                        system.debug('***********BuildScheduleAndUpdateDates     : Systems With Systems Add On ' + item.ServiceDate);
                    }
                    else
                    {
                        item.ServiceDate = opp_new.Install_Date__c.addDays(30); 
                        system.debug('***********BuildScheduleAndUpdateDates     : Systems With NO Systems Add On ' + item.ServiceDate);
                    }
                }
                else if(hasSchedule)
                {
                    item.ServiceDate = opp_new.Install_Date__c.addDays(30); 
                    system.debug('***********BuildScheduleAndUpdateDates     : Has Schedule ' + item.ServiceDate);
                }
                else
                {
                    item.ServiceDate = opp_new.Install_Date__c;
                    system.debug('***********BuildScheduleAndUpdateDates     : No Schedule ' + item.ServiceDate);
                }
            }

            //item.Quantity = 1;
            ItemsToUpdate.add(item);
            if(hasSchedule && !DoUpdateItems)
            {
                ProcessSchedule(item);
            }
        } 

    if(DoUpdateItems)
    {
        update ItemsToUpdate;
    }    
    upsert schedulesToUpsert;

}

When I update an opportunity, I get this error:

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger triggerOpportunityCloseInstallDateChange caused an unexpected exception, contact your administrator: triggerOpportunityCloseInstallDateChange: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 00kV0000002cHhTIAU; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: unknown (invalid quantity change on opportunity line item): [unknown]: Class.OpportunitySchedule.BuildScheduleAndUpdateDates: line 68, column 1

That error corresponds to this line

update ItemsToUpdate;

As you can see above, I'm not changing the quantity on that line item. I'm so confused. If I comment out that line, everything works fine (the schedule is built and updated).

I've even put in item.Quantity = 1; to see if I could manually set the quantity.

What does this error mean, and how do I get past it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

氛圍 2024-12-16 04:04:58

您收到的错误通常归因于 salesforce 需要在后端保持同步的某种类型的特殊字段。例如,如果您添加的行项目的价目表与为商机设置的价目表不同,则会出现该错误。

在这种情况下,可能是由于某些外力改变了数量,或者可能是由于计划记录依赖于行项目的数量为特定值。

对于改变数量的外力,我会尝试在调用 ProcessSchedule(item) 之前和之后放置调试语句。由于 SObject 通过引用传递给函数 ,该函数可能正在修改 item 而您却没有意识到。

如果不知道其他一些代码,很难准确说出问题可能是什么,但希望这将帮助您走向正确的方向!

The error you are getting is typically attributed to some type of special fields that salesforce needs to keep synchronized on the back end. For example, that error will come up if you add a Line Item with a different Pricebook than the one set for the Opportunity.

In this instance, it is probably due to either some external force changing the quantity or possibly Schedule Records relying on the Line Item's quantity being a specific value.

For the external force changing the quantity, I would try putting a debug statement before and after your call to ProcessSchedule(item). Since SObjects are passed to functions by reference, it is possible that that function is modifying item without you realizing it.

It's hard to say exactly what the issue might be without knowing some of the other code, but hopefully this will help get you in the right direction!

执笏见 2024-12-16 04:04:58

试试这个:

OppMap.put(OpportunityList[i].Id, OpportunityList[i].clone(true, true));

克隆调用中的第一个“true”保留 sObject 的 Id,第二个指示克隆执行深度复制,从而解决了引用问题。

[编辑]

重新阅读您的帖子我意识到这可能无法解决您的问题 - 抱歉!但深度克隆技巧确实有助于解决引用问题。祝你好运。

Try this:

OppMap.put(OpportunityList[i].Id, OpportunityList[i].clone(true, true));

The first "true" in the clone call retains the Ids of your sObjects and the second instructs clone to perform a deep copy, breaking the by reference problem.

[Edit]

Re-reading your post I realized that this might not solve your problem - sorry! But the deep clone trick does help with the by reference problem. Good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文