Skip to main content
Answer

User Field Value not displaying

  • March 17, 2025
  • 3 replies
  • 52 views

Hello,

I am trying to add a user field (decimal) called UsrSalesCommPct 

  public class AMEstimateItemExt : PXCacheExtension<PX.Objects.AM.AMEstimateItem>
{
public static bool IsActive() => true;

#region UsrSalesCommPct
[PXDBDecimal]
[PXUIField(DisplayName = "Sales Commission (%)", Required = true)]
public virtual decimal? UsrSalesCommPct { get; set; }
public abstract class usrSalesCommPct : PX.Data.BQL.BqlDecimal.Field<usrSalesCommPct> { }
#endregion

#region UsrContingencyPct
[PXDBDecimal]
[PXUIField(DisplayName = "Contingency (%)", Required = true)]
public virtual decimal? UsrContingencyPct { get; set; }
public abstract class usrContingencyPct : PX.Data.BQL.BqlDecimal.Field<usrContingencyPct> { }
#endregion

#region UsrMargin
[PXDBDecimal]
[PXUIField(DisplayName = "Margin")]
public virtual decimal? UsrMargin { get; set; }
public abstract class usrMargin : PX.Data.BQL.BqlDecimal.Field<usrMargin> { }
#endregion

#region UsrMarginPct
[PXDBDecimal]
[PXUIField(DisplayName = "Margin (%)")]
public virtual decimal? UsrMarginPct { get; set; }
public abstract class usrMarginPct : PX.Data.BQL.BqlDecimal.Field<usrMarginPct> { }
#endregion

#region UsrTotalCost
[PXDecimal]
[PXUIField(DisplayName = "Total Cost")]
public virtual decimal? UsrTotalCost { get; set; }
public abstract class usrTotalCost : PX.Data.BQL.BqlDecimal.Field<usrTotalCost> { }
#endregion
}
}

The field is properly saved in the database but as soon as I save the field value disappears, this is the code I have in the Graph 

    public class EstimateMaint_Extension : PXGraphExtension<PX.Objects.AM.EstimateMaint>
{

public PXSelect<AMEstimateItem,
Where<AMEstimateItem.estimateID, Equal<Required<AMEstimateItem.estimateID>>>> EstimateItemsByEstimateID;

private const string VALIDATION_UsrSalesCommPct = "The Sales Commission Percentage is required.";
private const string VALIDATION_UsrContingencyPct = "The Contingency Percentage is required.";

public static bool IsActive() => true;

#region Event Handlers

/*
protected void AMEstimateItem_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
{

var row = (AMEstimateItem)e.Row;
if (row == null) return;

AMEstimateItemExt rowExt = PXCache<AMEstimateItem>.GetExtension<AMEstimateItemExt>(row);
if (rowExt == null) return;

if (rowExt.UsrSalesCommPct == 0) cache.RaiseExceptionHandling<AMEstimateItemExt.usrSalesCommPct>(row, null, new PXSetPropertyException(VALIDATION_UsrSalesCommPct));
if (rowExt.UsrContingencyPct == 0) cache.RaiseExceptionHandling<AMEstimateItemExt.usrContingencyPct>(row, null, new PXSetPropertyException(VALIDATION_UsrContingencyPct));
//SetTotal(row);
}
*/

protected void AMEstimateItem_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{

var row = (AMEstimateItem)e.Row;
if (row == null) return;

AMEstimateItemExt rowExt = PXCache<AMEstimateItem>.GetExtension<AMEstimateItemExt>(row);
if (rowExt == null) return;

rowExt.UsrMargin = row.CuryExtPrice - row.CuryExtCost;
rowExt.UsrMarginPct = (row.CuryExtPrice == 0) ? 0 : ((row.CuryExtPrice - row.CuryExtCost) / row.CuryExtPrice) * 100;

var result = EstimateItemsByEstimateID.Select(row.EstimateID);

if (result != null)
{
var item = result.FirstOrDefault()?.GetItem<AMEstimateItem>();
if (item != null)
{
rowExt.UsrSalesCommPct = item.GetExtension<AMEstimateItemExt>()?.UsrSalesCommPct;
rowExt.UsrContingencyPct = item.GetExtension<AMEstimateItemExt>()?.UsrContingencyPct;
}
}

SetTotal(row );
}

protected void AMEstimateItem_UsrSalesCommPct_FieldVerifying(PXCache cache, PXFieldVerifyingEventArgs e)
{
if (e.Row == null) return;
var row = (AMEstimateItem)e.Row;

decimal? newValue = (decimal?)e.NewValue;
if (newValue == 0) throw new PXSetPropertyException(VALIDATION_UsrSalesCommPct);
}

protected void AMEstimateItem_UsrContingencyPct_FieldVerifying(PXCache cache, PXFieldVerifyingEventArgs e)
{
if (e.Row == null) return;
var row = (AMEstimateItem)e.Row;

decimal? newValue = (decimal?)e.NewValue;
if (newValue == 0) throw new PXSetPropertyException(VALIDATION_UsrContingencyPct);
}

protected void AMEstimateItem_UsrContingencyPct_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_UsrSalesCommPct_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_FixedLaborCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_VariableLaborCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_MachineCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_MaterialCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_ToolCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_FixedOverheadCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_VariableOverheadCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);
protected void AMEstimateItem_SubcontractCost_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) => SetTotal((AMEstimateItem)e.Row);

#endregion

private void SetTotal(AMEstimateItem row)
{
if (row == null) return;
AMEstimateItemExt rowExt = PXCache<AMEstimateItem>.GetExtension<AMEstimateItemExt>(row);
if (rowExt == null) return;
rowExt.UsrTotalCost = CalculateTotalCost(row.FixedLaborCost, row.VariableLaborCost, row.MachineCost, row.MaterialCost, row.ToolCost, row.FixedOverheadCost, row.VariableOverheadCost, row.SubcontractCost, rowExt.UsrSalesCommPct, rowExt.UsrContingencyPct);
}

private decimal CalculateTotalCost(decimal? laborCostFixed, decimal? laborCostVar, decimal? machineCost, decimal? materialCost, decimal? toolCost, decimal? overheadCostFixed, decimal? overheadCostVar, decimal? subcontractCost, decimal? salesCommPct, decimal? contingencyPct)
{
var totalCost = (laborCostFixed ?? 0m) + (laborCostVar ?? 0m) + (machineCost ?? 0m) + (materialCost ?? 0m) + (toolCost ?? 0m) + (overheadCostFixed ?? 0m) + (overheadCostVar ?? 0m) + (subcontractCost ?? 0m);

var salesCommission = ((salesCommPct ?? 0m) * (materialCost ?? 0m)) / 100;
totalCost += salesCommission;

var contingency = (totalCost * (contingencyPct ?? 0m)) / 100;
totalCost += contingency;

return totalCost;
}

}

I tried to disable everything under the RowSelected but I still do not see the value after the record is saved.

 

Thank you in Advanced

 

 

Best answer by darylbowman

AMEstimateItem is a projection:

You will need to create a cache extension on PX.Objects.AM.Standalone.AMEstimateItem as well. Then change your current field definition to [PXDBDecimal(BqlField = typeof(PX.Objects.AM.Standalone.AMEstimateItemExt.usrSalesCommPct)] (with respect to whatever that cache extension / field name is).

3 replies

darylbowman
Captain II
Forum|alt.badge.img+15
  • Answer
  • March 17, 2025

AMEstimateItem is a projection:

You will need to create a cache extension on PX.Objects.AM.Standalone.AMEstimateItem as well. Then change your current field definition to [PXDBDecimal(BqlField = typeof(PX.Objects.AM.Standalone.AMEstimateItemExt.usrSalesCommPct)] (with respect to whatever that cache extension / field name is).


  • Author
  • Freshman I
  • March 17, 2025

Thank you, that worked, I will add the new code below in case someone else will get stuck on the same issue as me. I am not sure what a projection is, do you have a link I can do some study in regards? 

namespace PX.Objects.AM.Standalone
{
public class StandaloneAMEstimateItemExt : PXCacheExtension<PX.Objects.AM.Standalone.AMEstimateItem>
{
public static bool IsActive() => true;

#region UsrSalesCommPct
[PXDBDecimal]
[PXUIField(DisplayName = "Sales Commission (%)", Required = true)]
public virtual decimal? UsrSalesCommPct { get; set; }
public abstract class usrSalesCommPct : PX.Data.BQL.BqlDecimal.Field<usrSalesCommPct> { }
#endregion

#region UsrContingencyPct
[PXDBDecimal]
[PXUIField(DisplayName = "Contingency (%)", Required = true)]
public virtual decimal? UsrContingencyPct { get; set; }
public abstract class usrContingencyPct : PX.Data.BQL.BqlDecimal.Field<usrContingencyPct> { }
#endregion

#region UsrMargin
[PXDBDecimal]
[PXUIField(DisplayName = "Margin")]
public virtual decimal? UsrMargin { get; set; }
public abstract class usrMargin : PX.Data.BQL.BqlDecimal.Field<usrMargin> { }
#endregion

#region UsrMarginPct
[PXDBDecimal]
[PXUIField(DisplayName = "Margin (%)")]
public virtual decimal? UsrMarginPct { get; set; }
public abstract class usrMarginPct : PX.Data.BQL.BqlDecimal.Field<usrMarginPct> { }
#endregion

}
}

namespace PX.Objects.AM
{
public class AMEstimateItemExt : PXCacheExtension<PX.Objects.AM.AMEstimateItem>
{
public static bool IsActive() => true;

#region UsrSalesCommPct
[PXDBDecimal(BqlField = typeof(PX.Objects.AM.Standalone.StandaloneAMEstimateItemExt.usrSalesCommPct))]
[PXUIField(DisplayName = "Sales Commission (%)", Required = true)]
public virtual decimal? UsrSalesCommPct { get; set; }
public abstract class usrSalesCommPct : PX.Data.BQL.BqlDecimal.Field<usrSalesCommPct> { }
#endregion

#region UsrContingencyPct
[PXDBDecimal(BqlField = typeof(PX.Objects.AM.Standalone.StandaloneAMEstimateItemExt.usrContingencyPct))]
[PXUIField(DisplayName = "Contingency (%)", Required = true)]
public virtual decimal? UsrContingencyPct { get; set; }
public abstract class usrContingencyPct : PX.Data.BQL.BqlDecimal.Field<usrContingencyPct> { }
#endregion

#region UsrMargin
[PXDBDecimal(BqlField = typeof(PX.Objects.AM.Standalone.StandaloneAMEstimateItemExt.usrMargin))]
[PXUIField(DisplayName = "Margin")]
public virtual decimal? UsrMargin { get; set; }
public abstract class usrMargin : PX.Data.BQL.BqlDecimal.Field<usrMargin> { }
#endregion

#region UsrMarginPct
[PXDBDecimal(BqlField = typeof(PX.Objects.AM.Standalone.StandaloneAMEstimateItemExt.usrMarginPct))]
[PXUIField(DisplayName = "Margin (%)")]
public virtual decimal? UsrMarginPct { get; set; }
public abstract class usrMarginPct : PX.Data.BQL.BqlDecimal.Field<usrMarginPct> { }
#endregion

#region UsrTotalCost
[PXDecimal]
[PXUIField(DisplayName = "Total Cost")]
public virtual decimal? UsrTotalCost { get; set; }
public abstract class usrTotalCost : PX.Data.BQL.BqlDecimal.Field<usrTotalCost> { }
#endregion
}
}

 


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