Today I want to speak with you about PXRestrictorAttribute usage and examples.
Lets start with PXSelector, as they are lies together. The PXSelectorAttribute attribute is required for selecting some dependent data. Also selector maintain consistency and checks that referred data exists and meets required conditions.
However from development stand point it has two major drawbacks:
- It gives the uninformative message <object_name> cannot be found in the system if a record with a given key does not meet the selector condition.
- When you change other fields of the object, the selector incorrectly gives the same message if the object referenced by the selector has changed and no longer meets the condition of the selector.
The PXRestrictorAttribute can be used to solve these problems.
The restrictor finds the selector on the same field, injecting into it an additional condition and the corresponding error message. The restrictor condition is appended to the selector condition via a Boolean AND and an appropriate error message is generated if the referenced object violates the restrictor constraint. Also, if the referenced object has changed and no longer meets the restrictor condition, no error messages are produced when you change any other fields of the referencing object.
Some important points about restrictor:
- PXRestrictorAttribute does not work alone – using it without the selector has no effect.
- The condition of selector applies the last, after all restrictor conditions
- Multiple restrictors can be used with one selector attribute. In this case, all additional restrictors conditions are applied randomly. Once any condition is violated, the appropriate error message is generated.
- The constructor of PXRestrictorAttribute takes three parameters:
- The restrictor’s additional condition. This BQL type must implement the IBqlWhere interface.
- The appropriate error message. The message can contain format elements (curly brackets) to show context. The message must be a string constant defined in a localizable static class (such as PX.Objects.GL.Messages).
- An array of field types. These fields must belong to the current object and must implement the IBqlField interface. The values of the fields will be used for error message formatting.
Also, there are several options that specify the restrictor behavior:
- There is a ReplaceInherited property indicates whether the current restrictor should override the inherited restrictors. If this property is set to true, then all inherited restrictors (placed on any aggregate attributes or base attribute) will be replaced.
- CacheGlobal supports global dictionary functionality in the same way as in PXSelectorAttribute. For details, see PXSelectorAttribute.CacheGlobal.
Big thanks for Acumatica dev team for provided example.
Have a nice development!