Is there any event triggered when highlighting a row? - acumatica

I created a ListView to show the list of documents, then created a button "Button A" to do some actions, my requirement is I would like the button status may be changed with the selected document changes.
Fox example: there are three documents in the following graphic, I want the button is enabled when I click Order-00001 or Order-00002, and it is disabled for Order-00003 due to no money in it.
I appreciate if you could give me a hint if there is any event to be raised when I click a row. Thanks a lot.

To reduce callback to the server there isn't a row selected event. Instead there is PXToolbarButton StateColumn property to control the button enabled state.
When you declare your button, you specify a Boolean DAC field that will enable/disable the button based on it's value. Note that the button needs the DependOnGrid property set to the ID of the grid to get the selected row:
<px:PXToolBarButton Text="Button A" DependOnGrid="grid" StateColumn="IsButtonVisible">
IsButtonVisible is a custom unbound Boolean DAC field (you may choose any name you want except isSelected/Selected which is reserved for checkbox):
#region IsButtonVisible
public abstract class isButtonVisible : IBqlField
{
}
protected bool? _IsButtonVisible;
[PXBool]
[PXUIField(DisplayName = "Is Button Visible", Enabled = false, Visible = false)]
public virtual bool? IsButtonVisible
{
get
{
return _IsButtonVisible;
}
set
{
_IsButtonVisible = value;
}
}
#endregion
You can set the value of IsButtonVisible in the RowSelected event based on your business logic:
protected virtual void DAC_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
DAC row = e.Row as DAC;
if (row != null)
{
bool yourCondition = ???;
row.IsButtonVisible = yourCondition;
}
}
Source:
Enable disable button of grid or PXToolBarButton, which depends from value of column in Acumatica

Related

How to Enable PO Link on Sales Order screen

I'm trying to change the logic that enables the "PO Link" action/button on the Sales Order lines. I'm not finding where the code that controls the enable/disable lives. Is it controlled by a workflow? If so, where?
I've tried the below but the SetEnable() is being overridden, apparently.
public class MySOOrderEntryExt :
PXGraphExtension<PX.Objects.SO.GraphExtensions.SOOrderEntryExt.POLinkDialog,
PX.Objects.SO.GraphExtensions.SOOrderEntryExt.PurchaseSupplyBaseExt, SOOrderEntry>
{
public void _(Events.RowSelected<SOOrder> e)
{
//Base.Actions["pOSupplyOK"].SetEnabled(false); //Doesn't work.
Base.Actions["pOSupplyOK"].SetVisible(false);
}
}
Any ideas would be great.
TIA!
The control consists of 2 components. In the ASPX in the ActionBar of the grid, teh button is defined as:
<px:PXToolBarButton Text="PO Link" DependOnGrid="grid" StateColumn="IsPOLinkAllowed">
<AutoCallBack Command="POSupplyOK" Target="ds" ></AutoCallBack>
</px:PXToolBarButton>
The StateColumn refers to the field that determines if the action/button is enabled or not. This is defined in SOLine in the field IsPOLinkAllowed as:
#region IsPOLinkAllowed
public abstract class isPOLinkAllowed : PX.Data.BQL.BqlBool.Field<isPOLinkAllowed> { }
[PXFormula(typeof(Switch<Case<Where<SOLine.pOCreate, Equal<True>, And<SOLine.operation, Equal<SOOperation.issue>>>, True>, False>))]
[PXUIField(DisplayName = "", Visibility = PXUIVisibility.Invisible, Visible = false, Enabled = false)]
[PXBool]
public virtual bool? IsPOLinkAllowed
{
get;
set;
}
#endregion
The PXFormula indicates that the POCreate field must be true and the operation of the Sales Order be an Issue.
The simplest way to modify this behavior likely is to change the attributes on the field via a DAC extension or CacheAttached in the graph to result in true when you want it enabled.

Setting the Value of a Custom Field in Acumatica 2019 R1

I am in the process of upgrading from Acumatica 2018 R2 to 2019 R1. In quite a few of my customizations, I have code, triggered by a button click or an event handler, which sets/changes the value of a custom field. That was working as expected in 2018 R2. However, in 2019 R1 the values on the custom fields are not being updated. Here's a simple example.
public class SOOrderEntry_SOOpenPOsGILink_Extension : PXGraphExtension<SOOrderEntry>
{
protected virtual void SOLine_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SOLine row = (SOLine)e.Row;
if (row != null)
{
bool isEmpty = true;
SOLineExt ext = row.GetExtension<SOLineExt>();
// logic determining value of isEmpty
ext.UsrEnableOpenPOs = isEmpty;
}
}
}
Where UsrEnableOpenPOs is defined as folows.
public class SOLineExt : PXCacheExtension<PX.Objects.SO.SOLine>
{
#region UsrEnableOpenPOs
[PXBool]
[PXUIField(DisplayName="EnableOpenPOs", Enabled = false, Visible=false)]
[PXUnboundDefault(false, PersistingCheck = PXPersistingCheck.Nothing)]
public virtual bool? UsrEnableOpenPOs { get; set; }
public abstract class usrEnableOpenPOs : PX.Data.BQL.BqlBool.Field<usrEnableOpenPOs> { }
#endregion
}
In this example, when a SOLine is selected on the SO Order Entry screen, the value of SOLineExt.UsrEnableOpenPOs should be set to the value of isEmpty. This code works in 2018 R2 and correctly updates UsrEnableOpenPOs. However, in 2019 R1, the code is triggered correctly and runs, but the value on the screen is not updated.
As I mentioned, we have quite a few instances where we are running into this problem. In some cases the code is triggered by a button click and in other cases by different events like RowSelected, RowInserting, FieldUpdated and RowUpdated.
I would appreciate some insight on why this code is no longer working and what I can do to fix it.
Should always try to set the value in cache vs the row instance.
ex:
sender.SetValueExt<SOLineExt.usrEnableOpenPOs>(row, isEmptry);
Unbound fields should be set in the RowSelecting or FieldSelecting events. The RowSelected event should be for UI changes such as disabled, visible, etc. fields.

Hide Columns in Grid by Default

With a new custom screen/graph/DAC, how can I make columns in a grid hidden by default? That is I want the column / controls in the Grid but only shown if the user goes in to the Column Configuration and selects to add it.
(These are purely informational columns on the grid of a custom Processing screen)
Visibility of DAC fields is controlled by PXUIField attribute properties.
The 'Visible' property determines whether or not the field is shown on screen.
The 'Visibility' property determines whether or not the field is available for display.
For your use case, you want to hide it by default (Visible = false) and make it available for display in the grid column selection dialog (Visibility = PXUIVisibility.Visible):
[PXUIField(Visibility = PXUIVisibility.Visible, Visible = false)]
You can also set these properties using static functions instead of DAC field attributes:
PXUIFieldAttribute.SetVisibility(cache, null, typeof(DAC.field).Name, PXUIVisibility.Visible);
PXUIFieldAttribute.SetVisible(cache, null, typeof(DAC.field).Name, false);
In the DAC or Graph you can set the fields Visible property to false
Example found on sales order for the "Line Order" field.
#region SortOrder
public abstract class sortOrder : PX.Data.IBqlField
{
}
protected Int32? _SortOrder;
[PXUIField(DisplayName = AP.APTran.sortOrder.DispalyName, Visible = false, Enabled = false)]
[PXDBInt]
public virtual Int32? SortOrder
{
get
{
return this._SortOrder;
}
set
{
this._SortOrder = value;
}
}
#endregion

How to display product availability in Opportunity Products Grid footer?

In Sales Order documents grid footer. It displays the product's availability.
How to do the same in Opportunity products grid ?
More so, how do you enforce it to be displayed at the footer
instead of a simple grid column ? Is there such attribute ?
Thanks for the replies.
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:

Hide/Disable other fields based on Input field

I want to hide or update a field on the UI based on conditions of another field.
For example, if I have a field called Color:
[PXUIField(DisplayName="Color")]
[PXStringList("Red,Blue,Other")]
[PXDefault("Red")]
And text field for comments only shown when "Other" is selected, how is this accomplished?
The requested behavior can either be accomplished either with a series of event handlers or with a bunch of attributes. You can find several examples on how to subscribe to the RowSelected and FieldUpdated events in the T200 training course, available at Acumatica University and Acumatica Open University
Going with field attributes is a more convenient and way easier option for your particular scenario. I would recommend setting CommitChanges to True for the drop-down, so the Comments field is cleared and disabled/enabled immediately after the user updates Color. Also, it's very to have your Color declared after Comments, so the framework will process Comments field first and always clear the current Comments value after the Color field got updated.
public class Other : Constant<string>
{
public Other() : base("Other") { }
}
public abstract class comments : IBqlField { }
[PXDBString(255, IsUnicode = true)]
[PXUIField(DisplayName = "Comments")]
[PXUIEnabled(typeof(Where<color, Equal<Other>>))]
[PXFormula(typeof(Default<color>))]
[PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
public string Comments { get; set; }
public abstract class color : IBqlField { }
[PXDBString(10, IsUnicode = true)]
[PXUIField(DisplayName = "Color")]
[PXStringList("Red,Blue,Other")]
[PXDefault("Red")]
public string Color { get; set; }
The only way to conditionally hide/show editor on a form is though the RowSelected event handler:
public void YourDAC_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
YourDAC row = e.Row as YourDAC;
if (row == null) return;
PXUIFieldAttribute.SetVisible<YourDAC.comments>(sender, row, row.Color == "Other");
}
I believe, in the T200 training course, there are several examples on the PXUIFieldAttribute.SetVisible method.

Resources