Skip to main content

This seems like one of those simple requests.  I actually did this for the same client on SOLine but on CROpportunityProducts I’m not having any luck.

This works when new line added to CROpportunityProducts:

        protected virtual void CROpportunityProducts_Quantity_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e, PXFieldDefaulting baseEvent)
{
baseEvent?.Invoke(sender, e);
CROpportunityProducts row = e.Row as CROpportunityProducts;
if (row == null) return;

if (!row.Quantity.HasValue && Base.IsImport != true)
{
e.NewValue = row.Quantity = 1M;
}
}

But when inventory item is selected, quantity goes back to 0.  I saw there is an attribute (PXDBOpportunityProductQuantityAttribute) so I’ve attempted every combination of removing/overriding this using CacheAttached.  

This doesn’t work:

        pPXDefault(TypeCode.Decimal, "0.0")]
PXUIField(DisplayName = "Quantity", Visibility = PXUIVisibility.Visible)]
protected virtual void CROpportunityProducts_Quantity_CacheAttached(PXCache sender) { }

And this doesn’t work either:

        aPXRemoveBaseAttribute(typeof(PXDBOpportunityProductQuantityAttribute))]
protected virtual void CROpportunityProducts_Quantity_CacheAttached(PXCache sender) { }

Quantity goes back to zero after selecting inventory item no matter what.  I tried FieldUpdated event and this doesn’t work either:

        protected virtual void CROpportunityProducts_InventoryID_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e, PXFieldUpdated baseEvent) 
{
baseEvent?.Invoke(sender, e);
CROpportunityProducts row = e.Row as CROpportunityProducts;
if (row != null && row.InventoryID != null)
{
sender.SetValueExt<CROpportunityProducts.quantity>(e.Row, 1M);
}
}

Any ideas? 

Hi @rjean09 

 

I you could use the RowInserted Handler, or amending you FieldUpdated Handler.

 

Personally I prefer the strongly typed ones, I think that what theyre called…

//CROpportunityProducts FieldUpdated Handler, only triggers when a new value for inventory ID is persisted/when a new key value is entered.
protected virtual void _(Events.FieldUpdated<CROpportunityProducts, CROpportunityProducts.inventoryID> e, PXFieldUpdated b)
{
CROpportunityProducts row = e.Row;
if(row == null) return; // if there is no data stop, this is very important.

b?.Invoke(e.Cache, e.Args);

e.Cache.SetValueExt<CROpportunityProducts.quantity>(row, 1.0);
}

//RowInserted Handler to set the value when the row is first entered.
protected virtual void _(Events.RowInserted<CROpportunityProducts> e, PXRowInserted b)
{
CROpportunityProducts row = e.Row;
if(row == null)// same as above, if there is no row, there wont be anything to call.

b?.Invoke(e.Cache, e.Args);

row.InventoryID = 1.0;
}

Hope this helps!

Aleks


Something still causing Quantity to go back to zero after InventoryID FieldUpdated.  I set a breakpoint and can see Quantity being set to 1 but something else is flipping it back to zero.  Again, this same code I have working in Sales Order SOLine.  I’ve looked in the OpportunityMaint graph, etc. and can’t see anything that would be doing this.  Also tried removing the  PXDBOpportunityProductQuantityAttribute with CacheAttached.

I also prefer the strong typed event handlers.  I didn’t realize I could add the 2nd argument for the base.Invoke to that so thanks for that.  I’ve updated my code to use this but still doesn’t fix the issue.

 

Hi @rjean09 

 

I you could use the RowInserted Handler, or amending you FieldUpdated Handler.

 

Personally I prefer the strongly typed ones, I think that what theyre called…

//CROpportunityProducts FieldUpdated Handler, only triggers when a new value for inventory ID is persisted/when a new key value is entered.
protected virtual void _(Events.FieldUpdated<CROpportunityProducts, CROpportunityProducts.inventoryID> e, PXFieldUpdated b)
{
CROpportunityProducts row = e.Row;
if(row == null) return; // if there is no data stop, this is very important.

b?.Invoke(e.Cache, e.Args);

e.Cache.SetValueExt<CROpportunityProducts.quantity>(row, 1.0);
}

//RowInserted Handler to set the value when the row is first entered.
protected virtual void _(Events.RowInserted<CROpportunityProducts> e, PXRowInserted b)
{
CROpportunityProducts row = e.Row;
if(row == null)// same as above, if there is no row, there wont be anything to call.

b?.Invoke(e.Cache, e.Args);

row.InventoryID = 1.0;
}

Hope this helps!

Aleks

 


HI @rjean09 

 

What version of Acumatica are you on?

 

Aleks


Quantity is a calculation of BaseQuantity, taking UOM conversion into account. I’m curious if you would override the FieldDefaulting event on BaseQuantity and set that to 1 if you’d have more success.


Thanks for that @darylbowman that’s very useful to know!


HI @rjean09 

You can use code like that.
 

        protected virtual void CROpportunityProducts_Quantity_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e, PXFieldDefaulting baseEvent)
{
baseEvent?.Invoke(sender, e);
CROpportunityProducts row = e.Row as CROpportunityProducts;
if (row == null) return;

if (Base.IsImport != true)
{
e.NewValue = 1M;
}
}

without 

!row.Quantity.HasValue

 

Also be aware to check if Base Quantity works well in cases where different UOMs are used.


HI @rjean09 

 

What version of Acumatica are you on?

 

Aleks

23.116.0019


Try this:

protected virtual void _(Events.FieldDefaulting<CROpportunityProducts.quantity> e, PXFieldDefaulting b)
{
b?.Invoke(e.Cache, e.Args);

var value = e.NewValue as decimal?;
if (value is null || value == 0)
{
e.NewValue = 1m;
e.Cancel = true;
}
}

 


Try this:

protected virtual void _(Events.FieldDefaulting<CROpportunityProducts.quantity> e, PXFieldDefaulting b)
{
b?.Invoke(e.Cache, e.Args);

var value = e.NewValue as decimal?;
if (value is null || value == 0)
{
e.NewValue = 1m;
e.Cancel = true;
}
}

 

Works perfectly!  Don’t even need anything on InventoryID FieldUpdated event now either.  Thanks!


Reply