0
votes

I have created a customization to add the Item Status to the SOLine. The graph code and DAC compile just fine and give no errors. When I check the new field of status it is just blank. Here is how I went about this:

First the DAC:

public class SOLineExt : PXCacheExtension<PX.Objects.SO.SOLine>
  {
    #region ItemStatus
    public abstract class itemStatus : PX.Data.IBqlField
    {
    }
    protected string _ItemStatus;

    [PXString()]
    [PXDefault()]
    [PXUIField(DisplayName = "Status", IsReadOnly = true)]
    public virtual string ItemStatus
    {
      get
      {
        return this._ItemStatus;
      }
      set
      {
        this._ItemStatus = value;
      }
    }
    #endregion
  }

Graph:

  public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
  {
    #region Event Handlers
protected void SOLine_RowSelecting(PXCache cache, PXRowSelectingEventArgs e,PXRowSelecting InvokeBaseHandler)
    {
if(InvokeBaseHandler != null)
           InvokeBaseHandler(cache, e);
            var row = (SOLine)e.Row;
            if (row == null) return;

                    InventoryItem item = PXSelect<InventoryItem, Where<InventoryItem.inventoryID, Equal<Required<SOLine.inventoryID>>>>.Select(Base, row.InventoryID);
                    if(item != null){
                      SOLineExt soLinesExt = row.GetExtension<SOLineExt>();
                    if (soLinesExt != null){
                       if (item.ItemStatus == 'AC')
                        soLinesExt.ItemStatus = "Active";
                     if (item.ItemStatus == 'NS')
                      soLinesExt.ItemStatus = "No Sales"; 
                      if (item.ItemStatus == 'NP')
                      soLinesExt.ItemStatus = "No Purchases"; 
                      if (item.ItemStatus == 'NR')
                      soLinesExt.ItemStatus = "No Request"; 
                      if (item.ItemStatus == 'IN')
                      soLinesExt.ItemStatus = "Inatctive"; 
                      if (item.ItemStatus == 'DE')
                      soLinesExt.ItemStatus = "Marked for Deletion"; 

                    }  
                    }


    }
    #endregion
  }

I have used a similar method for this to add other fields onto grids, it's just this field in particular I'm having trouble with. Noticed that I do want the full status name to show instead of just the two character code.

1

1 Answers

2
votes

Option # 1

You can utilize PXDBScalar and PXDefault as below to achieve your goal. You can refer the comment for each attribute decorated for this custom field.

public class SOLineExt : PXCacheExtension<PX.Objects.SO.SOLine>
{
    #region UsrItemStatus
    public abstract class usrItemStatus : PX.Data.IBqlField
    {
    }
    protected string _UsrItemStatus;

    [PXString()]
    [PXUIField(DisplayName = "Status", IsReadOnly = true)]
    //Sub-Select or Sub Query - required to get value for Saved SO Lines
    [PXDBScalar(typeof(Search<InventoryItem.itemStatus, 
             Where<InventoryItem.inventoryID, Equal<SOLine.inventoryID>>>))]
    //StringList Attribute so that you don’t need to convert value to display text
    [InventoryItemStatus.List]
    //Defaulted when inserting new SO Line
    [PXDefault(typeof(Search<InventoryItem.itemStatus, 
             Where<InventoryItem.inventoryID, Equal<Current<SOLine.inventoryID>>>>),
               PersistingCheck = PXPersistingCheck.Nothing)]
    //Triggering default assignment upon changing Inventory ID in SO Line 
    [PXFormula(typeof(Default<SOLine.inventoryID>))]
    public virtual string UsrItemStatus
    {
        get
        {
            return this._UsrItemStatus;
        }
        set
        {
            this._UsrItemStatus = value;
        }
    }
    #endregion
}

Option # 2

Include InventoryItem DAC in data view (Transactions in this specific case) working with Document Details Grid. And add InventoryItem__ItemStatus field to Grid. Out-of-box SOOrderEntry Graph has implementation of data view delegate for Transactions so we will have to modify that as well.

public class SOOrderEntryPXDemoExt : PXGraphExtension<SOOrderEntry>
{
    public override void Initialize()
    {
        Base.Transactions.Join<InnerJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<SOLine.inventoryID>>>>();
    }

    [PX.Api.Export.PXOptimizationBehavior(IgnoreBqlDelegate = true)]
    protected virtual IEnumerable transactions()
    {
        PXSelectBase<SOLine> query =
            new PXSelectJoin<SOLine,
                    LeftJoin<INItemCost, On<INItemCost.inventoryID, Equal<SOLine.inventoryID>>,
                    InnerJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<SOLine.inventoryID>>>>,
                    Where<SOLine.orderType, Equal<Current<SOOrder.orderType>>,
                        And<SOLine.orderNbr, Equal<Current<SOOrder.orderNbr>>>>,
                    OrderBy<Asc<SOLine.orderType, Asc<SOLine.orderNbr, Asc<SOLine.lineNbr>>>>>(Base);

        var ret = new List<PXResult<SOLine, INItemCost, InventoryItem>>();
        int startRow = PXView.StartRow;
        int totalRows = 0;
        foreach (PXResult<SOLine, INItemCost, InventoryItem> record in query.View.Select(
            PXView.Currents, PXView.Parameters, PXView.Searches, PXView.SortColumns,
            PXView.Descendings, PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows))
        {
            SOLine line = (SOLine)record;
            INItemCost itemCost = (INItemCost)record;

            Base.initemcost.StoreCached(new PXCommandKey(new object[] { line.InventoryID }), new List<object> { itemCost });

            ret.Add(record);
        }
        PXView.StartRow = 0;
        return ret;
    }
}

enter image description here