从机会创建服务订单时删除行

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);
        }            
    }