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:
- Add button to the grid
- Inside of the button fullfil
- Persist
- Call to db with modifications
- Persist one more time
- 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<SOOrder> result = 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:
- on the first line of the code your adapter has information that Acumatica should go to <New> sales order
- Base.Actions.PressSave() generates sales order and persists it to Db, but doesn't notify adapter about this fact
- 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