I was over thinking this this morning.
My ASPX looks like a processing from.
The detail view isn’t a processing view it’s just the good old fashioned view.
public SelectFrom<MAXXPOSupplyPlanDetail>.
Where<MAXXPOSupplyPlanDetail.planID.IsEqual<MAXXPOGeneratePOFromSupplyPlanFilter.planID.FromCurrent>.
And<MAXXPOSupplyPlanDetail.purchaseOrderNbr.IsNull>.
And<MAXXPOSupplyPlanDetail.vendorID.IsEqual<MAXXPOGeneratePOFromSupplyPlanFilter.vendorID.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.vendorID.FromCurrent.IsNull>>.
And<MAXXPOSupplyPlanDetail.siteID.IsEqual<MAXXPOGeneratePOFromSupplyPlanFilter.siteID.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.siteID.FromCurrent.IsNull>>.
And<MAXXPOSupplyPlanDetail.requestedDate.IsGreaterEqual<MAXXPOGeneratePOFromSupplyPlanFilter.fromDateRequested.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.fromDateRequested.FromCurrent.IsNull>>.
And<MAXXPOSupplyPlanDetail.requestedDate.IsLessEqual<MAXXPOGeneratePOFromSupplyPlanFilter.toDateRequested.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.toDateRequested.FromCurrent.IsNull>>>.
OrderBy<MAXXPOSupplyPlanDetail.inventoryID.Desc, MAXXPOSupplyPlanDetail.requestedDate.Asc>.
View
SupplyPlanDetails;
And then the action creates a list of the detail records that were selected which is passed to a PXLongOperation.
#region i Actions ]
public PXAction<MAXXPOGeneratePOFromSupplyPlanFilter> RunGeneratePurchaseOrder;
PXButton(Connotation = PX.Data.WorkflowAPI.ActionConnotation.Success)]
PXUIField(DisplayName = "Generate Purchase Order", Enabled = true)]
protected virtual IEnumerable runGeneratePurchaseOrder(PXAdapter adapter)
{
List<MAXXPOGeneratePOFromSupplyPlanFilter> list = new List<MAXXPOGeneratePOFromSupplyPlanFilter>();
foreach (MAXXPOGeneratePOFromSupplyPlanFilter purchasePlan in adapter.Get<MAXXPOGeneratePOFromSupplyPlanFilter>())
{
list.Add(purchasePlan);
}
var filters = Filter.Current;
List<MAXXPOSupplyPlanDetail> selectedSupplyPlanDetails =
SupplyPlanDetails
.Select()
.RowCast<MAXXPOSupplyPlanDetail>()
.Where(x => x.Selected == true)
.ToList();
PXLongOperation.StartOperation(this, delegate ()
{
GeneratePurchaseOrders(filters,selectedSupplyPlanDetails);
});
return list;
}
Hi Matthew! I don’t know how much of this code you’ve been able to convert already, but I figure I’d provide a basic example of how to turn this existing page into a processing page for anyone else curious:
Convert SelectFrom data view to PXProcessing data view
public PXProcessing<MAXXPOSupplyPlanDetail, Where<MAXXPOSupplyPlanDetail.planID.IsEqual<MAXXPOGeneratePOFromSupplyPlanFilter.planID.FromCurrent>.
And<MAXXPOSupplyPlanDetail.purchaseOrderNbr.IsNull>.
And<MAXXPOSupplyPlanDetail.vendorID.IsEqual<MAXXPOGeneratePOFromSupplyPlanFilter.vendorID.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.vendorID.FromCurrent.IsNull>>.
And<MAXXPOSupplyPlanDetail.siteID.IsEqual<MAXXPOGeneratePOFromSupplyPlanFilter.siteID.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.siteID.FromCurrent.IsNull>>.
And<MAXXPOSupplyPlanDetail.requestedDate.IsGreaterEqual<MAXXPOGeneratePOFromSupplyPlanFilter.fromDateRequested.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.fromDateRequested.FromCurrent.IsNull>>.
And<MAXXPOSupplyPlanDetail.requestedDate.IsLessEqual<MAXXPOGeneratePOFromSupplyPlanFilter.toDateRequested.FromCurrent>.
Or<MAXXPOGeneratePOFromSupplyPlanFilter.toDateRequested.FromCurrent.IsNull>>>,
OrderBy<MAXXPOSupplyPlanDetail.inventoryID.Desc, MAXXPOSupplyPlanDetail.requestedDate.Asc>> SupplyPlanDetails;
Adding a PXProcessing data view like this will automatically add the “Process” and “Process All” buttons to the toolbar on the page. You can then specify the process delegate of the data view, which will be the method that triggers when the user clicks either of the two buttons.
SetProcessDelegate call
public GraphConstructor()
{
var filters = Filter.Current;
List<MAXXPOSupplyPlanDetail> selectedSupplyPlanDetails =
SupplyPlanDetails
.Select()
.RowCast<MAXXPOSupplyPlanDetail>()
.Where(x => x.Selected == true)
.ToList();
SupplyPlanDetails.SetProcessDelegate(
delegate (List<MAXXPOSupplyPlanDetail> list)
{
GeneratePurchaseOrders(filters, selectedSupplyPlanDetails);
});
}
In the above snippet, just replace “GraphConstructor” with whatever the name of your graph is that the screen is using. One nice additional benefit is that the call for GeneratePurchaseOrders will automatically run in a long running operation when it’s used as the process delegate for the processing data view, so there’s no need to create the long running operation separately (There won’t be any adverse effects if you do, doing so will simply use the existing long operation thread for the delegate if there is one).
You’ll also just want to make sure that you have an unbound “Selected” field added to your custom DAC, like so
Selected checkbox
#region Selected
public abstract class selected : BqlBool.Field<selected> { }
lPXBool]
&PXDefault(false, PersistingCheck = PXPersistingCheck.Nothing)]
PXUIField(DisplayName = "Selected")]
public virtual bool? Selected { get; set; }
#endregion
Then the processing page will use whatever records are marked as selected and process those when the user clicks “Process”.
For anyone else looking for more info, I would definitely recommend going through the material for the T240 Processing Forms course here: T240 Processing Forms 2023 R2 (acumatica.com)
Hi @NicholasBova52 ,
Thanks for replying, I attempted to implement your suggestions however running into an issue where nothing is happening when clicking either of the processing buttons. Debugging the code the constructor looks to be working fine however the GeneratePurchaseOrders method never gets hit.
Hi @NicholasBova52 ,
Thanks for replying, I attempted to implement your suggestions however running into an issue where nothing is happening when clicking either of the processing buttons. Debugging the code the constructor looks to be working fine however the GeneratePurchaseOrders method never gets hit.
After looking at the code again, I think there is a mistake I made in the setup for the processing delegate. We should be passing the list variable of MAXXPOSupplyPlanDetail to the method GeneratePurchaseOrders instead of the one selected from selectedSupplyPlanDetails. Since no records are selected at the time the constructor runs, the collection is empty and the process delegate method will not run.
Corrected code
public GraphConstructor()
{
SupplyPlanDetails.SetProcessDelegate(
delegate (List<MAXXPOSupplyPlanDetail> list)
{
GeneratePurchaseOrders(Filter.Current, list);
});
}
Give this a try and let me know if the method is still not triggering.
Thanks @NicholasBova52 ,
It was giving me a PX1008 error so I tweaked the code a smidge, to make it calm down.
var filter = Filter.Current;
SupplyPlanDetails.SetProcessDelegate(
delegate (List<MAXXPOSupplyPlanDetail> list)
{
GeneratePurchaseOrders(filter, list);
});
The screen seems to be behaving how I expect.