How To Avoid Navigation Away From Created Item After Calling Presssave Or Persist Action

 

Hello everybody,

today I want to tell you a story, that swallowed quite big amount of time of whole team.

Recently we've got seemingly easy to fulfil requirement: 

  1. Add button to the grid
  2. Inside of the button fullfil 
    1. Persist
    2. Call to db with modifications
    3. Persist one more time
  3. Leave the page opened on created item in UI

Initially our code looked like this:

public PXAction<SOOrder> SomeAction;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Some Action", Visible = true)]
protected virtual IEnumerable someAction(PXAdapter adapter)
{
    Base.Actions.PressSave();
    //API call
    Base.Actions.PressSave();
    return adapter.Get();
}

I could say that everything worked perfectly except one tiny detail: after clicking of the button page was navigated away to creation of new Sales order. After plenty of research inside of Acumatica source code we have found this option:

public PXAction<SOOrder> SomeAction;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Some Action", Visible = true)]
protected virtual IEnumerable someAction(PXAdapter adapter)
{
    Base.Actions.PressSave();
    List<SOOrderresult = new List<SOOrder>();
    //API Call
    result.Add(Base.CurrentDocument.Current);
    return result;
}

Another way of dealing with this bug is this:

public PXAction<SOOrder> SomeAction1;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Some Action", Visible = true)]
protected virtual IEnumerable btnCreatingNew(PXAdapter adapter)
{
    Base.Actions.PressSave();
    //some other code
    adapter.Searches[adapter.Searches.Length - 1] = Base.CurrentDocument.Current.RefNbr;
    return adapter.Get();
}

Summary

Reason of such behavior is fact that Acumatica uses value returned from action in order to know which order to open. Then happens this:

  1. on the first line of the code your adapter has information that Acumatica should go to <New> sales order
  2. Base.Actions.PressSave() generates sales order and persists it to Db, but doesn't notify adapter about this fact
  3. When adapter.Get is executed, Acumatica reads from it order which should be opened, finds there <New> and navigates away from created SO

In order to deal with you can choose option 1, or option 2. Option 1 I've discovered in Acumatica source code, and option 2 is mentioned at stackoverflow by Ruslan

 

Comments are closed