Acumatica中重写二级Graph Extension方法的实现疑问
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:
- Integrate your reusable sales tax/discount business objects.
- Add order totals to the product sum (your core requirement).
- 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 baseOpportunityMaintGraph. - 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?> baseMethodparameter 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
SalesTaxMaintandDiscountMaint(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

