Acumatica 针灸-写关系的方法在哪里?

Acumatica 针灸-写关系的方法在哪里?,acumatica,Acumatica,在从Opportunity创建销售订单时,有人能帮我找到Acumatica在代码中写入CRRelation表的位置吗?我已经搜索了“CRRelation”的所有实例,但它们似乎都没有实际写入表。这是在DoCreateSalesOrder(CreateSalesOrderFilter参数)方法中完成的,该方法在CreateSalesOrder操作中调用: public PXAction<CROpportunity> createSalesOrder; [PXUIField(Displ

在从Opportunity创建销售订单时,有人能帮我找到Acumatica在代码中写入CRRelation表的位置吗?我已经搜索了“CRRelation”的所有实例,但它们似乎都没有实际写入表。

这是在
DoCreateSalesOrder(CreateSalesOrderFilter参数)
方法中完成的,该方法在
CreateSalesOrder
操作中调用:

public PXAction<CROpportunity> createSalesOrder;

[PXUIField(DisplayName = Messages.CreateSalesOrder, MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
public virtual IEnumerable CreateSalesOrder(PXAdapter adapter)
{
    foreach (CROpportunity opportunity in adapter.Get())
    {
        Customer customer = (Customer)PXSelect<Customer, Where<Customer.bAccountID, Equal<Current<CROpportunity.bAccountID>>>>
            .SelectSingleBound(this, new object[] { opportunity });
        if (customer == null)
        {
            throw new PXException(Messages.ProspectNotCustomer);
        }

        var products = Products.View.SelectMultiBound(new object[] { opportunity }).RowCast<CROpportunityProducts>();
        if (products.Any(_ => _.InventoryID == null) && !products.Any(_ => _.InventoryID != null))
        {
            throw new PXException(Messages.SalesOrderHasOnlyNonInventoryLines);
        }

        if (CreateOrderParams.AskExtFullyValid((graph, viewName) => { }, DialogAnswerType.Positive))
        {
            Save.Press();
            PXLongOperation.StartOperation(this, delegate()
            {
                var grapph = PXGraph.CreateInstance<OpportunityMaint>();
                grapph.Opportunity.Current = opportunity;
                grapph.CreateOrderParams.Current = CreateOrderParams.Current;
                grapph.DoCreateSalesOrder(CreateOrderParams.Current);
            });
        }
        yield return opportunity;
    }
}
您可以在下面找到该方法的完整代码:

protected virtual void DoCreateSalesOrder(CreateSalesOrderFilter param)
{
    bool recalcAny = param.RecalculatePrices == true ||
                     param.RecalculateDiscounts == true ||
                     param.OverrideManualDiscounts == true ||
                     param.OverrideManualDocGroupDiscounts == true ||
                     param.OverrideManualPrices == true;

    var opportunity = this.Opportunity.Current;
    Customer customer = (Customer)PXSelect<Customer, Where<Customer.bAccountID, Equal<Current<CROpportunity.bAccountID>>>>.Select(this);

    SOOrderEntry docgraph = PXGraph.CreateInstance<SOOrderEntry>();

    CurrencyInfo info = PXSelect<CurrencyInfo, Where<CurrencyInfo.curyInfoID, Equal<Current<CROpportunity.curyInfoID>>>>.Select(this);
    info.CuryInfoID = null;
    info = CurrencyInfo.GetEX(docgraph.currencyinfo.Insert(info.GetCM()));

    SOOrder doc = new SOOrder();
    doc.OrderType = CreateOrderParams.Current.OrderType ?? SOOrderTypeConstants.SalesOrder;
    doc = docgraph.Document.Insert(doc);
    doc = PXCache<SOOrder>.CreateCopy(docgraph.Document.Search<SOOrder.orderNbr>(doc.OrderNbr));

    doc.CuryInfoID = info.CuryInfoID;
    doc = PXCache<SOOrder>.CreateCopy(docgraph.Document.Update(doc));

    doc.CuryID = info.CuryID;
    doc.OrderDate = Accessinfo.BusinessDate;
    doc.OrderDesc = opportunity.Subject;
    doc.TermsID = customer.TermsID;
    doc.CustomerID = opportunity.BAccountID;
    doc.CustomerLocationID = opportunity.LocationID ?? customer.DefLocationID;
    if (opportunity.TaxZoneID != null)
    {
    doc.TaxZoneID = opportunity.TaxZoneID;
        if (!recalcAny)
        {
        SOTaxAttribute.SetTaxCalc<SOLine.taxCategoryID>(docgraph.Transactions.Cache, null, TaxCalc.ManualCalc);
            SOTaxAttribute.SetTaxCalc<SOOrder.freightTaxCategoryID>(docgraph.Document.Cache, null,
                TaxCalc.ManualCalc);
        }
    }
    doc.ProjectID = opportunity.ProjectID;
    doc.BranchID = opportunity.BranchID;
    doc = docgraph.Document.Update(doc);

    var campaignRelation = docgraph.RelationsLink.Insert();
    campaignRelation.RefNoteID = doc.NoteID;
    campaignRelation.Role = CRRoleTypeList.Source;
    campaignRelation.TargetType = CRTargetEntityType.CROpportunity;
    campaignRelation.TargetNoteID = opportunity.NoteID;
    campaignRelation.DocNoteID = opportunity.NoteID;
    campaignRelation.EntityID = opportunity.BAccountID;
    campaignRelation.ContactID = opportunity.ContactID;
    docgraph.RelationsLink.Update(campaignRelation);

    bool failed = false;
    foreach (CROpportunityProducts product in SelectProducts(opportunity.QuoteNoteID))
    {
        if (product.SiteID == null)
        {
            InventoryItem item = (InventoryItem)PXSelectorAttribute.Select<CROpportunityProducts.inventoryID>(Products.Cache, product);
            if (item != null && item.NonStockShip == true)
            {
                Products.Cache.RaiseExceptionHandling<CROpportunityProducts.siteID>(product, null,
                    new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(CROpportunityProducts.siteID).Name));
                failed = true;
            }
        }

        SOLine tran = new SOLine();
        tran = docgraph.Transactions.Insert(tran);
        if (tran != null)
        {
            tran.InventoryID = product.InventoryID;
            tran.SubItemID = product.SubItemID;
            tran.TranDesc = product.Descr;
            tran.OrderQty = product.Quantity;
            tran.UOM = product.UOM;
            tran.CuryUnitPrice = product.CuryUnitPrice;
            tran.TaxCategoryID = product.TaxCategoryID;
            tran.SiteID = product.SiteID;
            tran.IsFree = product.IsFree;
            tran.ProjectID = product.ProjectID;
            tran.TaskID = product.TaskID;
            tran.CostCodeID = product.CostCodeID;
            tran.ManualPrice = true;
            tran.ManualDisc = true;
            tran.CuryDiscAmt = product.CuryDiscAmt;
            tran.DiscAmt = product.DiscAmt;
            tran.DiscPct = product.DiscPct;
            tran.POCreate = product.POCreate;
            tran.VendorID = product.VendorID;

            if (param.RecalculatePrices != true)
            {
                tran.ManualPrice = true;
            }
            else
            {
                if (param.OverrideManualPrices != true)
                    tran.ManualPrice = product.ManualPrice;
                else
                    tran.ManualPrice = false;
            }

            if (param.RecalculateDiscounts != true)
            {
                tran.ManualDisc = true;
            }
            else
            {
                if (param.OverrideManualDiscounts != true)
                    tran.ManualDisc = product.ManualDisc;
                else
                    tran.ManualDisc = false;
            }

            tran.CuryDiscAmt = product.CuryDiscAmt;
            tran.DiscAmt = product.DiscAmt;
            tran.DiscPct = product.DiscPct;
        }

        tran = docgraph.Transactions.Update(tran);
        PXNoteAttribute.CopyNoteAndFiles(Products.Cache, product, docgraph.Transactions.Cache, tran,
            Setup.Current);
    }

    PXNoteAttribute.CopyNoteAndFiles(Opportunity.Cache, opportunity, docgraph.Document.Cache, doc, Setup.Current);

    if (failed)
        throw new PXException(Messages.SiteNotDefined);

    //Skip all customer dicounts
    if (param.RecalculateDiscounts != true && param.OverrideManualDiscounts != true)
    {
        var discounts = new Dictionary<string, SOOrderDiscountDetail>();
        foreach (SOOrderDiscountDetail discountDetail in docgraph.DiscountDetails.Select())
        {
            docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.skipDiscount>(discountDetail, true);
            string key = discountDetail.Type + ':' + discountDetail.DiscountID + ':' + discountDetail.DiscountSequenceID;
            discounts.Add(key, discountDetail);
        }
        Discount ext = this.GetExtension<Discount>();
        foreach (CROpportunityDiscountDetail discountDetail in ext.DiscountDetails.Select())
        {
            SOOrderDiscountDetail detail;
            string key = discountDetail.Type + ':' + discountDetail.DiscountID + ':' + discountDetail.DiscountSequenceID;
            if (discounts.TryGetValue(key, out detail))
            {
                docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.skipDiscount>(detail, false);
                if (discountDetail.IsManual == true && discountDetail.Type == DiscountType.Document)
                {
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.extDiscCode>(detail, discountDetail.ExtDiscCode);
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.description>(detail, discountDetail.Description);
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.isManual>(detail, discountDetail.IsManual);
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.curyDiscountAmt>(detail, discountDetail.CuryDiscountAmt);
                }
            }
            else
            {
                detail = (SOOrderDiscountDetail)docgraph.DiscountDetails.Cache.CreateInstance();
                detail.Type = discountDetail.Type;
                detail.DiscountID = discountDetail.DiscountID;
                detail.DiscountSequenceID = discountDetail.DiscountSequenceID;
                detail.ExtDiscCode = discountDetail.ExtDiscCode;
                detail.Description = discountDetail.Description;
                detail = (SOOrderDiscountDetail)docgraph.DiscountDetails.Cache.Insert(detail);
                if (discountDetail.IsManual == true && (discountDetail.Type == DiscountType.Document || discountDetail.Type == DiscountType.ExternalDocument))
                {
                    detail.CuryDiscountAmt = discountDetail.CuryDiscountAmt;
                    detail.IsManual = discountDetail.IsManual;
                    docgraph.DiscountDetails.Cache.Update(detail);
                }
            }
        }
        SOOrder old_row = PXCache<SOOrder>.CreateCopy(docgraph.Document.Current);
        docgraph.Document.Cache.SetValueExt<SOOrder.curyDiscTot>(docgraph.Document.Current, DiscountEngineProvider.GetEngineFor<SOLine, SOOrderDiscountDetail>().GetTotalGroupAndDocumentDiscount(docgraph.DiscountDetails));
        docgraph.Document.Cache.RaiseRowUpdated(docgraph.Document.Current, old_row);
    }

    doc = docgraph.Document.Update(doc);

    if (opportunity.TaxZoneID != null && !recalcAny)
    {
        foreach (CRTaxTran tax in PXSelect<CRTaxTran, Where<CRTaxTran.quoteID, Equal<Current<CROpportunity.quoteNoteID>>>>.Select(this))
        {
            SOTaxTran newtax = new SOTaxTran();
            newtax.LineNbr = int.MaxValue;
            newtax.TaxID = tax.TaxID;

            newtax = docgraph.Taxes.Insert(newtax);

            if (newtax != null)
            {
                newtax = PXCache<SOTaxTran>.CreateCopy(newtax);
                newtax.TaxRate = tax.TaxRate;
                newtax.CuryTaxableAmt = tax.CuryTaxableAmt;
                newtax.CuryTaxAmt = tax.CuryTaxAmt;

                newtax.CuryUnshippedTaxableAmt = tax.CuryTaxableAmt;
                newtax.CuryUnshippedTaxAmt = tax.CuryTaxAmt;
                newtax.CuryUnbilledTaxableAmt = tax.CuryTaxableAmt;
                newtax.CuryUnbilledTaxAmt = tax.CuryTaxAmt;

                newtax = docgraph.Taxes.Update(newtax);
            }
        }
    }

    if (opportunity.AllowOverrideContactAddress == true)
    {
        CRContact _CRContact = Opportunity_Contact.SelectSingle();
        CRAddress _CRAddress = Opportunity_Address.SelectSingle();
        // Insert
        if (_CRContact != null)
        {
            SOBillingContact _billingContact = docgraph.Billing_Contact.Select();                                    

            if (_billingContact != null)
            {
                _billingContact.FullName = _CRContact.FullName;
                _billingContact.Salutation = _CRContact.Salutation;
                _billingContact.Phone1 = _CRContact.Phone1;
                _billingContact.Email = _CRContact.Email; 

                _billingContact = docgraph.Billing_Contact.Update(_billingContact);
                _billingContact.IsDefaultContact = false;
                _billingContact = docgraph.Billing_Contact.Update(_billingContact);
            }                    
        }

        if (_CRAddress != null)
        {
            SOBillingAddress _billingAddress = docgraph.Billing_Address.Select();

            if (_billingAddress != null)
            {
                _billingAddress.AddressLine1 = _CRAddress.AddressLine1;
                _billingAddress.AddressLine2 = _CRAddress.AddressLine2;
                _billingAddress.City = _CRAddress.City;
                _billingAddress.CountryID = _CRAddress.CountryID;
                _billingAddress.State = _CRAddress.State;
                _billingAddress.PostalCode = _CRAddress.PostalCode;
                _billingAddress = docgraph.Billing_Address.Update(_billingAddress);
                _billingAddress.IsDefaultAddress = false;
                _billingAddress = docgraph.Billing_Address.Update(_billingAddress);
            }
        }
    }
    if (recalcAny)
    {
        docgraph.recalcdiscountsfilter.Current.OverrideManualPrices = param.OverrideManualPrices == true;
        docgraph.recalcdiscountsfilter.Current.RecalcDiscounts = param.RecalculateDiscounts == true;
        docgraph.recalcdiscountsfilter.Current.RecalcUnitPrices = param.RecalculatePrices == true;
        docgraph.recalcdiscountsfilter.Current.OverrideManualDiscounts = param.OverrideManualDiscounts == true;
        docgraph.recalcdiscountsfilter.Current.OverrideManualDocGroupDiscounts = param.OverrideManualDocGroupDiscounts == true;

        docgraph.Actions[nameof(Discount.RecalculateDiscountsAction)].Press();
    }

    if (!this.IsContractBasedAPI)
        throw new PXRedirectRequiredException(docgraph, "");

    docgraph.Save.Press();
}
受保护的虚拟void DoCreateSalesOrder(CreateSalesOrderFilter参数)
{
bool recalcAny=param.recreacteprices==true||
param.RecreactedisCounts==true||
param.OverrideManualDiscounts==true||
param.overrideManualDocGroupPrefications==true||
param.OverrideManualPrices==true;
var opportunity=this.opportunity.Current;
客户客户=(客户)PXSelect.选择(此);
SOOrderEntry docgraph=PXGraph.CreateInstance();
CurrencyInfo=PXSelect.Select(此);
info.CuryInfoID=null;
info=CurrencyInfo.GetEX(docgraph.CurrencyInfo.Insert(info.GetCM());
SOOrder doc=新SOOrder();
doc.OrderType=CreateOrderParams.Current.OrderType??SOOrderTypeConstants.SalesOrder;
doc=docgraph.Document.Insert(doc);
doc=PXCache.CreateCopy(docgraph.Document.Search(doc.OrderNbr));
doc.CuryInfoID=info.CuryInfoID;
doc=PXCache.CreateCopy(docgraph.Document.Update(doc));
doc.CuryID=info.CuryID;
doc.OrderDate=Accessinfo.BusinessDate;
doc.OrderDesc=opportunity.Subject;
doc.TermsID=customer.TermsID;
doc.CustomerID=opportunity.BAccountID;
doc.CustomerLocationID=opportunity.LocationID??customer.DefLocationID;
if(opportunity.TaxZoneID!=null)
{
doc.TaxZoneID=opportunity.TaxZoneID;
如果(!重新校准)
{
SOTaxAttribute.SetTaxCalc(docgraph.Transactions.Cache,null,TaxCalc.ManualCalc);
SOTaxAttribute.SetTaxCalc(docgraph.Document.Cache,null,
TaxCalc.ManualCalc);
}
}
doc.ProjectID=opportunity.ProjectID;
doc.BranchID=opportunity.BranchID;
doc=docgraph.Document.Update(doc);
var-activityrelation=docgraph.RelationsLink.Insert();
activityrelation.RefNoteID=doc.NoteID;
activityrelation.Role=CRRoleTypeList.Source;
ActivityRelation.TargetType=CRTargetEntityType.CropOpportunity;
活动关系.TargetNoteID=opportunity.NoteID;
ActivationRelation.DocNoteID=opportunity.NoteID;
ActivationRelation.EntityID=opportunity.BAccountID;
ActivationRelation.ContactID=opportunity.ContactID;
docgraph.RelationsLink.Update(活动关系);
bool失败=错误;
foreach(选择产品中的CROpportunityProducts产品(opportunity.QuoteNodeId))
{
if(product.SiteID==null)
{
InventoryItem=(InventoryItem)PXSelectorAttribute.Select(Products.Cache,product);
if(item!=null&&item.NonStockShip==true)
{
Products.Cache.RaiseExceptionHandling(product,null,
新的PXSetPropertyException(ErrorMessages.FieldIsEmpty,typeof(croportUnityProducts.siteID.Name));
失败=真;
}
}
SOLine tran=新的SOLine();
tran=docgraph.Transactions.Insert(tran);
if(tran!=null)
{
tran.InventoryID=product.InventoryID;
tran.SubItemID=product.SubItemID;
tran.TranDesc=product.Descr;
交易订单数量=产品数量;
交易计量单位=产品计量单位;
tran.CuryUnitPrice=product.CuryUnitPrice;
tran.TaxCategoryID=product.TaxCategoryID;
tran.SiteID=product.SiteID;
tran.IsFree=product.IsFree;
tran.ProjectID=product.ProjectID;
tran.TaskID=product.TaskID;
tran.CostCodeID=product.CostCodeID;
tran.ManualPrice=真;
tran.ManualDisc=真;
tran.curydiscamp=product.curydiscamp;
tran.DiscAmt=product.DiscAmt;
tran.DiscPct=product.DiscPct;
tran.POCreate=product.POCreate;
tran.VendorID=product.VendorID;
如果(参数重新计算价格!=真)
{
tran.ManualPrice=真;
}
其他的
{
if(param.OverrideManualPrices!=true)
tran.ManualPrice=product.ManualPrice;
其他的
tran.ManualPrice=假;
}
if(param.recreaceDiscounts!=真)
{
tran.ManualDisc=真;
}
其他的
{
if(param.OverrideManualDiscounts!=真)
tran.ManualDisc=product.ManualDisc;
其他的
tran.ManualDisc=假;
}
tran.curydiscamp=product.curydiscamp;
tran.DiscAmt=product.DiscAmt;
tran.DiscPct=product.DiscPct;
}
tran=docgraph.Transactions.Update(tran);
PXNoteAttribute.CopyNoteAndFiles(Products.Cache,product,docgraph.Transactions.Cache,tran,
设置(当前);
}
PXNoteAttribute.CopyNoteAndFiles(Opportunity.Cache,Opportunity,docgraph.Document.Cache,doc,Setup.Current);
如果(失败)
抛出新的PXException(Messages.SiteNotDefined);
//跳过所有客户结算
if(param.recommedisconts!=true&¶m.overridemanualdisconts!=true)
{
var折扣=新字典();
foreach(docgraph.DiscountDetails.Select()中的SOOrderDiscountDetail折扣细节)
{
docgraph.DiscountDetails.SetValueExt(DiscountDetails,true);
字符串键=discountDetail.Type+':'+discountDetail.DiscountID+
protected virtual void DoCreateSalesOrder(CreateSalesOrderFilter param)
{
    bool recalcAny = param.RecalculatePrices == true ||
                     param.RecalculateDiscounts == true ||
                     param.OverrideManualDiscounts == true ||
                     param.OverrideManualDocGroupDiscounts == true ||
                     param.OverrideManualPrices == true;

    var opportunity = this.Opportunity.Current;
    Customer customer = (Customer)PXSelect<Customer, Where<Customer.bAccountID, Equal<Current<CROpportunity.bAccountID>>>>.Select(this);

    SOOrderEntry docgraph = PXGraph.CreateInstance<SOOrderEntry>();

    CurrencyInfo info = PXSelect<CurrencyInfo, Where<CurrencyInfo.curyInfoID, Equal<Current<CROpportunity.curyInfoID>>>>.Select(this);
    info.CuryInfoID = null;
    info = CurrencyInfo.GetEX(docgraph.currencyinfo.Insert(info.GetCM()));

    SOOrder doc = new SOOrder();
    doc.OrderType = CreateOrderParams.Current.OrderType ?? SOOrderTypeConstants.SalesOrder;
    doc = docgraph.Document.Insert(doc);
    doc = PXCache<SOOrder>.CreateCopy(docgraph.Document.Search<SOOrder.orderNbr>(doc.OrderNbr));

    doc.CuryInfoID = info.CuryInfoID;
    doc = PXCache<SOOrder>.CreateCopy(docgraph.Document.Update(doc));

    doc.CuryID = info.CuryID;
    doc.OrderDate = Accessinfo.BusinessDate;
    doc.OrderDesc = opportunity.Subject;
    doc.TermsID = customer.TermsID;
    doc.CustomerID = opportunity.BAccountID;
    doc.CustomerLocationID = opportunity.LocationID ?? customer.DefLocationID;
    if (opportunity.TaxZoneID != null)
    {
    doc.TaxZoneID = opportunity.TaxZoneID;
        if (!recalcAny)
        {
        SOTaxAttribute.SetTaxCalc<SOLine.taxCategoryID>(docgraph.Transactions.Cache, null, TaxCalc.ManualCalc);
            SOTaxAttribute.SetTaxCalc<SOOrder.freightTaxCategoryID>(docgraph.Document.Cache, null,
                TaxCalc.ManualCalc);
        }
    }
    doc.ProjectID = opportunity.ProjectID;
    doc.BranchID = opportunity.BranchID;
    doc = docgraph.Document.Update(doc);

    var campaignRelation = docgraph.RelationsLink.Insert();
    campaignRelation.RefNoteID = doc.NoteID;
    campaignRelation.Role = CRRoleTypeList.Source;
    campaignRelation.TargetType = CRTargetEntityType.CROpportunity;
    campaignRelation.TargetNoteID = opportunity.NoteID;
    campaignRelation.DocNoteID = opportunity.NoteID;
    campaignRelation.EntityID = opportunity.BAccountID;
    campaignRelation.ContactID = opportunity.ContactID;
    docgraph.RelationsLink.Update(campaignRelation);

    bool failed = false;
    foreach (CROpportunityProducts product in SelectProducts(opportunity.QuoteNoteID))
    {
        if (product.SiteID == null)
        {
            InventoryItem item = (InventoryItem)PXSelectorAttribute.Select<CROpportunityProducts.inventoryID>(Products.Cache, product);
            if (item != null && item.NonStockShip == true)
            {
                Products.Cache.RaiseExceptionHandling<CROpportunityProducts.siteID>(product, null,
                    new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(CROpportunityProducts.siteID).Name));
                failed = true;
            }
        }

        SOLine tran = new SOLine();
        tran = docgraph.Transactions.Insert(tran);
        if (tran != null)
        {
            tran.InventoryID = product.InventoryID;
            tran.SubItemID = product.SubItemID;
            tran.TranDesc = product.Descr;
            tran.OrderQty = product.Quantity;
            tran.UOM = product.UOM;
            tran.CuryUnitPrice = product.CuryUnitPrice;
            tran.TaxCategoryID = product.TaxCategoryID;
            tran.SiteID = product.SiteID;
            tran.IsFree = product.IsFree;
            tran.ProjectID = product.ProjectID;
            tran.TaskID = product.TaskID;
            tran.CostCodeID = product.CostCodeID;
            tran.ManualPrice = true;
            tran.ManualDisc = true;
            tran.CuryDiscAmt = product.CuryDiscAmt;
            tran.DiscAmt = product.DiscAmt;
            tran.DiscPct = product.DiscPct;
            tran.POCreate = product.POCreate;
            tran.VendorID = product.VendorID;

            if (param.RecalculatePrices != true)
            {
                tran.ManualPrice = true;
            }
            else
            {
                if (param.OverrideManualPrices != true)
                    tran.ManualPrice = product.ManualPrice;
                else
                    tran.ManualPrice = false;
            }

            if (param.RecalculateDiscounts != true)
            {
                tran.ManualDisc = true;
            }
            else
            {
                if (param.OverrideManualDiscounts != true)
                    tran.ManualDisc = product.ManualDisc;
                else
                    tran.ManualDisc = false;
            }

            tran.CuryDiscAmt = product.CuryDiscAmt;
            tran.DiscAmt = product.DiscAmt;
            tran.DiscPct = product.DiscPct;
        }

        tran = docgraph.Transactions.Update(tran);
        PXNoteAttribute.CopyNoteAndFiles(Products.Cache, product, docgraph.Transactions.Cache, tran,
            Setup.Current);
    }

    PXNoteAttribute.CopyNoteAndFiles(Opportunity.Cache, opportunity, docgraph.Document.Cache, doc, Setup.Current);

    if (failed)
        throw new PXException(Messages.SiteNotDefined);

    //Skip all customer dicounts
    if (param.RecalculateDiscounts != true && param.OverrideManualDiscounts != true)
    {
        var discounts = new Dictionary<string, SOOrderDiscountDetail>();
        foreach (SOOrderDiscountDetail discountDetail in docgraph.DiscountDetails.Select())
        {
            docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.skipDiscount>(discountDetail, true);
            string key = discountDetail.Type + ':' + discountDetail.DiscountID + ':' + discountDetail.DiscountSequenceID;
            discounts.Add(key, discountDetail);
        }
        Discount ext = this.GetExtension<Discount>();
        foreach (CROpportunityDiscountDetail discountDetail in ext.DiscountDetails.Select())
        {
            SOOrderDiscountDetail detail;
            string key = discountDetail.Type + ':' + discountDetail.DiscountID + ':' + discountDetail.DiscountSequenceID;
            if (discounts.TryGetValue(key, out detail))
            {
                docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.skipDiscount>(detail, false);
                if (discountDetail.IsManual == true && discountDetail.Type == DiscountType.Document)
                {
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.extDiscCode>(detail, discountDetail.ExtDiscCode);
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.description>(detail, discountDetail.Description);
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.isManual>(detail, discountDetail.IsManual);
                    docgraph.DiscountDetails.SetValueExt<SOOrderDiscountDetail.curyDiscountAmt>(detail, discountDetail.CuryDiscountAmt);
                }
            }
            else
            {
                detail = (SOOrderDiscountDetail)docgraph.DiscountDetails.Cache.CreateInstance();
                detail.Type = discountDetail.Type;
                detail.DiscountID = discountDetail.DiscountID;
                detail.DiscountSequenceID = discountDetail.DiscountSequenceID;
                detail.ExtDiscCode = discountDetail.ExtDiscCode;
                detail.Description = discountDetail.Description;
                detail = (SOOrderDiscountDetail)docgraph.DiscountDetails.Cache.Insert(detail);
                if (discountDetail.IsManual == true && (discountDetail.Type == DiscountType.Document || discountDetail.Type == DiscountType.ExternalDocument))
                {
                    detail.CuryDiscountAmt = discountDetail.CuryDiscountAmt;
                    detail.IsManual = discountDetail.IsManual;
                    docgraph.DiscountDetails.Cache.Update(detail);
                }
            }
        }
        SOOrder old_row = PXCache<SOOrder>.CreateCopy(docgraph.Document.Current);
        docgraph.Document.Cache.SetValueExt<SOOrder.curyDiscTot>(docgraph.Document.Current, DiscountEngineProvider.GetEngineFor<SOLine, SOOrderDiscountDetail>().GetTotalGroupAndDocumentDiscount(docgraph.DiscountDetails));
        docgraph.Document.Cache.RaiseRowUpdated(docgraph.Document.Current, old_row);
    }

    doc = docgraph.Document.Update(doc);

    if (opportunity.TaxZoneID != null && !recalcAny)
    {
        foreach (CRTaxTran tax in PXSelect<CRTaxTran, Where<CRTaxTran.quoteID, Equal<Current<CROpportunity.quoteNoteID>>>>.Select(this))
        {
            SOTaxTran newtax = new SOTaxTran();
            newtax.LineNbr = int.MaxValue;
            newtax.TaxID = tax.TaxID;

            newtax = docgraph.Taxes.Insert(newtax);

            if (newtax != null)
            {
                newtax = PXCache<SOTaxTran>.CreateCopy(newtax);
                newtax.TaxRate = tax.TaxRate;
                newtax.CuryTaxableAmt = tax.CuryTaxableAmt;
                newtax.CuryTaxAmt = tax.CuryTaxAmt;

                newtax.CuryUnshippedTaxableAmt = tax.CuryTaxableAmt;
                newtax.CuryUnshippedTaxAmt = tax.CuryTaxAmt;
                newtax.CuryUnbilledTaxableAmt = tax.CuryTaxableAmt;
                newtax.CuryUnbilledTaxAmt = tax.CuryTaxAmt;

                newtax = docgraph.Taxes.Update(newtax);
            }
        }
    }

    if (opportunity.AllowOverrideContactAddress == true)
    {
        CRContact _CRContact = Opportunity_Contact.SelectSingle();
        CRAddress _CRAddress = Opportunity_Address.SelectSingle();
        // Insert
        if (_CRContact != null)
        {
            SOBillingContact _billingContact = docgraph.Billing_Contact.Select();                                    

            if (_billingContact != null)
            {
                _billingContact.FullName = _CRContact.FullName;
                _billingContact.Salutation = _CRContact.Salutation;
                _billingContact.Phone1 = _CRContact.Phone1;
                _billingContact.Email = _CRContact.Email; 

                _billingContact = docgraph.Billing_Contact.Update(_billingContact);
                _billingContact.IsDefaultContact = false;
                _billingContact = docgraph.Billing_Contact.Update(_billingContact);
            }                    
        }

        if (_CRAddress != null)
        {
            SOBillingAddress _billingAddress = docgraph.Billing_Address.Select();

            if (_billingAddress != null)
            {
                _billingAddress.AddressLine1 = _CRAddress.AddressLine1;
                _billingAddress.AddressLine2 = _CRAddress.AddressLine2;
                _billingAddress.City = _CRAddress.City;
                _billingAddress.CountryID = _CRAddress.CountryID;
                _billingAddress.State = _CRAddress.State;
                _billingAddress.PostalCode = _CRAddress.PostalCode;
                _billingAddress = docgraph.Billing_Address.Update(_billingAddress);
                _billingAddress.IsDefaultAddress = false;
                _billingAddress = docgraph.Billing_Address.Update(_billingAddress);
            }
        }
    }
    if (recalcAny)
    {
        docgraph.recalcdiscountsfilter.Current.OverrideManualPrices = param.OverrideManualPrices == true;
        docgraph.recalcdiscountsfilter.Current.RecalcDiscounts = param.RecalculateDiscounts == true;
        docgraph.recalcdiscountsfilter.Current.RecalcUnitPrices = param.RecalculatePrices == true;
        docgraph.recalcdiscountsfilter.Current.OverrideManualDiscounts = param.OverrideManualDiscounts == true;
        docgraph.recalcdiscountsfilter.Current.OverrideManualDocGroupDiscounts = param.OverrideManualDocGroupDiscounts == true;

        docgraph.Actions[nameof(Discount.RecalculateDiscountsAction)].Press();
    }

    if (!this.IsContractBasedAPI)
        throw new PXRedirectRequiredException(docgraph, "");

    docgraph.Save.Press();
}