Skip to main content
Answer

Default Opportunity detail quantity to 1

  • August 29, 2024
  • 9 replies
  • 105 views

Forum|alt.badge.img+1

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:

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

And this doesn’t work either:

        [PXRemoveBaseAttribute(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? 

Best answer by darylbowman

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;
}
}

 

9 replies

Forum|alt.badge.img+8
  • Captain II
  • August 30, 2024

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


Forum|alt.badge.img+1
  • Author
  • Semi-Pro III
  • August 30, 2024

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

 


Forum|alt.badge.img+8
  • Captain II
  • September 3, 2024

HI @rjean09 

 

What version of Acumatica are you on?

 

Aleks


darylbowman
Captain II
Forum|alt.badge.img+15

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.


Forum|alt.badge.img+8
  • Captain II
  • September 3, 2024

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


Forum|alt.badge.img+1
  • Jr Varsity I
  • September 3, 2024

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.


Forum|alt.badge.img+1
  • Author
  • Semi-Pro III
  • September 3, 2024

HI @rjean09 

 

What version of Acumatica are you on?

 

Aleks

23.116.0019


darylbowman
Captain II
Forum|alt.badge.img+15
  • Answer
  • September 5, 2024

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;
}
}

 


Forum|alt.badge.img+1
  • Author
  • Semi-Pro III
  • September 5, 2024

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!