In the course of attempting to add an unbound field to the grid of the ‘Critical Materials’ screen (CriticalMaterialsInq), what should have been a simple task turned into much more. Here’s my assessment of why, but I would love to hear some feedback from people who have a more thorough understanding of how the Acumatica cache works.
The grid is based on the ProdMatlRecs data view, made up of SelectedProdMatl records. The SelectedProdMatl records are created from AMProdMatl records and inserted into the cache in a data view delegate (prodMatlRecs()). Here’s where things get interesting.
If the cache contains records marked as inserted, these records are ‘yielded’ and that’s it
bool itVar1 = false;
IEnumerator enumerator = this.ProdMatlRecs.Cache.Inserted.GetEnumerator();
while (enumerator.MoveNext())
{
SelectedProdMatl itVar2 = (SelectedProdMatl)enumerator.Current;
itVar1 = true;
yield return itVar2;
}If there aren’t any ‘inserted’ records, the results are selected and constructed from AMProdMatl records, inserted, and then ‘yielded’:
if (!itVar1)
{
foreach (/* records selected */)
{
var row = BuildSelectedProdMatl(prodMatlList, result, result, result, result, result, result, result, result, result);
if (row != null)
{
prodMatlList.Add(row);
}
}
foreach (var prodMatl in prodMatlList)
{
var isShort = prodMatl.QtyShort.GetValueOrDefault() > 0 && prodMatl.StatusID != ProductionOrderStatus.Completed;
var isAllocated = prodMatl.IsAllocated == true;
if (isShort || (current.ShowAll.GetValueOrDefault() && !isAllocated) || current.ShowAllocated.GetValueOrDefault() && isAllocated)
{
ProdMatlRecs.Insert(prodMatl);
yield return prodMatl;
}
}
}At the end, the cache is marked as ‘clean’:
this.ProdMatlRecs.Cache.IsDirty = false;
The problem with how this is written is that using cache functions like .SetValueExt and using event handlers don’t change what is displayed on the screen unless the grid is refreshed manually. Calling .View.RequestRefresh() was not enough (in my experience).
I ended up overriding the data view and delegate in order to do several things:
- checked for (and returned)
cachedrecords instead ofinserted - inserted and then set the cache status as
Held - did NOT yield any records, but returned
ProdMatlRecs.Cache.Cachedinstead
Now the cache mechanisms function normally and behaves as any ‘normal’ Acumatica screen.
I invite any criticism or feedback on whether this is the correct way a data view delegate should be written.
