FGetting a Form Field from a grid extension - acumatica

I have added a field to the Prepare Replenishment form that needs to be updated when a user selects a row in the Replenishment Item grid. How do I access the field. I know it is in the INReplenishmentFilterExt but I can't figure out how to get access to the extension.
Edit #1: I am able to get the value of the field but it does not update on the screen when I use cache.SetValue. I am trying to update this filter extension field from inside of the Selected event handler.
protected void INReplenishmentItem_Selected_FieldUpdating(PXCache cache, PXFieldUpdatingEventArgs e)
{
var row = (INReplenishmentItem)e.Row;
if (row == null)
return;
INReplenishmentFilter filter = Base.Filter.Current;
INReplenishmentFilterExt filterExt = PXCache<INReplenishmentFilter>.GetExtension<INReplenishmentFilterExt>(filter);
decimal poAmount = filterExt.UsrPOAmount.HasValue ? filterExt.UsrPOAmount.Value : 0;
decimal lastPrice = pvi.LastPrice.HasValue ? pvi.LastPrice.Value : 0;
decimal newPOAmount = poAmount + lastPrice;
cache.SetValue<INReplenishmentFilterExt.usrPOAmount>(filterExt, newPOAmount);
}

You cannot set the value of the Filter using the Cache of INReplenishmentItem.
I have edited my answer, the code below should work.
//Always use virtual methods for Event Handlers
protected virtual void INReplenishmentItem_Selected_FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
{
//Try not to use vars. Especially when you know the Type of the object
INReplenishmentItem row = e.Row as INReplenishmentItem;
if (row != null)
{
INReplenishmentFilter filter = Base.Filter.Current;
INReplenishmentFilterExt filterExt = PXCache<INReplenishmentFilter>.GetExtension<INReplenishmentFilterExt>(filter);
decimal poAmount = filterExt.UsrPOAmount ?? 0;
decimal lastPrice = pvi.LastPrice ?? 0;//Not sure what pvi is
decimal newPOAmount = poAmount + lastPrice;
//"sender" is the cache that specifically stores the datatype of row
//Therefor you cannot use it to update records of a different datatype
//You also should not pass an Extension into the argument that should be the row object you are trying to update
Base.Filter.Cache.SetValueExt<INReplenishmentFilterExt.usrPOAmount>(filter, newPOAmount);
}
}

Related

Hiding value of a selector in a grid dynamically

I am trying to hide these duplicate inventory ID values for the "price" and "Cost" lines (when one "adds" an item to the grid it creates three lines), but the selector description still appears.
How can I just make these value come up blank in the grid?
Even better, how can I disable a link command so if someone inadvertently clicks then it wont link to the stock item screen?
Here is my code thus far:
protected void _(Events.FieldSelecting<FPPriceSheetDetail, FPPriceSheetDetail.inventoryID> e)
{
if (e.Row is null) return;
if (e.Row.RowType == FPPriceSheetRowType.BreakQty) return;
var state = PXFieldState.CreateInstance(e.ReturnState, typeof(string), true, false, 1, null, null, null, nameof(FPPriceSheetDetail.inventoryID));
state.SelectorMode = PXSelectorMode.TextMode;
state.DescriptionName = "";
state.ValueField = "";
state.Visibility = PXUIVisibility.Visible;
state.Visible = true;
e.ReturnState = state;
e.ReturnValue = "";
}
I would rather review the pxSelector and in the condition only show 1-row type - this will remove the duplicates. The point of the selector is to select one of the values within the result - assuming all the information the selector are selectable.

How can i load dropdown values dynamically in acumatica for each row with different dropdown values?

Example:
As per the Below screenshot, i have to combine below two grids into one grid and the first grid(query list) will display as it is and the second grid values should show as drop down for the respective query.
Samplegridsimage
when i tried to use field selecting event, it is loading all vales from second grid but i need only 3 values for fuel type value and for others different drop down.
can anyone suggest how to get only particular values in the drop down.
protected virtual void KNRWTAXQueries_Response_FieldSelecting(PXCache cache, PXFieldSelectingEventArgs e)
{
KNRWTAXQueries doc = e.Row as KNRWTAXQueries;
if (doc == null) return;
List<string> Responsevalues = new List<string>();
List<string> ResponseLables = new List<string>();
if (QueryList.Current != null)
{
if (Base.Transactions.Current != null)
{
foreach (KNRWTAXQueries queries in PXSelect<KNRWTAXQueries, Where<KNRWTAXQueries.nonStockItemID, Equal<Required<APTran.inventoryID>>>>.Select(Base, doc.NonStockItemID))
{
foreach (KNRWTAXResponse response in PXSelect<KNRWTAXResponse, Where<KNRWTAXResponse.tAXQueID, Equal<Required<KNRWTAXResponse.tAXQueID>>>>.
Select(Base, queries.Taxqueid))
{
Responsevalues.Add(response.Response);
ResponseLables.Add(response.Response);
e.ReturnState = PXStringState.CreateInstance(e.ReturnState, 255, true, typeof(KNRWTAXQueries.response).Name, false, 1, string.Empty, Responsevalues.ToArray(),
ResponseLables.ToArray(), true, null);
}
}
}
}
// ((PXStringState)e.ReturnState).MultiSelect = false;
}
You can use RowSelected event of the row to set the list. No need to use FieldSelecting (however you can use field selecting too)
You should use PXStringListAttribute.SetList method to set new list instead of using string state
You should set MatrixMode=true in the aspx grid row so that list is recreated for each row (oterwise the list will be the same for all rows)
<px:PXGridColumn DataField="OrigTranType" Type="DropDownList" MatrixMode="true" />

How to set First Dropdown value as default for first line in grid then Second value defaults from second line in grid

In the Product drop-down, there are 2 values, First value (Product) will default for first line only and Second value (Co-Product) will default from the second line.
I tried this in FieldDefaulting event
protected void TSFormulaProdsNCoProds_Product_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e)
{
var row = (TSFormulaProdsNCoProds)e.Row;
if (row == null)
return;
if (TSFormProdsNCoProds.Select().Count == 0)
{
e.NewValue = "P";
}
else
{
e.NewValue = "C";
}
}
Can anyone provide a suggestion to me?
Most likely you have PXDefault attribute decorated at DAC level. In that case, you need to set Cancel flag to prevent execution of FieldDefaulting event handlers that are defined in attributes.
Example :-
protected void TSFormulaProdsNCoProds_Product_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e)
{
var row = (TSFormulaProdsNCoProds)e.Row;
if (row == null)
return;
e.NewValue = (TSFormProdsNCoProds.Select().Count == 0) ? "P" : "C";
e.Cancel = true;
}
This is explained in Example 5.2: Inserting a Default Detail Data Record of T200 Acumatica Framework Fundamental course.

Acumatica - FieldDefaulting update ImageUrl from DAC extension

I am trying to update the Inventory Item ImageUrl if it is found to be null with some conditions. I have added a Usr field called UsrStyleImg to the Item Class screen. This field is for a basic image of an item and it is stored in the database. The functionality I want is if the Inventory Item does not have an image in the ImageUrl then it will default to the UsrStyleImg that is connected with the ItemClassID. ItemClassID is also found on the Stock Item Screen. Here is the code I have in the InventoryItemMaint graph:
protected void InventoryItem_ImageUrl_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e)
{
var row = (InventoryItem)e.Row;
if (row == null) return;
var item = (INItemClass)PXSelect<INItemClass, Where<INItemClass.itemClassID, Equal<Current<InventoryItem.itemClassID>>>>.Select(Base, row.ItemClassID);
var image = PXSelect<InventoryItem, Where<InventoryItem.imageUrl, Equal<Current<InventoryItem.imageUrl>>>>.Select(Base, row.ImageUrl);
if (image != null)
return;
else {
e.NewValue = item.GetExtension<INItemClassExt>().UsrStyleImg;
}
}
The code compiles fine but when I test with an Item that has an Item Class attached to it with an image in the INItemClass table called UsrStyleImg it does not populate to the imageUrl found in the Inventory Item table or the Stock Item screen. I have also tried this with FieldSelecting and using the e.ReturnValue with still the same results.
If I need more clarification please let me know.
Try using a RowSelecting Event
protected virtual void InventoryItem_RowSelecting(PXCache sender, PXRowSelectingEventArgs e)
{
InventoryItem row = e.Row as InventoryItem;
//Extra checks to prevent infinite loops
if (row != null && !string.IsNullOrWhiteSpace(row.InventoryCD) && Base.Item.Cache.GetStatus(row) == PXEntryStatus.Notchanged)
{
if (!string.IsNullOrWhiteSpace(row.ItemClassID))
{
//You must always use a PXConnectionScope if Selecting during RowSelecting
using (new PXConnectionScope())
{
//If you're going to pass in a value in .Select, use Required instead of Current.
INItemClass itemClass = PXSelectReadonly<INItemClass, Where<INItemClass.itemClassID, Equal<Required<INItemClass.itemClassID>>>>.Select(Base, row.ItemClassID);
if (itemClass != null && string.IsNullOrWhiteSpace(row.ImageUrl))
{
INItemClassExt itemClassExt = itemClass.GetExtension<INItemClassExt>();
//To prevent unneeded update if it's blank
if (!string.IsNullOrWhiteSpace(itemClassExt.UsrStyleImg))
{
row.ImageUrl = itemClassExt .UsrStyleImg;
//Force set the status in the Cache, otherwise it infinite loops
Base.Item.Cache.SetStatus(row, PXEntryStatus.Updated);
Base.Item.Update(row);
}
}
}
}
}
}

Change String length or decimal precision of field attribute dynamically

I'm trying to use setup data from one table to allow me to format fields on the fly / dynamically. I know I can change field names and visibility based on the PXUIFieldAttribute class, but changing the precision or string length is a bit trickier, obviously. From the research I've done, I've come up with the following example code that seems like it should work - but I get the error:
"Unable to cast object of type 'PX.Data.PXUIFieldAttribute' to type 'PX.Data.PXDBDecimalAttribute'.
I don't see why this is occurring...
protected virtual void xTACOpenSourceDetail_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
var osd = (PXCache)sender;
foreach (PXDBDecimalAttribute attribute in this.Caches<xTACOpenSourceDetail>().GetAttributes("Number1"))
{
PXDBDecimalAttribute someAttribute = attribute as PXDBDecimalAttribute;
if (someAttribute != null)
{
someAttribute.DBProperties._precision = 4;
}
}
}
I just tried the below code in sales order screen and it seems working!
var props = typeof(SOOrder).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(PXDecimalAttribute)));
foreach (System.Reflection.PropertyInfo item in props)
{
PXDecimalAttribute.SetPrecision(this.Base.Caches[typeof(SOOrder)], item.Name, 1);
}
You might need to change this to match your DAC.

Resources