Skip to main content
Question

How can I override the LotSerialStatusByCostCenter accumulator attribute?

  • March 17, 2026
  • 1 reply
  • 24 views

mos11
Freshman I
Forum|alt.badge.img
 public override void Initialize()
{
base.Initialize();

PXCache cacheBase = Base.Caches[typeof(INLotSerialStatusByCostCenter)];
cacheBase.Interceptor = new BZAccumulatorAttribute();

}
public class BZAccumulatorAttribute : PX.Objects.IN.InventoryRelease.Accumulators.QtyAllocated.LotSerialStatusByCostCenter.AccumulatorAttribute
{
public BZAccumulatorAttribute() : base()
{
_SingleRecord = true;
}

protected override bool PrepareInsert(PXCache cache, object row, PXAccumulatorCollection columns)
{
bool ret = base.PrepareInsert(cache, row, columns);
SiteStatusByCostCenter siteStatusByCostCenter = (SiteStatusByCostCenter)row;
InventoryItem item = InventoryItem.PK.Find(cache.Graph, siteStatusByCostCenter.InventoryID);
if (item != null)
{
BZInventoryItemExt itemExt = item.GetExtension<BZInventoryItemExt>();
if (siteStatusByCostCenter.SkipQtyValidation != true && siteStatusByCostCenter.ValidateHardAvailQtyForAdjustments == true && siteStatusByCostCenter.QtyHardAvail < itemExt.UsrBZThresholdQty)
{
columns.AppendException(string.Empty, new PXAccumulatorRestriction<PX.Objects.IN.INSiteStatusByCostCenter.qtyHardAvail>(PXComp.GE, itemExt.UsrBZThresholdQty));
ret = false;
}
}
return ret;
}}

In LotSerialStatusByCostCenter Accumulator Attribute PrepareInsert method, there is code like if (diff.QtyOnHand < 0m) columns.Restrict<qtyOnHand>(PXComp.GE, -diff.QtyOnHand);. I want to override it and add a check (for example, if qty < 10, throw an error). How does it throw an error when qty < 0 if ‘Allow Negative’ is not enabled? I want to do this on the Invoice screen. How can I do this?

1 reply

kbibelhausen
Freshman I
  • Freshman I
  • March 18, 2026

You can override the LotSerialStatusByCostCenter accumulator attribute using a cache interceptor in a graph extension. Here's the approach:

 

## Create a Custom Accumulator Attribute

 

First, create your custom accumulator attribute that inherits from the original or PXAccumulatorAttribute:

 

```csharp

public class CustomLotSerialStatusByCostCenterAccumulator : PXAccumulatorAttribute

{

public CustomLotSerialStatusByCostCenterAccumulator(params Type[] fields)

: base(fields)

{

// Your custom logic here

}

 

// Override methods as needed

public override List UpdateParameters(PXCache sender, object row, PXDataFieldParam[] pars, PXDataFieldParam[] keys, UpdateMode mode)

{

// Custom update logic

return base.UpdateParameters(sender, row, pars, keys, mode);

}

}

```

 

## Apply the Override Using Cache Interceptor

 

In your graph extension's Initialize method, replace the accumulator attribute:

 

```csharp

public class YourGraphExtension : PXGraphExtension

{

public override void Initialize()

{

base.Initialize();

 

PXCache cache = Base.Caches[typeof(LotSerialStatusByCostCenter)];

cache.Interceptor = new CustomLotSerialStatusByCostCenterAccumulator(

// Specify the fields that should be accumulated

typeof(LotSerialStatusByCostCenter.qtyOnHand),

typeof(LotSerialStatusByCostCenter.qtyAvail)

// Add other relevant fields

);

}

}

```

 

## Key Points

 

- The cache interceptor approach replaces the existing accumulator attribute entirely

- You'll need to identify which fields are being accumulated in the original attribute

- Make sure to call `base.Initialize()` before setting the interceptor

- Test thoroughly as accumulator attributes affect data consistency and concurrency handling

 

This pattern follows the same approach shown in the knowledge base for customizing other accumulator attributes like AverageCostStatus.

 

---

Drafted by AcuDev (AI) · Reviewed by Kevin Bibelhausen, Studio B

AcuOps — AI-powered environment management for Acumatica · b.studio