If we compare to sales order, the sales order line gets its value from LSSOLine during Availabilty_FieldSelecting
. The wire-up on the page is on the tab via StatusField="Availability"
. We can do something similar by adding an unbound extension field and then during a field selecting fill in the value. An alternative would be to implement an LSCROpportunityProducts
class that is inherits LSSelect
similar to LSSoLine
(a better preferred solution). To keep this simple and focus on just getting the field to display text, I will use an extension field and a simple field selecting in the extension graph for opportunity.
(1) In a dac extension, create an unbound field (MyAvailability is the example field):
[PXTable(typeof(CROpportunityProducts.cROpportunityID), typeof(CROpportunityProducts.cROpportunityProductID), IsOptional = true)]
[Serializable]
public class CROpportunityProductsMyExtension : PXCacheExtension<CROpportunityProducts>
{
#region MyAvailability
public abstract class myAvailability : PX.Data.IBqlField
{
}
protected string _MyAvailability;
[PXString(IsUnicode = true)]
[PXUIField(DisplayName = "Product Availability", Enabled = false)]
public virtual string MyAvailability
{
get
{
return this._MyAvailability;
}
set
{
this._MyAvailability = value;
}
}
#endregion
}
(2) On the opportunity products tab, wire up the new field as the grid status value by setting property StatusField
. The page needs modified to add this value and should look something like this when added (requires screen customization in your project -> actions edit ASPX and locate ProductsGrid to paste in your StatusField and value):
<px:PXGrid ID="ProductsGrid" SkinID="Details" runat="server" Width="100%"
Height="500px" DataSourceID="ds" ActionsPosition="Top" BorderWidth="0px"
SyncPosition="true" StatusField="MyAvailability">
(3) Now in a graph extension populate the field:
Edit: The use of Current<>
does not always contain the correct currently highlighted row in the UI. Switched to Required<>
based on the PXFieldSelectingEventArgs.Row
and the results are correct for multiple rows in the products tab.
public class CROpportunityMaintMyExtension : PXGraphExtension<OpportunityMaint>
{
public virtual void CROpportunityProducts_MyAvailability_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
var row = (CROpportunityProducts) e.Row;
if (row == null)
{
e.ReturnValue = string.Empty;
return;
}
INLocationStatus locationStatus = PXSelectGroupBy<INLocationStatus,
Where<INLocationStatus.inventoryID, Equal<Required<CROpportunityProducts.inventoryID>>,
And2<Where<INLocationStatus.subItemID, Equal<Required<CROpportunityProducts.subItemID>>,
Or<Not<FeatureInstalled<PX.Objects.CS.FeaturesSet.subItem>>>>,
And<Where<INLocationStatus.siteID, Equal<Required<CROpportunityProducts.siteID>>,
Or<Required<CROpportunityProducts.siteID>, IsNull>>>>>,
Aggregate<Sum<INLocationStatus.qtyOnHand, Sum<INLocationStatus.qtyAvail>>>
>.Select(sender.Graph, row.InventoryID, row.SubItemID, row.SiteID, row.SiteID);
// Need to convert to transaction UOM... (this is always base units)
decimal? qtyOnHand = locationStatus?.QtyOnHand;
decimal? qtyAvail = locationStatus?.QtyAvail;
e.ReturnValue = $"Qty On hand = {qtyOnHand.GetValueOrDefault()} ; Qty Avail = {qtyAvail.GetValueOrDefault()}";
}
}
The results:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…