Skip to main content
Solved

Custom Processing Form - Not Showing Processing DIalog?

  • January 12, 2022
  • 5 replies
  • 446 views

Forum|alt.badge.img

Hello,

I have created a custom processing form, based largely on the info from T240. The Graph makes use of a` PXFilteredProcessing` data view. The grid in the view is dynamically populated based on user selection. Both the loading/filtering of records and processing of checked records seems to work as expected; however, for some reason the Processing Dialog is not showing. When I initiate processing by clicking the β€œCalcuate” button (the caption I set for my β€œProcess” button), I merely get the little gray loading spinner (the one that appears anytime you save records, navigate, etc. in the system) NOT the actual processing dialog.

I have compared my code against Acumatica’s standard processing forms and see nothing that could explain this behavior. Any guidance would be appreciated.

 

My Graph code (some code omitted for brevity):


    public class MHPRProcessBenefits : PXGraph<MHPRProcessBenefits>
    {
        public PXCancel<ProcessBenefitFilter> Cancel;
        public PXFilter<ProcessBenefitFilter> Filter;
        public PXFilteredProcessing<PREmployee, ProcessBenefitFilter> ActiveEmps;
        public override bool IsDirty => false;


        protected IEnumerable<PREmployee> activeEmps()
        {
            var filter = Filter.Current;

            switch (filter?.CalcType)
            {
                case ACA_INIT:
                    return SelectFrom<PREmployee>
                        .Where<PREmployee.vStatus.IsEqual<VendorStatus.active>.And<PREmployeeExtension.usrInitMeasureCalcd.IsEqual<False>>>.View.Select(this).FirstTableItems;
                case ACA_STANDARD:
                case BENEFIT:
                    return SelectFrom<PREmployee>
                                .Where<PREmployee.vStatus.IsEqual<VendorStatus.active>>.View.Select(this).FirstTableItems;
                case RETIREMENT:
                    return SelectFrom<PREmployee>
                           .Where<PREmployee.vStatus.IsEqual<VendorStatus.active>.And<BAccountRetirmentExtension.usrHoursReqMet.IsEqual<False>>>.View.Select(this).FirstTableItems;
                default:
                    return new List<PREmployee>();

            }

        }

        protected virtual void _(Events.RowSelected<ProcessBenefitFilter> e)
        {
            var row = e.Row;
            if (row == null)
            {
                return;
            }

            ActiveEmps.SetProcessCaption("Calculate");
            ActiveEmps.SetProcessAllCaption("Calculate All");
            ActiveEmps.SetProcessDelegate<PREmployeePayrollSettingsMaint>(
                delegate (PREmployeePayrollSettingsMaint graph, PREmployee emp)
                {
                    graph.Clear();
                    var graphExt = graph.GetExtension<PREmployeeMaintExtension>();

                    try
                    {
                        switch (Filter.Current.CalcType)
                        {
                            case AppConstants.CalcOperation.ACA_INIT:
                                graphExt.updateInitialACA(emp, true);
                                break;
                            case AppConstants.CalcOperation.ACA_STANDARD:
                                graphExt.updateStandardACA(emp, true);
                                break;
                            case AppConstants.CalcOperation.BENEFIT:
                                graphExt.updateBenefitEligibility(emp, true);
                                break;
                            case AppConstants.CalcOperation.RETIREMENT:
                                graphExt.updateRetirement(emp, true);
                                break;
                        }

                    }
                    catch (Exception ex)
                    {
                        PXProcessing.SetError(ex.Message);
                    }
                });

        }

The ASPX is very simple too:

<%@ Page Language="C#"  MasterPageFile="~/MasterPages/FormDetail.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="MH501000.aspx.cs" Inherits="Page_MH501000" Title="Untitled Page" %>

<%@ MasterType VirtualPath="~/MasterPages/FormDetail.master" %>

<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
	<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
        TypeName="PRImport.MHPRProcessBenefits"
        PrimaryView="Filter"
        >
		<CallbackCommands>
		</CallbackCommands>
	</px:PXDataSource>
</asp:Content>

	<asp:Content ID="Content2" ContentPlaceHolderID="phF" runat="server">
	<px:PXFormView ID="form" runat="server" Style="z-index: 100" Width="100%" DataMember="Filter">
		<Template>
			<px:PXLayoutRule runat="server" StartRow="True" LabelsWidth="XS" ControlSize="M" />
				<px:PXDropDown ID="edAction" runat="server" DataField="CalcType" CommitChanges="True" />
		</Template>
	</px:PXFormView>
</asp:Content>



	<asp:Content ID="Content3" ContentPlaceHolderID="phG" runat="server">
	<px:PXGrid ID="grid1" runat="server" Width="100%" AllowPaging="True" AdjustPageSize="Auto" SkinID="Inquire" DataSourceID="ds" ExportNotes="False" NoteIndicator="False" FilesIndicator="False">
		<Levels>
			<px:PXGridLevel DataMember="ActiveEmps">
				<RowTemplate>
					<px:PXSelector ID="edRefNbr" runat="server" DataField="RefNbr" AllowEdit="true" ></px:PXSelector>
				</RowTemplate>
				<Columns>
					<px:PXGridColumn DataField="Selected" Width="30px" TextAlign="Center" Type="CheckBox" AllowCheckAll="True" AllowSort="False" AllowMove="False" ></px:PXGridColumn>
					<px:PXGridColumn DataField="UsrInitMeasureStart" Width="90" ></px:PXGridColumn>
					<px:PXGridColumn DataField="UsrInitMeasureCalcd" Width="60" ></px:PXGridColumn>
					<px:PXGridColumn DataField="UsrHoursReqMet" Width="60" ></px:PXGridColumn>
					<px:PXGridColumn DataField="UsrCurECPStart" Width="90" ></px:PXGridColumn>
					<px:PXGridColumn DataField="AcctName" Width="220" ></px:PXGridColumn>
					<px:PXGridColumn DataField="AcctCD" Width="140" ></px:PXGridColumn></Columns>
			</px:PXGridLevel>
		</Levels>
		<AutoSize Container="Window" Enabled="True" MinHeight="300" />
	</px:PXGrid>
</asp:Content>

Screenshot of form in UI:

 

Best answer by markusray17

You want to set the process delegate(as well as the captions) in the graph constructor not in the row selected event but that isn’t what is causing your issue.

I suspect your code is being run synchronously because you are accessing the (this).Filter view. Any reference inside the delegate to the graph instance will cause the code to run synchronously which would prevent the dialog from showing.

You can lexically bind the Filter.Current.CalcType value to a variable in the surrounding closure which should fix the issue.

//Constructor
public MyGraph(){

            var filterCalcType = Filter.Current.CalcType;

            ActiveEmps.SetProcessCaption("Calculate");
            ActiveEmps.SetProcessAllCaption("Calculate All");
            ActiveEmps.SetProcessDelegate<PREmployeePayrollSettingsMaint>(
                delegate (PREmployeePayrollSettingsMaint graph, PREmployee emp)
                {
                    graph.Clear();
                    var graphExt = graph.GetExtension<PREmployeeMaintExtension>();

                    try
                    {
                        switch (filterCalcType)
                        {
                            case AppConstants.CalcOperation.ACA_INIT:
                                graphExt.updateInitialACA(emp, true);
                                break;
                            case AppConstants.CalcOperation.ACA_STANDARD:
                                graphExt.updateStandardACA(emp, true);
                                break;
                            case AppConstants.CalcOperation.BENEFIT:
                                graphExt.updateBenefitEligibility(emp, true);
                                break;
                            case AppConstants.CalcOperation.RETIREMENT:
                                graphExt.updateRetirement(emp, true);
                                break;
                        }

                    }
                    catch (Exception ex)
                    {
                        PXProcessing.SetError(ex.Message);
                    }
                });
}

 

View original
Did this topic help you find an answer to your question?

5 replies

Forum|alt.badge.img+5
  • Jr Varsity II
  • 237 replies
  • Answer
  • January 12, 2022

You want to set the process delegate(as well as the captions) in the graph constructor not in the row selected event but that isn’t what is causing your issue.

I suspect your code is being run synchronously because you are accessing the (this).Filter view. Any reference inside the delegate to the graph instance will cause the code to run synchronously which would prevent the dialog from showing.

You can lexically bind the Filter.Current.CalcType value to a variable in the surrounding closure which should fix the issue.

//Constructor
public MyGraph(){

            var filterCalcType = Filter.Current.CalcType;

            ActiveEmps.SetProcessCaption("Calculate");
            ActiveEmps.SetProcessAllCaption("Calculate All");
            ActiveEmps.SetProcessDelegate<PREmployeePayrollSettingsMaint>(
                delegate (PREmployeePayrollSettingsMaint graph, PREmployee emp)
                {
                    graph.Clear();
                    var graphExt = graph.GetExtension<PREmployeeMaintExtension>();

                    try
                    {
                        switch (filterCalcType)
                        {
                            case AppConstants.CalcOperation.ACA_INIT:
                                graphExt.updateInitialACA(emp, true);
                                break;
                            case AppConstants.CalcOperation.ACA_STANDARD:
                                graphExt.updateStandardACA(emp, true);
                                break;
                            case AppConstants.CalcOperation.BENEFIT:
                                graphExt.updateBenefitEligibility(emp, true);
                                break;
                            case AppConstants.CalcOperation.RETIREMENT:
                                graphExt.updateRetirement(emp, true);
                                break;
                        }

                    }
                    catch (Exception ex)
                    {
                        PXProcessing.SetError(ex.Message);
                    }
                });
}

 


Forum|alt.badge.img
  • Author
  • Freshman II
  • 13 replies
  • January 12, 2022

@markusray17  That little change with the Filter fixed it. Thanks so much! Don’t think I would have ever thought of that.


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3399 replies
  • January 12, 2022

Hi @KellyMarchewa, Yes, as suggested above, we need to have a code at the Constructor level but not the RowSelected event. Here is the code for your reference. 

May help you for your reference.

public class MHPRProcessBenefits : PXGraph<MHPRProcessBenefits>
{
    public PXCancel<ProcessBenefitFilter> Cancel;
    public PXFilter<ProcessBenefitFilter> Filter;

    [PXFilterable]
    public PXFilteredProcessing<PREmployee, ProcessBenefitFilter> ActiveEmps;
    public override bool IsDirty => false;


    protected IEnumerable<PREmployee> activeEmps()
    {
        var filter = Filter.Current;

        switch (filter?.CalcType)
        {
            case ACA_INIT:
                return SelectFrom<PREmployee>
                    .Where<PREmployee.vStatus.IsEqual<VendorStatus.active>.And<PREmployeeExtension.usrInitMeasureCalcd.IsEqual<False>>>.View.Select(this).FirstTableItems;
            case ACA_STANDARD:
            case BENEFIT:
                return SelectFrom<PREmployee>
                            .Where<PREmployee.vStatus.IsEqual<VendorStatus.active>>.View.Select(this).FirstTableItems;
            case RETIREMENT:
                return SelectFrom<PREmployee>
                       .Where<PREmployee.vStatus.IsEqual<VendorStatus.active>.And<BAccountRetirmentExtension.usrHoursReqMet.IsEqual<False>>>.View.Select(this).FirstTableItems;
            default:
                return new List<PREmployee>();

        }
    }

    #region Constructor

    public MHPRProcessBenefits()
    {
        ActiveEmps.SetProcessCaption("Calculate");
        ActiveEmps.SetProcessAllCaption("Calculate All");
        ActiveEmps currentFilter = this.Filter.Current;
        ActiveEmps.SetProcessDelegate(
            delegate (List<PREmployee> list)
            {
                ProcessRecords(list, currentFilter);
            });
    }
    #endregion



    public static void ProcessRecords(List<PREmployee> list, ProcessBenefitFilter currentFilter)
    {
        PREmployeePayrollSettingsMaint graph = PXGraph.CreateInstance<PREmployeePayrollSettingsMaint>();

        foreach (PREmployee emp in list)
        {
            graph.Clear();
            var graphExt = graph.GetExtension<PREmployeeMaintExtension>();

            try
            {
                switch (Filter.Current.CalcType)
                {
                    case AppConstants.CalcOperation.ACA_INIT:
                        graphExt.updateInitialACA(emp, true);
                        break;
                    case AppConstants.CalcOperation.ACA_STANDARD:
                        graphExt.updateStandardACA(emp, true);
                        break;
                    case AppConstants.CalcOperation.BENEFIT:
                        graphExt.updateBenefitEligibility(emp, true);
                        break;
                    case AppConstants.CalcOperation.RETIREMENT:
                        graphExt.updateRetirement(emp, true);
                        break;
                }

            }
            catch (Exception ex)
            {
                PXProcessing.SetError(ex.Message);
            }
        }
    }
}

 


Dmitrii Naumov
Acumatica Moderator
Forum|alt.badge.img+7
  • Acumatica Moderator
  • 629 replies
  • January 13, 2022

Also I'd like to add to the answer provided by markusray17. there is a visual studio extension called Acuminator that highlights that kind of mistakes.


Forum|alt.badge.img+5
  • Jr Varsity II
  • 237 replies
  • January 13, 2022

I'm not sure it highlights this specific scenario. I am using the beta visual studio 2022 version of Acuminator but it didn't trigger a warning for this issue when I replicated it.

I think because of the anonymous function it doesn't detect properly. It definitely does detect it when using an instance method on the graph though. 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings