Sometimes as programmers we can lose sight of the person on the other end of our code… the person actually using it. We get a business requirement and start coding. If you are fortunate, your job isn’t to simply code what you were told. I am so fortunate, and so part of my responsibility is to think about the solution from the perspective of the end user. Being empowered to think about how the software will be used and then to apply that perspective to adjust the end result enables me to create a solution that is more efficient and easier to use.
In our environment, a Sales Order tracks usage of material by a department so that the cost of supplies taken from inventory can be charged against their departmental budgets. Some clients prefer to only allow the department to be credited for returns for a short time to discourage hoarding within the department, which drives replenishment in the storeroom, only to flood the storeroom later with returns of unused material. Material can be returned at a $0 cost, and that material will be free to whoever the lucky recipient is that consumes it at a later date. This practice uses a Sales Order for issuing and crediting returns with the department. The “no departmental credit” return is handled via an IN Receipt.
Today, my task is to create a simple menu option to facilitate returning a Sales Order shipment, either generating the RC type Sales Order to give credit to the department or via an IN Receipt if no credit is to be given. However, we want the attendant in the storeroom to have a standard process to follow, so he or she will locate the original shipment and initiate the return process from there. We will use a SmartPanel (Dialog Box) to ask the user the pertinent questions to determine whether we will generate a Sales Order or a IN Receipt. The questions are handled via a PXFilter view. Our challenge in this request is to provide a list of serial numbers for the attendant to select according to how many pieces of a Lot or Serial Tracked item are returned. This “little help” will aid the attendant to ensure the return is against the proper original shipment for Lot/Serial tracked items.
The solution is quite simple, although I have done little with this in my journey to learn Acumatica so far. What I need is a grid in the smartpanel to present the serial numbers on the specific line of the shipment and allow checking the boxes for the serial numbers to be returned. How do we do this? Well, finally we reach the point of today’s post… We need to make a hidden DAC within our Graph Extension to hold the “Selected” checkbox and the serial numbers. Then we need to populate the view using a constructor.
Our DAC will be called ReturnLotSerial.
#region ReturnLotSerial
[PXHidden]
[Serializable()]
public partial class ReturnLotSerial : IBqlTable
{
#region Selected
[PXDBBool]
public virtual bool? Selected { get; set; }
public abstract class selected : PX.Data.BQL.BqlBool.Field<selected> { }
#endregion
#region LotSerialNbr
[LotSerialNbr]
public virtual string LotSerialNbr { get; set; }
public abstract class lotSerialNbr : PX.Data.BQL.BqlBool.Field<lotSerialNbr> { }
#endregion
}
#endregion
Our PXFilter view will simply expose that DAC.
public PXFilter<ReturnLotSerial> returnlotserial;
And our constructor for the PXFilter view will look into our base graph to retrieve the lot/serial numbers stored against the current SOShipLine selected in the SO Shipments graph.
#region Returnlotserial Constructor - Get Serial Nbrs from SOLineSplit(s)
public IEnumerable Returnlotserial()
{
int counter = 0;
foreach(SOShipLineSplit split in Base.splits.Select())
{
counter++;
ReturnLotSerial serial = new ReturnLotSerial()
{ LotSerialNbr = split.LotSerialNbr };
yield return serial;
}
if (counter == 0)
{
ReturnLotSerial serial = new ReturnLotSerial()
{ LotSerialNbr = Base.Transactions.Current.LotSerialNbr };
yield return serial;
}
}
#endregion
The constructor is the part I want to focus on so that I may return here the next time I need to do this. First of all, notice that the constructor has the same name as my view, but the first letter case is different. Next, notice the return type of IEnumerable. We want to return a list of records described by our hidden DAC, but the value we want to display comes from another view. Therefore, we will create a record of our hidden DAC and use “yield return” to add that record to the IEnumerable returned when the constructor completes execution. Since we may have a value in the “Transactions” (SOShipLine) but no split then we want to present the value directly from the SOShipLine. (I think there is an SOShipLineSplit always created in the end, but this is a safety net to make sure we have a value to display when applicable.)
Now we simply add the grid to our smartpanel and use the values. Since we are offering a “Selected” checkbox, remember that we want to filter our results to only the records with Selected = true.
Our grid on the smartpanel…

Happy Coding!