Error messages are always placed at the top of the rule syntax. As the RESO standard does not define an error message syntax, error messaging is embedded within the comments to avoid any possibility of it conflicting with the RESO define rule syntax. Comments within reso can be either an “End of line” comment, where “//” indicates the beginning of a comment, or an line internal bounded comment where “/” delineates the beginning of the comment and “/” delineates the end of the comment.
End of line comment
// This comment continues to the end of this line
Internal bounded comment
/* This is a bounded comment */
Error message difinition
An error message definition is bounded with square bracket characters, “[“ and “]” and must be is only item inside an “End of line comment”.
//[ErrMsg1^ERROR, the list price field is not a valid field for the commercial lease property type.|LogicBlk1^FALSE|LogicBlk2^TRUE|LogicBlk3^FALSE]
After the initial square bracket “[ “ delineater is a character token that uniquely identifies the user message for rule. A token must only be comprised of letters and digits and the first character of the token must be a letter.
Error message identification tokens are normally numbered and begin with “ErrMsg”, for example “ErrMsg1” as shown above.
The “^” symbol is used to separate the key-value pairs, such as the error message token and the error message text, for example “ErrMsg1^ERROR, the list price field is not a valid field for the commercial lease property type.”
To assess whether an error message should be triggered, logic blocks key - value pairs are defined following the error message text, as delineated by the pipe “|” character. The logic block key – value pairs consist of a logic block token and a boolean indicating the expected evaluation of the logic block. Within the rule syntax, the logic block token is used to identify which logic and the scope of the logic that encapsulates the logic block. For example, in our example rule below, there are ten logic blocks identified, the first three are:
Token: LogicBlk1, Logic Block: (/*[LogicBlk1]*/ .ENTRY. = .OLDVALUE.), Evaluation Trigger: FALSE
Token: LogicBlk2, Logic Block: (/*[LogicBlk2]*/ (.NOT. (.ENTRY. = .EMPTY.)) .AND. (.NOT. (.OLDVALUE. = .ENTRY.))), Evaluation Trigger: TRUE
Token: LogicBlk3, Logic Block: (/*[LogicBlk3]*/ .NOT. (PropertyType .IN. ('Clse'))), Evaluation Trigger: FALSE
If all logic blocks defined for a rule evaluate per the defined boolean value, the associated error message text is returned.
Rule Example
//[ErrMsg1^ERROR, the list price field is not a valid field for the commercial lease property type.|LogicBlk1^FALSE|LogicBlk2^TRUE|LogicBlk3^FALSE]
//[ErrMsg2^ERROR, user does not have the required authority to alter the list price field.|LogicBlk1^FALSE|LogicBlk2^TRUE|LogicBlk4^FALSE]
//[ErrMsg3^ERROR, a residential, non-timeshare property must have a close price between $8,888.00 and $1,000,000,000.00.|LogicBlk1^FALSE|LogicBlk2^TRUE|LogicBlk5^TRUE|LogicBlk6^FALSE]
//[ErrMsg4^ERROR, a residential, timeshare property must have a close price between $1.00 and $100,000,000.00.|LogicBlk1^FALSE|LogicBlk2^TRUE|LogicBlk7^TRUE|LogicBlk8^FALSE]
//[ErrMsg5^ERROR, a non-residential, property must have a close price between $1.00 and $100,000,000.00.|LogicBlk1^FALSE|LogicBlk2^TRUE|LogicBlk9^TRUE|LogicBlk10^FALSE]
// Grandfather rule... line below
(/*[LogicBlk1]*/.ENTRY. = .OLDVALUE.).OR.
// Start of rule... First verify that target field is not empty and has changed ...
IIF((/*[LogicBlk2]*/(.NOT.(.ENTRY. = .EMPTY.)).AND.(.NOT.(.OLDVALUE. = .ENTRY.))),
// (THEN)
// If the property type is not commercial lease.
(/*[LogicBlk3]*/.NOT.(PropertyType.IN.('Clse'))).AND.
// If the user has the proper authorization to alter this field.
(/*[LogicBlk4]*/.USERCLASS..IN.('AG','HA','DB','HB','OM','HM','OA','PA','BANGM','BANGN','BANGL','BANGP','BANGQ','BANGG','AS')).AND.
// If property type is Residential, with a property sub-type that is not time-share and the list price is between $8,888.00 and $1 billion.
(((/*[LogicBlk5]*/(PropertyType.IN.('Resi')).AND..NOT.(PropertySubType.IN.('TIME'))).AND.(/*[LogicBlk6]*/(.ENTRY. > 8888.0).AND.(.ENTRY. < 999999999.0))).OR.
// If property type is Residential, with a property sub-type that is time-share and the list price is between $1.00 and $100 million.
((/*[LogicBlk7]*/(PropertyType.IN.('Resi')).AND.(PropertySubType.IN.('TIME'))).AND.(/*[LogicBlk8]*/(.ENTRY. > 1.0).AND.(.ENTRY. < 99999999.0))).OR.
// If property type is not Residential and the list price is between $1.00 and $100 million.
((/*[LogicBlk9]*/.NOT.(PropertyType.IN.('Resi'))).AND.(/*[LogicBlk10]*/(.ENTRY. > 1.0).AND.(.ENTRY. < 99999999.0)))),
// (ELSE)
// Set to true if target field is empty, otherwise false
.ENTRY. = .EMPTY.)