Skip to main content
Solved

Customize process logic in Print/Email Orders screen


Forum|alt.badge.img+1

Hi all,

 

I need to customize the process logic for a selected action in the Print/Email Orders screen. Currently, the action defined in SOOrderEntry graph is executed separately for each selected order when the process button is clicked. However, I want to process all the selected orders at once according to some logics.

Can someone guide me on how to execute the action for all selected orders at once instead of processing them separately? Which method should I override to achieve this?

Any help or suggestions would be highly appreciated.

 

Thanks

Best answer by slesin

Hello @charithalakshan49!

Are you adding a new action to the screen? I’m asking because all current actions available on this screen already work in so-called Batch Mode. It means that all selected entities are combined into a list, that will be passed to the action of the processing graph (SOOrderEntry in this case) via the PXAdapter parameter.

Here is the configuration of the SOOrderEntry.printQuote action for example (see the PX.Objects.SO.Workflow.SalesOrder.ScreenConfiguration file):

All actions of this mass process screen are added via Workflow engine. So if you want to add a new action that would work in batch mode (i.e., consumes a whole list of orders at once, not one-by-one separately), you have to register that action in the similar way the SOOrderEntry.printQuote is registered.

So the right form for such a change is the following:

public class SOOrderMassProcessNewActions : PXGraphExtension<SOOrderEntry>
{
    [PXButton, PXUIField(DisplayName = "Do Something Important")]
    protected virtual IEnumerable myNewBatchAction(PXAdapter a)
    {
        // this form makes an action to work in both batch and non-batch mode,
        // so always try to write actions in this way,
        // i.e., avoid Current-based processing, instead gather records from adapter
        var ordersToProcess = a.Get<SOOrder>().ToArray();
        foreach (var order is orders)
        {
           // do something here for each order
        }
    }
    public PXAction<SOOrder> MyNewBatchAction;

    // always try to separate functional changes from WF changes,
    // because those two types of changes have different dependencies
    public class WorkflowChanges : PXGraphExtension<
        PX.Objects.SO.Workflow.SalesOrder.ScreenConfiguration,
        SOOrderEntry>
    {
        // this method is a special entry-point and should always be sealed,
        // because it cannot be overridden further in any reasonable way
        public sealed override void Configure(PXScreenConfiguration config) =>
            Configure(config.GetScreenConfigurationContext<SOOrderEntry, SOOrder>());

        // prefer to store WF configuration in a static scope,
        // in order to avoid accidental access to instance members of graph/extension,
        // they are not initialized yet, so it is not safe to access them.
        protected static void Configure(WorkflowContext<SOOrderEntry, SOOrder> context)
        {
            context.UpdateScreenConfigurationFor(screen => screen
                .WithActions(actions =>
                {
                    // this registers the action in WF engine,
                    // and configures it to be visible on processing screen
                    // and work in batch mode.
                    // You may need to make additional configuration for the action
					actions.Add<SOOrderMassProcessNewActions>(g => g.MyNewBatchAction, c => c
						.MassProcessingScreen<SOOrderProcess>()
						.InBatchMode());
                }));
        }
    }
}

Hope that was helpful.

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

3 replies

darylbowman
Captain II
Forum|alt.badge.img+13

From what I can tell, with the complexity of that processing screen and the amount of overriding that you’d have to do, you be better off starting from scratch and building a completely new processing screen to accomplish your needs.


slesin
Acumatica Employee
Forum|alt.badge.img
  • Acumatica Employee
  • 9 replies
  • Answer
  • April 27, 2023

Hello @charithalakshan49!

Are you adding a new action to the screen? I’m asking because all current actions available on this screen already work in so-called Batch Mode. It means that all selected entities are combined into a list, that will be passed to the action of the processing graph (SOOrderEntry in this case) via the PXAdapter parameter.

Here is the configuration of the SOOrderEntry.printQuote action for example (see the PX.Objects.SO.Workflow.SalesOrder.ScreenConfiguration file):

All actions of this mass process screen are added via Workflow engine. So if you want to add a new action that would work in batch mode (i.e., consumes a whole list of orders at once, not one-by-one separately), you have to register that action in the similar way the SOOrderEntry.printQuote is registered.

So the right form for such a change is the following:

public class SOOrderMassProcessNewActions : PXGraphExtension<SOOrderEntry>
{
    [PXButton, PXUIField(DisplayName = "Do Something Important")]
    protected virtual IEnumerable myNewBatchAction(PXAdapter a)
    {
        // this form makes an action to work in both batch and non-batch mode,
        // so always try to write actions in this way,
        // i.e., avoid Current-based processing, instead gather records from adapter
        var ordersToProcess = a.Get<SOOrder>().ToArray();
        foreach (var order is orders)
        {
           // do something here for each order
        }
    }
    public PXAction<SOOrder> MyNewBatchAction;

    // always try to separate functional changes from WF changes,
    // because those two types of changes have different dependencies
    public class WorkflowChanges : PXGraphExtension<
        PX.Objects.SO.Workflow.SalesOrder.ScreenConfiguration,
        SOOrderEntry>
    {
        // this method is a special entry-point and should always be sealed,
        // because it cannot be overridden further in any reasonable way
        public sealed override void Configure(PXScreenConfiguration config) =>
            Configure(config.GetScreenConfigurationContext<SOOrderEntry, SOOrder>());

        // prefer to store WF configuration in a static scope,
        // in order to avoid accidental access to instance members of graph/extension,
        // they are not initialized yet, so it is not safe to access them.
        protected static void Configure(WorkflowContext<SOOrderEntry, SOOrder> context)
        {
            context.UpdateScreenConfigurationFor(screen => screen
                .WithActions(actions =>
                {
                    // this registers the action in WF engine,
                    // and configures it to be visible on processing screen
                    // and work in batch mode.
                    // You may need to make additional configuration for the action
					actions.Add<SOOrderMassProcessNewActions>(g => g.MyNewBatchAction, c => c
						.MassProcessingScreen<SOOrderProcess>()
						.InBatchMode());
                }));
        }
    }
}

Hope that was helpful.


Forum|alt.badge.img+1

Thanks @darylbowman  @slesin  for your suggestions!


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