You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica中重写二级Graph Extension方法的实现疑问

Using PXOverrideAttribute for Secondary Graph Extensions in Acumatica (Opportunities Scenario)

Let’s walk through exactly how to use PXOverrideAttribute to rewrite methods in a secondary Graph Extension, while integrating reusable business objects like sales tax and discounts, and rolling order totals into your product sum calculation.

Key Concepts for Secondary Extension Overrides

When working with nested Graph Extensions (secondary extensions that build on top of a primary extension), PXOverrideAttribute works similarly to overriding base Graph methods—but you need to explicitly target the primary extension’s method if that’s what you’re modifying. Here’s what to remember:

  • Match the exact method signature of the method you want to override (return type, parameters, accessibility).
  • Use [PXOverride(typeof(PrimaryExtensionClass))] if you’re overriding a method from the primary extension (instead of the base Graph).
  • You can still call the original method’s logic within your override if needed, using a delegate parameter.

Step-by-Step Example for Opportunities Graph

Let’s assume you have a primary extension OpportunityMaintPrimaryExtension that handles basic product total calculations, and you want a secondary extension OpportunityMaintSecondaryExtension to:

  1. Integrate your reusable sales tax/discount business objects.
  2. Add order totals to the product sum (your core requirement).
  3. Build on top of the primary extension’s existing logic.

1. Define the Primary Extension (for Context)

First, here’s what a typical primary extension might look like (this is the one you’re extending):

public class OpportunityMaintPrimaryExtension : PXGraphExtension<OpportunityMaint>
{
    // Original method calculating product total without order totals
    public virtual decimal? CalculateProductTotal(Opportunity opportunity)
    {
        decimal? total = 0;
        foreach (OpportunityProducts product in Base.OpportunityProducts.Select())
        {
            total += product.Amount;
        }
        return total;
    }
}

2. Create the Secondary Extension with PXOverride

Now, the secondary extension that overrides the CalculateProductTotal method, integrates sales tax/discounts, and adds order totals:

public class OpportunityMaintSecondaryExtension : PXGraphExtension<OpportunityMaintPrimaryExtension, OpportunityMaint>
{
    // Inject reusable business objects (e.g., Sales Tax handler)
    protected SalesTaxMaint _salesTaxMaint;
    protected DiscountMaint _discountMaint;

    public OpportunityMaintSecondaryExtension()
    {
        _salesTaxMaint = PXGraph.CreateInstance<SalesTaxMaint>();
        _discountMaint = PXGraph.CreateInstance<DiscountMaint>();
    }

    // Override the primary extension's CalculateProductTotal method
    [PXOverride(typeof(OpportunityMaintPrimaryExtension))]
    public virtual decimal? CalculateProductTotal(Opportunity opportunity, Func<Opportunity, decimal?> baseMethod)
    {
        // 1. Call the original method from the primary extension to get base product total
        decimal? baseProductTotal = baseMethod(opportunity);
        
        // 2. Add order totals (your requirement)
        decimal? orderTotal = Base.Opportunity.Current.OrderTotal;
        decimal? adjustedTotal = baseProductTotal + orderTotal;

        // 3. Apply reusable sales tax logic (using your custom Tax Attribute if needed)
        decimal? taxAmount = _salesTaxMaint.CalculateTax(adjustedTotal, opportunity.TaxCategoryID);
        adjustedTotal += taxAmount;

        // 4. Apply reusable discount logic
        decimal? discountAmount = _discountMaint.CalculateDiscount(adjustedTotal, opportunity.DiscountID);
        adjustedTotal -= discountAmount;

        return adjustedTotal;
    }
}

3. Key Details Explained

  • Graph Extension Inheritance: The secondary extension uses PXGraphExtension<OpportunityMaintPrimaryExtension, OpportunityMaint> to specify it extends the primary extension, which in turn extends the base OpportunityMaint Graph.
  • PXOverride Target: [PXOverride(typeof(OpportunityMaintPrimaryExtension))] tells Acumatica this method overrides the one from the primary extension, not the base Graph.
  • Delegate Parameter: The Func<Opportunity, decimal?> baseMethod parameter lets you call the original method’s logic—this is optional, but useful if you want to build on existing functionality instead of replacing it entirely.
  • Reusable Business Objects: We’re injecting SalesTaxMaint and DiscountMaint (your reusable objects) to leverage their existing calculation logic, keeping your code DRY.

Integrating Your Custom Tax Attribute

Since you mentioned you already overridden the Tax Category’s Tax Attribute, you can reference that logic directly in the override method. For example, if your custom attribute is CustomTaxAttribute, you could replace the tax calculation line with:

// Use your custom Tax Attribute logic
TaxCategory taxCategory = PXSelect<TaxCategory, Where<TaxCategory.taxCategoryID, Equal<Current<Opportunity.taxCategoryID>>>>.Select(Base);
decimal? taxAmount = CustomTaxAttribute.CalculateTax(taxCategory, adjustedTotal);

内容的提问来源于stack exchange,提问作者Brendan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:22:41