这个错误一直困扰着我两个星期。我是Apex的新手所以很容易。
我在After Opportunity Update上有一个触发器。
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;
以查看是否可以手动设置数量。
这个错误意味着什么,我该如何解决?
答案 0 :(得分:0)
您获得的错误通常归因于salesforce需要在后端保持同步的某些类型的特殊字段。例如,如果您添加的行项目与为商机设置的价目表不同,则会出现该错误。
在这种情况下,可能是由于某些外力改变了数量,或者可能是由于订单项的数量是特定值的计划记录。
对于更改数量的外力,我会尝试在调用ProcessSchedule(item)
之前和之后输入调试语句。由于SObject被传递给函数by reference,因此有可能该函数在没有意识到的情况下修改item
。
如果不了解其他一些代码,很难确切地说出问题是什么,但希望这有助于您找到正确的方向!
答案 1 :(得分:0)
试试这个:
OppMap.put(OpportunityList[i].Id, OpportunityList[i].clone(true, true));
克隆调用中的第一个“true”保留了sObjects的ID,第二个指示clone执行深层复制,打破了引用问题。
[编辑]
重新阅读你的帖子我意识到这可能无法解决你的问题 - 对不起!但深度克隆技巧确实有助于引用问题。祝你好运。