if (ASSIGNED_TO={null} && USER.{is internal}) { ASSIGNED_TO = USER; }
if (AREA=Issues && PROJECT=Issues && SCREEN_NAME='ADD')
{FIELD_NAME=VALUE;}
if (AREA=Issues && PROJECT=Issues && SCREEN_NAME=EDIT)
{FIELD_NAME=VALUE;}
FIELD_NAME=VALUE;
Note that this construct does not work within an onchange rule
if (FIELD_NAME.{changed}) {
OTHER_FIELD = FIELD_NAME;
}
if (AREA="Contracts" && SCREEN_NAME='ADD') {
ASSIGNED_TO=USER;
}
if (AREA = 'Issues' && USER = ASSIGNED_TO) {
IS_MANAGER='Y';
}
if (AREA = 'Requests' && BUS_UNIT.{CHANGED TO:'ABC'}){
ASSIGNED_USRS =[PCOLLINS,MGREEN];
}
if (MY_LIST.{contains 'Yellow'}) { COLOR = 'Yellow';}
if (MY_LIST.{contains 'Yellow', 'Blue', 'Orange'}) {
COLOR = 'Yellow';
}
if (MY_LIST.{contains 'Yellow', 'Green'} && MY_LIST.{excludes 'Blue', 'Red', 'Purple'}) {
COLOR = 'Yellow';
}
if (AREA='Bugs' && STATUS.{changed_to:'Closed'} && USER_ROLE='Administrator')
{COMMENTS='OK!'};
if (STATUS.{changed}) {FIELD_X='Changed'};
if (AREA='Issues' && SCREEN_NAME='ADD'){
PHS_COMPANY_NAME = USER.{company name};
PHS_FIRST_NAME = USER.{first name};
PHS_LAST_NAME = USER.{last name};
PHS_JOB_TITLE = USER.{job title};
PHS_ADDRESS = USER.{address};
PHS_WORK_PHONE = USER.{work phone};
PHS_EMAIL = USER.{email};
PHS_USER_DEFINED_1 = USER.{user defined 1};
}
if (STATUS.{changed_to:Fixed} && STATUS.{changed_from:Open} && DATE_FIRST_FIXED.{is null} ) {
DATE_FIRST_FIXED = SYSDATE;
}
if (AREA='Bug' && UNIT_PRICE.{not null} && TAX.{not null}){
TOTAL_PRICE = UNIT_PRICE; TOTAL_PRICE += TAX;
}
if (AREA='Issues' && DISCOUNT.{not null} ){
DISC_PRICE = PRICE; DISC_PRICE -= DISCOUNT;
}
if (AREA='Customer Issues' && HOURS.{not null} ){
PRICE = AMOUNT; PRICE *= HOURS;
}
if (AREA='Issues' && HOURS_WORKED.{not null} ){
PRICE_PER_HOUR = TOTAL_COST;
PRICE_PER_HOUR /= HOURS_WORKED;
}
if (STATUS.{changed_to:Fixed} && STATUS.{changed_from:Open} && COMMENTS.{is null} )
{Error: Comments are required when an issue is marked fixed.};
if (AREA="Customers" && SCREEN_NAME='ADD') {
SHORT_DESCR="New Customer - ";
SHORT_DESCR&=CUST_NAME;
SHORT_DESCR&=" - ";
SHORT_DESCR&=CUST_LEGAL_INDENTITY;
}
if (AREA='Issues' && ACT_PERCENT_COMPLETE.{changed}) {
COMPLETE_AS_OF_DATE = {SYSDATE};
}
NEXT_MAINTENANCE_DATE = MAINTENANCE_COMPLETION_DATE;
NEXT_MAINTENANCE_DATE += MAINTENANCE_INTERVAL;
if (AREA=Reviews && ADD_EXPENSE_BTN.{changed})
{EXPENSE_ADD='Y';} }
if (AREA=Issues && SEVERITY_LEVEL=1 && STATUS=Pending)
{ ERROR: Invalid status with this severity level }
if (AREA='Contracts' && CUST_LIST.{not null}) {
RELATIONSHIP_GROUP_PARENT = (customerLink).ID;
}
For example, let's say that your STATUS and RELEASE_STATUS fields have four values, New, Open, Fixed and Closed. You want the STATUS field to show the value that corresponds to the earliest one in the list that is encountered across al the RELEASE_STATUS values. Thus, if there are three repeating rows, with values of Open, Fixed and Fixed, you want the STATUS field to indicate a "roll-up" value of Open. Likewise, if all three values of RELEASE_STATUS are Open, then you want the STATUS to also show Open. This is achieved with the following onchange rules:
# First, push our changed status to the STATUS field, so we can then trigger a reset
# based on all repeating row fields, not simply the one that changed
if (RELEASE_STATUS.{changed}) {
STATUS = RELEASE_STATUS;
}
# Now do the actual roll up by resetting the main status based on whether specific
# RELEASE_STATUS values exist. Note that the order of these rules is critical
if (RELEASE_STATUS.{changed} && RELEASE_STATUS = 'Closed') {
STATUS = 'Closed';
}
if (RELEASE_STATUS.{changed} && RELEASE_STATUS = 'Fixed') {
STATUS = 'Fixed';
}
if (RELEASE_STATUS.{changed} && RELEASE_STATUS = 'Open') {
STATUS = 'Open';
}
if (RELEASE_STATUS.{changed} && RELEASE_STATUS = 'New') {
STATUS = 'New';
}
# Define a link to the parent issue
<== link myParent ==>
RG(RG_NAME = relatedChildren, RG_TYPE = PARENTS)
# Now define a link for the child issues of the same parent - i.e. the SIBLINGS
<== link openChildren ==>
RG(RG_NAME = relatedChildren, RG_TYPE = SIBLINGS), STATUS != 'Closed'
<== postupdate ==>
# If we have a parent and all its children are Closed - i.e. there are no children that are not closed
if (STATUS.{changed to: 'Closed'} && (myParent).ID.{is not null} && (openChildren).ID.{is null}) {
{UPDATE: myParent STATUS = 'Closed'};
}
First define the object to be used to move the value from a text field to a list field:
<== object cust ==> AREA='Customers', LINK=CUST_LIST, TITLE=CUSTOMER, PRIVACY=false
Now, use the rule in a way that is similar to:
if (CUST_LIST.{changed} && AREA=’Issues’) {
CUST_CONTACT = (cust).CUST_CONTACT;
EMAIL_ADDRESS = (cust).EMAIL_ADDRESS;
}
if (AGENCY.{contains 'Federal'})
{GROUP = 'Fed';}
if (AREA=Issues && THEME={null})
{ DRAFT=Y }
if (AREA=Issues && THEME={not null})
{ DRAFT=N }
<== preupdate ==>
if (AREA=Issues && STATUS.{changed_to:Pending Approval}) {
{MAIL:'Issue Approval Request', APPROVER} };
<== mail ==>
if (AREA="Contracts" && STATUS.{changed to:Finished}) {
ROLE:MANAGER;
}
<== mail ==>
if (AREA='Trouble Report' && SCREEN_NAME=’ADD’) {
ROLE:CE;
ORIGINATOR;
JLACEY;
KMORRIS;
SCHRISTIANI;
PREEVES;
BKISER;
LMJAMES;
}
if (ADD_SERIAL_BTN.{changed} && UNIT_SERIAL.{not null}) {
{ ADD: AREA='Calibration',
PROJECT='Unit',
UNIT_SERIAL,
COMPONENT,
SITE,
FACILITY
};
}
if (CALIB_DATE.{changed} && CALIB_DATE > (unitLink).CALIB_DATE && AREA='Calibration') {
{UPDATE: unitLink, CALIB_DATE, UNIT_CAL_EXPIRES };
}
if (AREA='Helpdesk' && EMPLOYEE_NAME.{not null} && SCREEN_NAME='ADD' && STATUS='New') {
SHORT_DESCR = 'Install new computer for - ';
SHORT_DESCR &= EMPLOYEE_NAME;
{ADD: AREA,
PROJECT,
MY_PARENT_ID = ID,
ASSIGNED_TO = 'BSMITH',
STATUS = 'Open',
PRIORITY = 'P 3',
IT_SELECT_TABS = 'New Employee',
SHORT_DESCR,
IT_DATE_REQUESTED,
IT_APPROVED_BY,
ORIGINATOR,
EMPLOYEE_NAME,
EMPLOYEE_DEPT,
EMPLOYEE_START_DATE
};
}
This is achieved by altering the current role of the user, if that user is not the ASSIGNED_TO. Given that the Guest user is typically not allowed to update issues, then changing the role to that of the Guest or the role identified by the behavior setting LIMITED_USER_ROLE, will cause the record to appear in read-only mode if the user is not the ASSIGNED_TO.
if (USER != ASSIGNED_TO) USER_ROLE = Guest;
<= link rgOpen ==> RG(RG_NAME=MY_GROUP, RG_TYPE=CHILDREN), STATUS != Closed
if (STATUS.{changed to: Closed} && (rgOpen).ID.{is not null} )
{ERROR: Cannot set the status to Closed when there are open child issues.};
If you simply have two rules that state the following:
TOT_PERCENT_DEFECT = DEFECTS;
TOT_PERCENT_DEFECT /= SAMPLE_SIZE;
where the value for DEFECTS is 25, and the value for SAMPLE_SIZE is 100, the result returned is .2, not .25. The reason for this result is that rules try to make sense of operations, especially division, and therefore avoids results like 1.333333333336, and returns 1.3 instead. The rules engine looks at the number of decimal places (the precision) of each of the values, and then limits the number of decimal places returned to no more than the number of decimal places used to express the value, plus the minimum additional needed to get a non-zero value. Generally this works well, but as seen in this case there can be display problems, not the least of which is that there is no way to guarantee that either of the numbers has a certain number of decimal places.
To avoid this, write the rules as follows:
TOT_PERCENT_DEFECT = DEFECTS;
# multiply by 100 first to preserve accuracy
TOT_PERCENT_DEFECT *=100;
TOT_PERCENT_DEFECT /= SAMPLE_SIZE;
# explicitly add '.00' to preserve 2 digits of precision in the result
TOT_PERCENT_DEFECT /= 100.00;
By first multiplying by 100, you guarantee that there will be an integer value, and then by specifying the .00 when scaling it back causes the rules to keep at least two digits of precision
if (SHORT_DESCR.{like : 'RE: Extraview [*]*'} )
{ STATUS = "Response received";}
This rule processes the issue and looks to see if the incoming issue matches the string ‘RE: Extraview [*]*’ (excluding the outermost quotations. The * is a wildcard. If the SHORT_DESC field in the issue contains a value similar to ‘RE: Extraview [#223456] This is a report of a problem.’ then the STATUS of the issue is set to the value of ‘Response received’
if (CUST_LIST.{changed}) ASSIGNED_TO = CUST_LIST.{owner};
This onchange rule will look for the owner of the user defined field named CUST_LIST and set this user's ID into the issue as the Assigned To
First, create a user defined field in the data dictionary. This is used to hold the number of days different between a date (or day) field, and the current date. The field does not need to be on any layout, but it should have read and write permission. For this example, the field is DIFF_DAYS. The following preupdate rule will check that the date is not in the past.
if (PROJECT = 'Action' && DATE_FOLLOW_UP.{not null}) {
DIFF_DAYS = (DATE_FOLLOW_UP - SYSDAY);
}
if (PROJECT = 'Action' && DATE_FOLLOW_UP.{not null} && DIFF_DAYS < 0)
{ STOP: The Follow Up Date must be greater than todays date };
The following onchange rule will populate the first blank repeating row, and add two new repeating rows, when the user clicks the button named GENERATE_PARTS_LIST_BTN and the value of the field named ASSEMBLY has a value of Primary.
if (GENERATE_PARTS_LIST_BTN.{changed} && ASSEMBLY='Primary' ) {
PARTS='Part 1';
{ ADD ROW: PARTS='Part 2'};
{ ADD ROW: PARTS='Part 3'}; }
If you want to set additional values on the repeating rows, you can modify the above along these lines:
if (GENERATE_PARTS_LIST_BTN.{changed} && ASSEMBLY='Primary' ) {
PARTS='Part 1', RELEASE_STATUS='New';
{ ADD ROW: PARTS='Part 2', RELEASE_STATUS='New'};
{ ADD ROW: PARTS='Part 3', RELEASE_STATUS='New'};
}
The following load rule will work on an Add screen only, and will set values on the screen as it is loaded.
if (SCREEN_NAME = 'ADD' && MY_ADD_NAV_BUTTON= 'Add Task' ) {
PRIORITY = 'P 2';
CATEGORY = 'Task';
}
If the user chooses the Add Task navigation bar item, then the PRIORITY and CATEGORY fields are set as shown above.