Question

Stop save after RaiseExceptionHandling is used


Userlevel 4
Badge +1

Hello, 
I have created a custom grid which stores a list of warehouses. I have a requirement to perform a couple of checks. 
1. The warehouse in the list cannot be the same as the selected warehouse. 
2. A warehouse shouldn’t be entered into the list twice. 

I’ve added these checks onto the RowSelected event, everything appears to work fine, the red cross appears on the row with the problem and on the tab. I’ve used this code to raise the error:

e.Cache.RaiseExceptionHandling<PinnSitePriority.prioritySiteID>(e.Row, inSite.SiteCD, new PXSetPropertyException(errDuplicateWarehouse, PXErrorLevel.RowError));

When I click the Save button I see the following:

This is exactly what I want. 

However, if I click into another row and the editing icon appears and then I click on the Save button... 

 

Acumatica doesn’t display the message - it ignores the errors reported on the grid and Saves the data, the Save button become disabled. 

Can anyone explain what is happening? I had expected that saving would not be possible if errors had been raised in a cached object but this doesn’t seem to be the case. 

I cannot find much explaining error trapping and handling in the documentation - I’ve seen info about getting the errors to appear but not how to stop the Save button from ignoring the errors. I’ve also seen other threads which ask similar questions to this and one of them suggested adding code to the RowPersisting event. In my case I would like to use the RowSelected event to report the error and it would be a shame if the code had to be repeated in the RowPersisting event. I’ve also tried using RowSelecting and RowSelected to report errors but I still have the same issue when the Save button ignores the errors. 

Should Acumatica be ignoring the errors I’ve raised? Am I raising errors in the correct way, at the correct time? Does anyone know how I can work around this issue?

Thanks
Steve


12 replies

Badge +11

Try using PXErrorLevel.Error instead

Userlevel 4
Badge +1

@stephenward03 
After Cache.RaiseExceptionhandling code,
You can try below code to stop saving.

 string ermsg = “Duplicate Warehouse”;
                        PXException exception = new PXException(ermsg);
                        throw exception;
                    

Userlevel 4
Badge +1

Using PXErrorLevel.Error changed the location of the error cross but that’s all, I was still allowed to save the record.

 

Userlevel 4
Badge +1

@stephenward03 
After Cache.RaiseExceptionhandling code,
You can try below code to stop saving.

 string ermsg = “Duplicate Warehouse”;
                        PXException exception = new PXException(ermsg);
                        throw exception;
                    

I think this type of set up might work with an ‘ing’ event like RowUpdating. I don’t think it works with the RowSelected event. 

A cut down version of my code is below

protected void _(Events.RowSelected<PinnSitePriority> e)
{
if (e.Row == null) return;
//ensure the main warehouse isn't added to the priority list
if (((PinnSitePriority)e.Row).PrioritySiteID == ((PinnSitePriority)e.Row).Siteid)
{
string errorMainWarehouse = "You cannot add the main Warehouse ID to the Automated Warehouse Priority List";
INSite priorityWarehouse = INSite.PK.Find(Base, (((PinnSitePriority)e.Row).PrioritySiteID));
e.Cache.RaiseExceptionHandling<PinnSitePriority.prioritySiteID>(e.Row, priorityWarehouse.SiteCD, new PXSetPropertyException(errorMainWarehouse, PXErrorLevel.Error));
}
}

 

Badge +11

I don’t know functionally why this wouldn’t work, but I don’t believe that RowSelected is actually the place that something like this should go. I believe RowPersisting would be better suited for doing validation checks, and perhaps the root cause is that RowSelected is simply not equipped to work with this sort of thing.

I use e.Cache.DisplayFieldError all the time, which at its core is exactly what you’re using, and I’ve never had it not work.

Userlevel 4
Badge +1

The problem with RowPersisting is that it only happens after clicking on the save button. It would be best is I could show the user that there is a problem before the save button is clicked. 

Perhaps the only way is to call the validation code from 2 places - RowUpdating and RowPersisting. The RowUpdating could be used to highlight the problem before pressing save, and RowPersisting to stop the save button actually saving the data to the database. 

This does feel a bit like overkill though, and I’m sure there must be another way. 

For an area of development that is so important I’m surprised there isn’t more documentation available.

Thanks

Steve

Badge +11

I’m curious if there’s a reason you haven’t included your custom Site ID as a key field in your custom DAC. The benefit of this would be that you couldn’t enter duplicates.

And I think you theoretically could put a PXRestrictor on the Site ID selector to prevent using the currently selected warehouse.

Userlevel 4
Badge +1

I guess I could have included the siteid in the key fields and that would have meant duplicates wouldn’t be possible. 
I did consider whether it would be possible to use a PXRestrictor to remove the ‘main’ site from the list but I decided it would probably be easier to just add a bit of a error trapping. Perhaps I was wrong. 

Either way, I really need to get to grips with data validation and error handling. It will be something I’m sure I’m need over and over again in the future. 

Badge +11

Yeah, like I said, it’s always worked for me in the past. Just for curiosities' sake, you could try using RowPersisting and see if the error handling works like you expect. If it does, you know the RowUpdated is the problem and possibly can find a way around it. If not, maybe something else is at play. 

Userlevel 7
Badge +17

Hi @stephenward03  Here is the solution I can suggest.

  1. The warehouse in the list cannot be the same as the selected warehouse.
  •  Add a condition to the DAC selector field, to do not load the current Warehouse value in the selector, which can solve the problem instead of providing the validation
  1. A warehouse shouldn’t be entered into the list twice. 
  • For the Duplication check, you can utilize the PXCheckUnique attribute as a means to prevent the presence of duplicate values. This is very to simple to add at the DAC level.

For the above two solutions, you can handle in the DAC it self with a simple steps.

Here is the example for PXCheckUnique

 

public abstract class description: PX.Data.BQL.BqlString.Field<description> { } [PXDBString(200,IsUnicode = true)] [PXUIField(DisplayName = "Description")] [PXCheckUnique(typeof(CustomDAC.description))] [PXDefault] public virtual string Description { get; set; }

 

 

Hope this helps!

Userlevel 4
Badge +1

Thanks guys. Some good suggests over the course of this thread. 

Whilst the idea of using a condition on the DAC selector and the suggestion of using PXCheckUnique will work I’m still really keen to understand how to control validation and stop data from being committed to the database. I have used PXCheckUnique in this case (but that as introduced another issue which I’ll not worry about here).

So for error trapping in a more general case, I’m come to the following conclusions:

  1. You can use RaiseExceptionHandling and PXSetPropertyException in many events in order to highlight a row in a grid with an error or warning icon. But just marking a row in the cache isn’t enough to stop the data from being saved. Though this seems quite inconsistent, when clicking a Save button, sometimes you will see an error message and the data isn’t saved - but you can move to another row, then click the Save button and the data is saved fine.
    Therefore I’ve had to repeat my data validation in the RowValidating event. 
  1. In the RowValidating event. The documentation suggests that setting e.cancel=true will rollback the transaction and not save the data. In my testing this wasn’t the case and I’ve had to throw PXRowPersistingException instead.

By using the RaiseExceptionHandling and PXSetPropertyException on the RowUpdating event and using PXRowPersistingException on the RowValidating event I’ve got the system working the way I need it but I’m still not sure is the best way. 

Thanks for the assistance
Steve

Badge +11

 

The documentation suggests that setting e.cancel=true will rollback the transaction and not save the data. In my testing this wasn’t the case and I’ve had to throw PXRowPersistingException instead

I drank this cool-aid. It ruined my day.

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved