| 3.1. Specification Changes
Section 11.4.9 should be rewritten as follows:
This section describes the ValidationExpression table that is referenced in Section 11.3.4. There MUST be a corresponding table entry for each ValidationExpressionID referenced in the METADATA-UPDATE_TYPEs for a Resource.
The table contains expressions that are to be evaluated when a field value is entered by the user. Expressions in the list MUST be evaluated in the order in which they appear in the list. There are three types of validation expressions, each introduced by a reserved token preceding the expression:
Every validation expression has one of following types:
Table 3-1 Validation Expression Data Types
| CHAR | any string of ASCII characters |
| INT | any integer (tiny, small, int, long) |
| FLOAT | decimal number with fraction part |
| TIME | time, date, datetime |
| BOOLEAN | true or false |
Table 3-2 Validation Expression Types
| Keyword Type | Purpose |
| ACCEPT | Boolean | If the expression is true, the field value is considered accepted without further testing. Subsequent SET expressions MUST be executed. |
| REJECT | Boolean | If the expression is true, the field value is considered rejected without further testing. Subsequent SET expressions MUST NOT be evaluated. |
| SET | Assignment | The expression MUST begin with a field name and an equal sign (“=”). The following expression is evaluated and the result stored in the designated field. |
| VALIDATE | Assignment | If the expression is true, an error MAY be returned to check if the field is valid with the client. |
11.4.9.1 Validation Expression BNF
<Exp> ::= <NotExp>
<NotExp> ::= .NOT. <NotExp> | <OrExp>
<OrExp> ::= <AndExp> *( .OR. <AndExp> )
<AndExp> ::= <EqExp> *( .AND. <EqExp> )
<EqExp> ::= <CmpExp>
| <CmpExp> = <CmpExp>
| <CmpExp> != <CmpExp>
<CmpExp> ::= <CntExp>
| <CntExp> <= <CntExp>
| <CntExp> >= <CntExp>
| <CntExp> < <CntExp>
| <CntExp> > <CntExp>
<CntExp> ::= <SumExp> | <SumExp> .CONTAINS. <SumExp>
<SumExp> ::= <ProdExp> *( ( + | - ) <ProdExp> )
<ProdExp> ::= <AtomExp> *( ( * | / | .MOD. ) <AtomExp> )
<AtomExp> ::= ( <Exp> )
| <Value>
| <FuncExp>
<FuncExp> ::= <Func> ( <Param> *( , <Param> ) )
<Func ::= ALPHA *( ALPHANUM )
<Param> ::= <Exp>
<Value> ::= <SpecValue>
| <CharValue>
| <IntValue>
| <FloatValue>
| <Name>
<Name> ::= ALPHA *( ALPHANUM )
<SpecValue> := . ALPHA *( ALPHANUM ) .
<CharValue> ::= ‘ PLAINTEXT ‘ | “ PLAINTEXT “
<TimeValue> ::= # DATE #
<IntValue> ::= 0*1(+ | -) 1*(DIGITS)
<FloatValue> ::= <IntValue> . *(DIGIT)
The text in CharValue must not include the (single or double) quote used to delimit the value.
- A <Name> is a name of a field, and has a type of that field specified by the metadata.
- A <TimeValue> has TIME type.
- A <CharValue> has CHAR type.
- A <IntValue> has INT type.
- A <FloatValue> has FLOAT type.
- A <SpecValue> may be one of these values:
| .TRUE. | BOOLEAN |
| .FALSE. | BOOLEAN |
| .EMPTY. | CHAR |
| .TODAY. | TIME |
| .NOW. | TIME |
| .ENTRY. | type of the current field |
| .OLDVALUE. | type of the current field |
| .USERID. | CHAR |
| .USERCLASS. | CHAR |
| .USERLEVEL. | CHAR |
| .AGENTCODE. | CHAR |
| .BROKERCODE. | CHAR |
| .BROKERBRANCH. | CHAR |
A <FuncExp> is a function with parameters. Following functions are defined:
| Function | Parameter types | Type |
| BOOL | BOOLEAN or CHAR | BOOLEAN |
| CHAR | any | CHAR |
| TIME | TIME or CHAR | TIME |
| DATE | TIME or CHAR | TIME |
| INT | INT or FLOAT or BOOL or CHAR | INT |
| FLOAT | INT or FLOAT or BOOL or CHAR | FLOAT |
| SUBSTR | CHAR,INT,INT | CHAR |
| STRLEN | CHAR | INT |
| IIF | BOOLEAN,any,any | any |
The BOOL, CHAR, TIME, DATE, INT and FLOAT functions are used just to change a type of expression. The DATE and TIME functions are synonyms.
In conversion from BOOLEAN to INT or FLOAT, .TRUE. is converted to 1 and .FALSE. is converted to 0. Casting FLOAT to INTEGER discards the fractional part. When converting to and from CHAR, functions should support the usual formats.
The SUBSTR function returns a substring of its first parameter. Second parameter is a starting position of the substring, third parameter is the ending position of the substring. Positions are 1-based.
The STRLEN function returns the length if its parameter.
The IIF function return the value of its second parameter if the first parameter evaluates to true, or the value of its third parameter otherwise. Types of second and third parameter must be same, and it is the type of the result.
The operators may be applied on certain types, and the resulting type is defined by the following table:
| Operator | Left operand | Right operand | Result |
| /,*,.MOD. | INT | INT | INT |
| /,* | INT | FLOAT | FLOAT |
| /,* | FLOAT | INT | FLOAT |
| /,* | FLOAT | FLOAT | FLOAT |
| + | INT | INT | INT |
| + | INT | FLOAT | FLOAT |
| + | INT or FLOAT | TIME | TIME |
| + | FLAOT | INT | FLOAT |
| + | FLOAT | FLOAT | FLOAT |
| + | TIME | INT or FLOAT | TIME |
| + | CHAR | CHAR | CHAR |
| - | INT | INT | INT |
| - | INT | FLOAT | FLOAT |
| - | FLOAT | INT | FLOAT |
| - | FLOAT | FLOAT | FLOAT |
| - | TIME | INT or FLOAT | TIME |
| - | TIME | TIME | INT |
| .CONTAINS. | CHAR | CHAR | CHAR |
| <,>,<=,>=,=,!= | Any | Same as left | BOOLEAN |
| .AND.,.OR. | BOOLEAN | BOOLEAN | BOOLEAN |
| .NOT. | | BOOLEAN | BOOLEAN |
The using of strong types will help in optimizing and preprocessing the validation expressions, as well as it specifies more precisely how to calculate the expression values. However, it forced the use of conversion functions, so I added some basic other functions as well. More functions may be added to the specifications if the need shows.
A need to use numbers to represent time intervals arose from the ambiguity in expressions like:
“2002-10-30” - “2002-9-10” = “P1M20D”
“2002-10-30” - “2002-9-10” = “P50D”
“2002-10-30” + “P1M20D” = “2002-12-20”
“2002-10-30” + “P50D” = “2002-12-19”
The Validation Expression metadata starts with a <METADATA-VALIDATION_EXPRESSION> tag with Resource, Version and Date attributes. This is followed by a <COLUMNS> section, which contains the name of the fields as defined fields as defined in Table 11-19, followed by the <DATA> section, which contains the actual Validation Expressions. The Validation Expression metadata has the following format:
<METADATA-VALIDATION_EXPRESSION ° Resource="resource-id" °
Version="valid-expression-type-version" ° Date="valid-expression-type-date">
<COLUMNS>valid-expression-type-field
*(valid-expression-type-field)Æ</COLUMNS>
*(<DATA>valid-expression-type-data *(valid-expression-type-data) </DATA>)
</METADATA-VALIDATION_EXPRESSION> ø resource-id ::= 1*32ALPHANUM
This value MUST be a ResourceID found in the Resource metadata. It is the Resource to which the Objects belong.
valid-expression-version::=1*2DIGITS . 1*2DIGITS . 1*5DIGITS
This is the version number of the Validation Expression metadata. The convention used is a “<major>.<minor>.<release>” numbering scheme. Every time the Validation Expression metadata changes the version number should be increased.
valid-expression-date:=DATE
The latest change date of the ValidationExpression metadata.
valid-expression-field::=<Field Name from Table 11-20>
valid-expression-data::=<expression type keyword><valid validation expression>
An example Validation Expression section follows:
GetMetadata request:
Type:
METADATA-VALIDATION_EXPRESSION ID:
Property:
Compact reply:
<METADATA-VALIDATION_EXPRESSION Resource="PROPERTY" Version="1.00.00000" Date="Tuesday, 03-Oct-2000 17:10:53 GMT">
<COLUMNS> ValidationExpressionID ValidationExpressionType Value </COLUMNS>
<DATA> 10010 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10011 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10012 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10013 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10014 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10015 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10016 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.),
.FALSE.) </DATA>
<DATA> 10017 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10018 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.)
</DATA>
<DATA> 10019 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10020 SET ListPriceOrig = .ENTRY. </DATA>
<DATA> 10021 SET ListPriceOrig = IIF (.OLDVALUE. = .EMPTY.,.ENTRY.,ListPriceOrig) </DATA>
<DATA> 10022 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10023 SET ListStatus = 'ACT' </DATA>
<DATA> 10024 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'),
(.FALSE.)) </DATA>
<DATA> 10025 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10026 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)), .TODAY.,
WidthdrawnDate) </DATA>
<DATA> 10027 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'),
(.FALSE.)) </DATA>
<DATA> 10028 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10029 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10030 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10031 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10032 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10033 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10034 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10035 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10036 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10037 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10038 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10039 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10040 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10041 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10042 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10043 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10044 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.),
.FALSE.) </DATA>
<DATA> 10045 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.) </DATA>
<DATA> 10046 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10047 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10048 SET ListPriceOrig = .ENTRY. </DATA>
<DATA> 10049 SET ListPriceOrig = IIF (.OLDVALUE. = .EMPTY.,.ENTRY.,ListPriceOrig) </DATA>
<DATA> 10050 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10051 SET ListStatus = 'ACT' </DATA>
<DATA> 10052 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'),
(.FALSE.)) </DATA>
<DATA> 10053 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10054 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)), .TODAY.,
WidthdrawnDate) </DATA>
<DATA> 10055 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'),
(.FALSE.)) </DATA>
<DATA> 10056 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10057 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10058 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10059 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10060 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10061 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10062 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10063 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10064 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10065 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10066 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10067 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10068 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10069 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10070 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10071 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10072 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.), .FALSE.)
</DATA>
<DATA> 10073 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.) </DATA>
<DATA> 10074 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10075 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10076 SET ListPriceOrig = .ENTRY. </DATA>
<DATA> 10077 SET ListPriceOrig = IIF (.OLDVALUE. = .EMPTY.,.ENTRY.,ListPriceOrig) </DATA>
<DATA> 10078 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10079 SET ListStatus = 'ACT' </DATA>
<DATA> 10080 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'), (.FALSE.))
</DATA>
<DATA> 10081 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10082 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)), .TODAY., WidthdrawnDate)
</DATA>
<DATA> 10083 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'), (.FALSE.))
</DATA>
<DATA> 10084 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10085 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10086 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10087 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10088 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10089 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10090 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10091 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10092 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10093 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10094 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10095 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10096 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10097 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10098 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10099 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10100 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.), .FALSE.) </DATA>
<DATA> 10101 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.) </DATA>
<DATA> 10102 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10103 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10104 SET ListPriceOrig = .ENTRY. </DATA>
<DATA> 10105 SET ListPriceOrig = IIF (.OLDVALUE. = .EMPTY.,.ENTRY.,ListPriceOrig) </DATA>
<DATA> 10106 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10107 SET ListStatus = 'ACT' </DATA>
<DATA> 10108 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10109 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10110 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10111 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)),
.TODAY., WidthdrawnDate) </DATA>
<DATA> 10112 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10113 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10114 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10115 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10116 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10117 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10118 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10119 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10120 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10121 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10122 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10123 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10124 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10125 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10126 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10127 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10128 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.), .FALSE.) </DATA>
<DATA> 10129 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.) </DATA>
<DATA> 10130 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10131 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10132 SET ListPriceOrig = .ENTRY. </DATA>
<DATA> 10133 SET ListPriceOrig = IIF (.OLDVALUE. = .EMPTY.,.ENTRY.,ListPriceOrig) </DATA>
<DATA> 10134 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10135 SET ListStatus = 'ACT' </DATA>
<DATA> 10136 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10137 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10138 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)), .TODAY., WidthdrawnDate)
</DATA>
<DATA> 10139 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10140 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10141 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10142 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10143 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10144 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10145 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10146 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10147 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10148 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10149 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10150 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10151 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10152 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10153 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10154 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10155 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10156 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.), .FALSE.) </DATA>
<DATA> 10157 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10158 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.) </DATA>
<DATA> 10159 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10160 SET ListPriceOrig = .ENTRY. </DATA>
<DATA> 10161 SET ListPriceOrig = IIF (.OLDVALUE. = .EMPTY.,.ENTRY.,ListPriceOrig) </DATA>
<DATA> 10162 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10163 SET ListStatus = 'ACT' </DATA>
<DATA> 10164 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10165 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10166 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)),
.TODAY., WidthdrawnDate) </DATA>
<DATA> 10167 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10168 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10169 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10170 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10171 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10172 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10173 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10174 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10175 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10176 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10177 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10178 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10179 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10180 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10181 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10182 REJECT .ENTRY. < (ListDate + #P90D#) </DATA>
<DATA> 10183 REJECT ((ListStatus = 'EXP') .OR. (ListStatus = 'CLOSD') .OR. (ListStatus = 'WITH')) .AND.
(.USERCLASS. != 'STAFF') </DATA>
<DATA> 10184 REJECT IIF ((ListStatus='ACT') .AND. (.USERCLASS. != 'STAFF'), (.ENTRY. < .OLDVALUE.), .FALSE.) </DATA>
<DATA> 10185 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. < (.TODAY. - #P14D#), .FALSE.) </DATA>
<DATA> 10186 REJECT IIF (.USERCLASS. != 'STAFF', .ENTRY. > .TODAY., .FALSE.) </DATA>
<DATA> 10187 REJECT (.USERCLASS. != 'STAFF') </DATA>
<DATA> 10188 REJECT .USERCLASS. != 'STAFF' </DATA>
<DATA> 10189 SET ListStatus = 'ACT' </DATA>
<DATA> 10190 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'WITH')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10191 REJECT IIF((.ENTRY. = 'WITH'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10192 SET WithdrawnDate = IIF(((.ENTRY. = 'WITH') .AND. (WithdrawnDate = .EMPTY.)),
.TODAY., WidthdrawnDate) </DATA>
<DATA> 10193 REJECT IIF(((.ENTRY. = 'ACT') .AND. (.OLDVALUE. = 'EXP')), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10194 REJECT IIF((.ENTRY. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10195 REJECT IIF(((.ENTRY. = 'CONKO') .OR. (.ENTRY.='CONTG') .OR. (.ENTRY.='PEND').OR.(.ENTRY.='LPRCH')),
((Terms=.EMPTY.) .OR. (PendingDate=.EMPTY.).OR.(OfficeSell = .EMPTY.).OR.(AgentSell = .EMPTY.)
.OR.(ClosedDateProposed = .EMPTY.)), (.FALSE.)) </DATA>
<DATA> 10196 REJECT IIF((.OLDVALUE. = 'CLOSD'), (.USERCLASS. != 'STAFF'), (.FALSE.)) </DATA>
<DATA> 10197 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10198 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10199 REJECT (.ENTRY. < ListDate) </DATA>
<DATA> 10200 REJECT (.ENTRY. > (.TODAY. + #P1Y#)) </DATA>
<DATA> 10201 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10202 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
<DATA> 10203 REJECT (.USERCLASS. != 'STAFF') .AND. (.TODAY. > (ListDate + #P30D#)) </DATA>
</METADATA-VALIDATION_EXPRESSION>
|