从机会创建服务订单时删除行
Deleting row when creating service order from opportunity
您好 Acumatica 社区!我 运行 遇到了一个问题,希望您能提供帮助。
用户正在根据商机创建服务订单。他们正在使用项目报价。创建服务订单时,我不需要包含某些行,例如服务。我试图找到一种方法来覆盖创建服务订单时的方法,但我没有成功。所以我尝试使用 RowInserting 事件并设置 e.Cancel = true。但是,这样做会给我一个错误 Object reference not set to an instance of the object。我只能假设 CreateServiceOrder 方法在我取消插入后尝试更新该行。
然后我尝试使用 RowUpdated 事件。调试时,好像该行被从缓存中移除了(没有放入脏队列,只是被移除了)。但是,当服务订单完成创建时,该行仍在网格中。我尝试在视图上使用 RequestRefresh,但无济于事。代码的要点如下。一如既往,我们将不胜感激!
public bool _isCreating = false;
protected virtual void FSSODet_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{
var row = e.Row as FSSODet;
if (row == null) return;
if (row.LastModifiedByScreenID == "CR304000" && row.RefNbr.Contains("<NEW>"))
{
if (!_isCreating)
{
_isCreating = true;
InventoryItem item =
PXSelect<InventoryItem,
Where<InventoryItem.inventoryID,
Equal<Required<FSSODet.inventoryID>>>>
.SelectSingleBound(Base, new object[] { }, row.InventoryID);
var itemExt = item.GetExtension<InventoryItemExt>();
if (!(item?.StkItem ?? false))
{
cache.Delete(row);
//Base.ServiceOrderDetails.Delete(row);
Base.ServiceOrderDetails.Cache.RaiseRowDeleting(row);
Base.ServiceOrderDetails.Cache.RaiseRowDeleted(row);
Base.ServiceOrderDetails.View.RequestRefresh();
}
_isCreating = false;
}
}
}
支持从机会报价创建服务订单的流程的代码文件称为 SM_OpportunityMaintExtension。您可以在文件夹 \CodeRepository\PX.Objects.FS 中找到此图。
为了实现您的目标,您将扩展名为 CreateServiceOrderDocument 的方法。因此,创建图形扩展并确保为该方法创建委托。
注意基本方法内部,循环遍历 CROpportunityProducts 的行。您可以在此处添加自定义代码(即挑选并选择要推送到服务订单的项目)下面的示例,如果 DiscountAmount = 0
,则仅推送 CROpportunity 项目
public delegate void CreateServiceOrderDocumentDelegate(OpportunityMaint graphOpportunityMaint, CROpportunity crOpportunityRow, FSCreateServiceOrderFilter fsCreateServiceOrderFilterRow);
[PXOverride]
public void CreateServiceOrderDocument(OpportunityMaint graphOpportunityMaint, CROpportunity crOpportunityRow, FSCreateServiceOrderFilter fsCreateServiceOrderFilterRow,
CreateServiceOrderDocumentDelegate baseMethod)
{
if (graphOpportunityMaint == null
|| crOpportunityRow == null
|| fsCreateServiceOrderFilterRow == null)
{
return;
}
ServiceOrderEntry graphServiceOrderEntry = PXGraph.CreateInstance<ServiceOrderEntry>();
FSServiceOrder newServiceOrderRow = CRExtensionHelper.InitNewServiceOrder(fsCreateServiceOrderFilterRow.SrvOrdType, ID.SourceType_ServiceOrder.OPPORTUNITY);
CRSetup crSetupRow = GetCRSetup();
graphServiceOrderEntry.ServiceOrderRecords.Current = graphServiceOrderEntry.ServiceOrderRecords.Insert(newServiceOrderRow);
CRExtensionHelper.UpdateServiceOrderHeader(graphServiceOrderEntry,
Base.Opportunity.Cache,
crOpportunityRow,
fsCreateServiceOrderFilterRow,
graphServiceOrderEntry.ServiceOrderRecords.Current,
Base.Opportunity_Contact.Current,
Base.Opportunity_Address.Current,
true);
foreach (CROpportunityProducts crOpportunityProductsRow in graphOpportunityMaint.Products.Select())
{
if (crOpportunityProductsRow.DiscAmt == 0) //only add the item to the service order if no discount!!!
{
InventoryItem inventoryItemRow = SharedFunctions.GetInventoryItemRow(graphServiceOrderEntry, crOpportunityProductsRow.InventoryID);
if (inventoryItemRow.StkItem == true
&& graphServiceOrderEntry.ServiceOrderTypeSelected.Current.PostTo == ID.SrvOrdType_PostTo.ACCOUNTS_RECEIVABLE_MODULE)
{
throw new PXException(TX.Error.STOCKITEM_NOT_HANDLED_BY_SRVORDTYPE, inventoryItemRow.InventoryCD);
}
FSxCROpportunityProducts fsxCROpportunityProductsRow = graphOpportunityMaint.Products.Cache.GetExtension<FSxCROpportunityProducts>(crOpportunityProductsRow);
CRExtensionHelper.InsertFSSODetFromOpportunity(graphServiceOrderEntry, graphOpportunityMaint.Products.Cache, crSetupRow, crOpportunityProductsRow, fsxCROpportunityProductsRow, inventoryItemRow);
}
}
graphServiceOrderEntry.ServiceOrderRecords.Current.SourceRefNbr = crOpportunityRow.OpportunityID;
if (!Base.IsContractBasedAPI)
{
throw new PXRedirectRequiredException(graphServiceOrderEntry, null);
}
}
您好 Acumatica 社区!我 运行 遇到了一个问题,希望您能提供帮助。
用户正在根据商机创建服务订单。他们正在使用项目报价。创建服务订单时,我不需要包含某些行,例如服务。我试图找到一种方法来覆盖创建服务订单时的方法,但我没有成功。所以我尝试使用 RowInserting 事件并设置 e.Cancel = true。但是,这样做会给我一个错误 Object reference not set to an instance of the object。我只能假设 CreateServiceOrder 方法在我取消插入后尝试更新该行。
然后我尝试使用 RowUpdated 事件。调试时,好像该行被从缓存中移除了(没有放入脏队列,只是被移除了)。但是,当服务订单完成创建时,该行仍在网格中。我尝试在视图上使用 RequestRefresh,但无济于事。代码的要点如下。一如既往,我们将不胜感激!
public bool _isCreating = false;
protected virtual void FSSODet_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{
var row = e.Row as FSSODet;
if (row == null) return;
if (row.LastModifiedByScreenID == "CR304000" && row.RefNbr.Contains("<NEW>"))
{
if (!_isCreating)
{
_isCreating = true;
InventoryItem item =
PXSelect<InventoryItem,
Where<InventoryItem.inventoryID,
Equal<Required<FSSODet.inventoryID>>>>
.SelectSingleBound(Base, new object[] { }, row.InventoryID);
var itemExt = item.GetExtension<InventoryItemExt>();
if (!(item?.StkItem ?? false))
{
cache.Delete(row);
//Base.ServiceOrderDetails.Delete(row);
Base.ServiceOrderDetails.Cache.RaiseRowDeleting(row);
Base.ServiceOrderDetails.Cache.RaiseRowDeleted(row);
Base.ServiceOrderDetails.View.RequestRefresh();
}
_isCreating = false;
}
}
}
支持从机会报价创建服务订单的流程的代码文件称为 SM_OpportunityMaintExtension。您可以在文件夹 \CodeRepository\PX.Objects.FS 中找到此图。
为了实现您的目标,您将扩展名为 CreateServiceOrderDocument 的方法。因此,创建图形扩展并确保为该方法创建委托。
注意基本方法内部,循环遍历 CROpportunityProducts 的行。您可以在此处添加自定义代码(即挑选并选择要推送到服务订单的项目)下面的示例,如果 DiscountAmount = 0
,则仅推送 CROpportunity 项目public delegate void CreateServiceOrderDocumentDelegate(OpportunityMaint graphOpportunityMaint, CROpportunity crOpportunityRow, FSCreateServiceOrderFilter fsCreateServiceOrderFilterRow);
[PXOverride]
public void CreateServiceOrderDocument(OpportunityMaint graphOpportunityMaint, CROpportunity crOpportunityRow, FSCreateServiceOrderFilter fsCreateServiceOrderFilterRow,
CreateServiceOrderDocumentDelegate baseMethod)
{
if (graphOpportunityMaint == null
|| crOpportunityRow == null
|| fsCreateServiceOrderFilterRow == null)
{
return;
}
ServiceOrderEntry graphServiceOrderEntry = PXGraph.CreateInstance<ServiceOrderEntry>();
FSServiceOrder newServiceOrderRow = CRExtensionHelper.InitNewServiceOrder(fsCreateServiceOrderFilterRow.SrvOrdType, ID.SourceType_ServiceOrder.OPPORTUNITY);
CRSetup crSetupRow = GetCRSetup();
graphServiceOrderEntry.ServiceOrderRecords.Current = graphServiceOrderEntry.ServiceOrderRecords.Insert(newServiceOrderRow);
CRExtensionHelper.UpdateServiceOrderHeader(graphServiceOrderEntry,
Base.Opportunity.Cache,
crOpportunityRow,
fsCreateServiceOrderFilterRow,
graphServiceOrderEntry.ServiceOrderRecords.Current,
Base.Opportunity_Contact.Current,
Base.Opportunity_Address.Current,
true);
foreach (CROpportunityProducts crOpportunityProductsRow in graphOpportunityMaint.Products.Select())
{
if (crOpportunityProductsRow.DiscAmt == 0) //only add the item to the service order if no discount!!!
{
InventoryItem inventoryItemRow = SharedFunctions.GetInventoryItemRow(graphServiceOrderEntry, crOpportunityProductsRow.InventoryID);
if (inventoryItemRow.StkItem == true
&& graphServiceOrderEntry.ServiceOrderTypeSelected.Current.PostTo == ID.SrvOrdType_PostTo.ACCOUNTS_RECEIVABLE_MODULE)
{
throw new PXException(TX.Error.STOCKITEM_NOT_HANDLED_BY_SRVORDTYPE, inventoryItemRow.InventoryCD);
}
FSxCROpportunityProducts fsxCROpportunityProductsRow = graphOpportunityMaint.Products.Cache.GetExtension<FSxCROpportunityProducts>(crOpportunityProductsRow);
CRExtensionHelper.InsertFSSODetFromOpportunity(graphServiceOrderEntry, graphOpportunityMaint.Products.Cache, crSetupRow, crOpportunityProductsRow, fsxCROpportunityProductsRow, inventoryItemRow);
}
}
graphServiceOrderEntry.ServiceOrderRecords.Current.SourceRefNbr = crOpportunityRow.OpportunityID;
if (!Base.IsContractBasedAPI)
{
throw new PXRedirectRequiredException(graphServiceOrderEntry, null);
}
}