How do I redirect to a dashboard now that GIScreenHelper is marked obsolete? - acumatica

We have a dashboard that is accessed via the Inquiry menu on the Stocked Items page. Until our most recent minor upgrade on 2019 R2, the following code compiled without issue to allow opening the dashboard relevant to the current Inventory ID. It still compiles but with a warning that GIScreenHelper is obsolete and will be marked internal in the next upgrade. Hence my question... how do I redirect to a dashboard if I can't use GIScreenHelper to initialize the graph used in the PXRedirectRequiredException?
string screenID = "SS0010DB"; //DashboardID
PXSiteMapNode sm = GIScreenHelper.GetSiteMapNode(screenID);
PXGraph graph = GIScreenHelper.InstantiateGraph(screenID);
if (graph is LayoutMaint)
{
LayoutMaint copygraph = graph as LayoutMaint;
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters["InventoryID"] = item.InventoryCD;
copygraph.Filter.Current.Values = parameters;
throw new PXRedirectRequiredException(sm.Url, copygraph, PXBaseRedirectException.WindowMode.New, string.Empty);
}
I have tried initializing LayoutMaint directly, but I can't figure out what to set to specify which Screen ID to utilize and pass parameters.

I guess you have 2 options here:
Create the DashboardMaint graph instance which is the Dashboards page graph and provide the Name of the Dashboard and invoke the viewDashboard action of that graph.
Just take the code of the viewDashboard action of the DashboardMaint and redirect to your Dashboard directly:
[PXButton(ConfirmationType = PXConfirmationType.IfDirty, ConfirmationMessage = "Any unsaved changes will be discarded. Do you want to proceed?")]
[PXUIField(DisplayName = "View")]
public void viewDashboard()
{
throw new PXRedirectToUrlException(PXSiteMap.Provider.FindSiteMapNodeByScreenID(this.Dashboards.Current.ScreenID).Url, PXBaseRedirectException.WindowMode.Same, "View Dashboard");
}
UPDATED
Below is a code example how to open Dashboard with predefined value for Filter.
The example is written for Customer View dashboard.
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "CustomerView")]
protected virtual IEnumerable RedirectToCustomerViewDashboard(PXAdapter adapter)
{
string screenID = "DB000031"; //DashboardID
LayoutMaint graph;
using (new PXScreenIDScope(screenID))
{
graph = PXGraph.CreateInstance<LayoutMaint>(screenID);
}
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters["CustomerAccountID"] = "ABARTENDE";
graph.Filter.Current.Values = parameters;
throw new PXRedirectRequiredException(PXSiteMap.Provider.FindSiteMapNodeByScreenID(screenID).Url, graph, PXBaseRedirectException.WindowMode.New, string.Empty);
}
The key for the value is Name of the parameter from Dashboard definition

Related

Passing parameters to GraphAction in Acumatica from toolbar button

(Edited to better reflect the current state after help from the comments)
I have a graph extension to which I have added a PXAction and PXButton etc. The method (now) accepts parameters.
The button appears on the screen as expected an I can debug the action code in Visual Studio when the button is clicked.
// test params action.
public PXAction<InventoryItem> testParams;
[PXUIField(DisplayName = "Test Params", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXButton(CommitChanges = true)]
public virtual IEnumerable TestParams(PXAdapter adapter, [PXInt] int? siteID, [PXString] string testParamStr)
{
IEnumerable ret = adapter.Get();
if (adapter.Parameters != null)
{
int a = 0;
a++;
}
return adapter.Get();
}
After adding the parameters to my C# method and re publishing etc, the parameters appeared as options in the Parameter column below and I have been able to configure parameters to send through when I press the button on my stock item screen:
However... when I debug and look at the adapter, the method arguments (siteId and testParamsStr) are null as is adapter.Parameters
and adapter.CommandArguments is an empty string.
As per Hugues Beauséjour's comment, the documentation for amending an existing action describes just this but how do we get at the values in the C# code? Looking at existing actions in Acumatica I don't think I'm missing any markup attributes etc.
Ideally I'd like a zero-code way to do what I'm trying to do but I'm not sure that's possible so I'm trying very short action code that passes values to a central class we will write to allow users to set up their own parameters that the central class will process so that they don't have to do any lengthy coding in the action code (the rest of the story is longer but that's the bit that's relevant to this question!).
Thanks!
This is how to pass parameters using code only. I'm posting it to help other people who might need it. For configuring the wizard parameters, this will not help much unfortunately.
// Graph Action
public PXAction<MyPrimaryDAC> MyAction;
[PXButton]
[PXUIField(DisplayName = "My Action")]
public virtual IEnumerable myAction(PXAdapter adapter)
{
// String value coming from JavaScript is read in adapter.CommandArguments
string payload = adapter.CommandArguments;
}
// JavaScript calls the graph action with a string parameter in payload variable
var ds = px_alls['ds'];
var actionName = 'MyAction';
var payload = 'string value passed to server';
ds.executeCallback(actionName, payload);

How can I set a custom field on Acumatica Production Detail Operation when the Production Order is first created?

I have a custom field on an Acumatica Production Detail Operation (UsrEligibleForRoboticFulfillment) that I have created an Action to set based on criteria on the component items in the Materials tab. (code below)
I would like to call this Action to set the field as soon as the Production Order is created, but the split nature of the Production Order is such that there are no events on the Production Detail raised that I can attach to and call the Action. I've tried Row Inserted as well as Persist delegate on the Production Detail graph.
I CAN attach to either the AMProdItem Row Inserted or Persist Delegate on the Production Maint graph, but at this point in time the Operations and Materials have not yet been created.
What's the best way to update this field when a new Production Order is created?
Action code:
public PXAction<AMProdItem> UpdateEligibleForRoboticFulfillment;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Update Robotic Eligibility", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
protected void updateEligibleForRoboticFulfillment()
{
AMProdItem prodDetail = Base.ProdItemRecords.Current;
AMProdOper prodOper = Base.ProdOperRecords.Current;
InventoryItem finishedProduct = PXSelect<InventoryItem,
Where<InventoryItem.inventoryID, Equal<Current<AMProdItem.inventoryID>>>>.Select(Base).FirstOrDefault();
//Only production orders are eligible for robotic fulfillment, not disassemblies
if (prodDetail.OrderType == "MO")
{
bool wasRoboticsEligible = (prodOper.GetExtension<AMProdOperExt>().UsrEligibleForRoboticFulfillment ?? false);
//Get the current branchID
int branchID = (int)Base.Accessinfo.BranchID;
//Get the default site/warehouse for this branch.
INSite site = INTranHelper.GetDefaultSiteForItemBranch(branchID);
//Get the flag indicating whether this site is active for robotics
bool activeRobotics = site.GetExtension<INSiteExt>().UsrActiveRobotics ?? false;
//Get the flags for manual process and component robotics compatible
bool requiresManualProcess = finishedProduct.GetExtension<InventoryItemExt>().UsrManualFinishRequired ?? false;
//Gotta be prepared for the possibility that more than one component is used
//Check for any components that are NOT robotics eligible that have qty required and haven't already been fully allocated
PXResultset<AMProdMatl> components = PXSelectJoin<AMProdMatl,
InnerJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<AMProdMatl.inventoryID>,
And<InventoryItemExt.usrRoboticsCompatible, Equal<False>,
And<AMProdMatl.orderType, Equal<Current<AMProdOper.orderType>>,
And<AMProdMatl.prodOrdID, Equal<Current<AMProdOper.prodOrdID>>,
And<AMProdMatl.operationID, Equal<Current<AMProdOper.operationID>>,
And<AMProdMatl.qtyActual, Less<AMProdMatl.totalQtyRequired>,
And<AMProdMatl.qtyReq, Greater<decimal0>>>>>>>>>>
.Select(Base);
bool roboticsEligible = !requiresManualProcess && activeRobotics;
//If any component is not eligible, the whole operation is not eligible
if (components.Count > 0)
{
roboticsEligible = false;
}
//If the robotics eligible flag should have changed, change it
if (wasRoboticsEligible != roboticsEligible)
{
prodOper.GetExtension<AMProdOperExt>().UsrEligibleForRoboticFulfillment = roboticsEligible;
Base.ProdOperRecords.Update(prodOper);
}
}
}
Had to open a ticket with Acumatica; got a working solution! I had to enclose the persist delegate method in a transaction scope.
Override Persist() method of graph
Call base method first so that Operations and Materials on the Production Order Detail gets created
Enclosed in transaction scope
Something like this:
public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
if (/**/)
{
using (var ts = new PXTransactionScope())
{
//Call base method to persist
baseMethod();
/*Custom Logic here*/
ts.Complete();
}
}
else
baseMethod();
}

Acumatica Redirect to a Dashboard and pass parameter value issue

I'm successfully redirecting to a Dashboard passing parameter from Customers screen (AR303000) but, not able to replicate the result when I redirect to the Dashboard from Customer Pop Up Panel. it call the Dashboard without the parameter. I can see the code passing the value correctly, but the Dashboard does not display any value.
Any Help will be appreciated.
Thanks.
Alfredo
Here is a copy of the code.
#region CustomerCard
public PXAction<PX.Objects.AR.Customer> customerCard;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Customer Card")]
protected void CustomerCard()
{
Customer customer = Base.BAccount.Current;
if (customer != null)
{
string screenID = "DBPS0007"; //DashboardID
PXSiteMapNode sm = GIScreenHelper.GetSiteMapNode(screenID);
PXGraph graph = GIScreenHelper.InstantiateGraph(screenID);
if (graph is LayoutMaint)
{
LayoutMaint copygraph = graph as LayoutMaint;
Dictionary<string, object> parameters = new
Dictionary<string, object>();
parameters["CustomerAccountID"] = customer.AcctCD;
copygraph.Filter.Current.Values = parameters;
throw new PXRedirectRequiredException(sm.Url, copygraph,
PXBaseRedirectException.WindowMode.New, string.Empty);
}
}
}
#endregion

How to Redirect to a Dashboard and pass parameter value

Is it possible to redirect to a Dashboard Screen and pass dashboard parameter value on Acumatica? For example, the Customer View Dashboard on Acumatica has a parameter (see below) I would like to redirect to this screen with param value.
In order to redirect to Dashboard screen with param values, you can use the graph of the Dashboard(s) screen and pass the parameters to the Filter Dataview of the graph.
Then you can throw a PXRedirectRequiredException with Url, and graph(dashboard).
See snippet below:
public class CustomerMaint_Extension : PXGraphExtension<CustomerMaint>
{
#region Event Handlers
public PXAction<PX.Objects.AR.Customer> Test;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "test")]
protected void test()
{
Customer customer = Base.BAccount.Current;
if (customer != null)
{
string screenID = "DB000031";
PXSiteMapNode sm = GIScreenHelper.GetSiteMapNode(screenID);
PXGraph graph = GIScreenHelper.InstantiateGraph(screenID);
if (graph is LayoutMaint)
{
LayoutMaint copygraph = graph as LayoutMaint;
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters["CustomerAccountID"] = customer.AcctCD;
copygraph.Filter.Current.Values = parameters;
throw new PXRedirectRequiredException(sm.Url, copygraph, PXBaseRedirectException.WindowMode.New, String.Empty);
}
}
}
#endregion
}
See below:
Redirect with Parameter:

Custom Print Invoice Action on Process Screen

I am trying to have a print invoice Action on my new process screen which points to new custom report taking Customer Ref Nbr as a parameter. Any help on how to start with this?
In Acumatica redirection to another page (points to new custom report) is done by throwing redirection exceptions. For redirecting to a report page the exception you should use is 'PXReportRequiredException'.
Code for launching your custom report with parameter:
public PXAction<Customer> printInvoice;
[PXUIField(DisplayName = "Print Invoice", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
public virtual IEnumerable PrintInvoice(PXAdapter adapter)
{
Customer customer = [fetch desired customer record here];
if (customer != null && customer.RefNbr != null)
{
// Add your report parameters to a Dictionary<string, string> collection.
// The dictionary key is the parameter name as shown in the report editor.
// The dictionary value is the value you assign to that parameter.
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["RefNbr"] = customer.RefNbr;
// Provide your custom report ReportID
string reportID = "AR641000";
// Provide a title name for your report page
string reportName = "Customer Invoice"
// Redirect to report page by throwing a PXReportRequiredException object
throw new PXReportRequiredException(parameters, reportID, reportName);
}
return adapter.Get();
}
You can look up the parameter names in the Parameters tab of the Schema Builder dialog of Acumatica Report Designer:

Resources