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';
}
checkbox_fld = 'Y';
checkbox_fld = 'N';
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=Issues && SEVERITY_LEVEL=1 && STATUS=Pending && USER.{language}='fr')
{
ERROR: Statut invalide avec ce niveau de gravité
}
if (AREA=Issues && SEVERITY_LEVEL=1 && STATUS=Pending && USER.{language}='en')
{
ERROR: Invalid status with this severity level
}
if (AREA='Contracts' && CUST_LIST.{not null}) {
RELATIONSHIP_GROUP_PARENT = (customerLink).ID;
}
The important factor here is that the RELEASE_FOUND field is dependent upon its parent fied, PRODUCT_NAME. Therefore you must set both values at one time. The RELEASE_FIXED field has the same dependency.
PRODUCT_NAME = 'My Product';
RELEASE_FOUND = 2.3.4;
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.
It is not valid to add completely blank rows to a repeating row. You can, however, use an unused field that is not even on the layout in question. For example, to add three blank rows to a layout named MY_RR_LAYOUT, you could use this, utilizing the ALT_ID field which is not used on repeating rows and using a text field on the layout:
{ADD ROW: TO MY_RR_LAYOUT MY_TXT_FIELD = ALT_ID};
{ADD ROW: TO MY_RR_LAYOUT MY_TXT_FIELD = ALT_ID};
{ADD ROW: TO MY_RR_LAYOUT MY_TXT_FIELD = ALT_ID};
I want to add a user's personal signature to a letter or email I am going to send. How do I accomplish this?
Users may store their photograph and their signature within their account settings. A common requirement is to place the current user's signature within an HTML Area field, so it may be sent by email, or sent to a PDF to be used as an outgoing letter.This requires the following configuration:
Have an HTML Area field within an add or edit screen
Create an image field and place this on the same layout. This is used to hold the user's signature, so it remains as part of the record and part of the audit trail
Create a rule similar to:
<== load ==>
MY_IMAGE_FIELD = USER.{signature};
Within the HTML Area field have text such as $$MY_IMAGE_FIELD$$
. This provides the link from the field containing the signature into the body of the email or letter that you are composing.
Setting a date field such as DUE_DATE
will set the time of the entry to 12:00 AM unless the user explicitly sets the time. This means deadlines occur at the beginning rather than the end of the work day. How do I enforce setting the time to be at the end of the work day, rather than the beginning of the day?
Create a rule similar to this:
<== preupdate ==>
{
DUE_DATE = SYSDAY;
DUE_DATE += 0.75
}
Use the click of a menubar button placed on an add or edit screen to update values within the current issue. The following rule updates two field values when the button is clicked:
<== onchange ==>
if (MY_BUTTON.{changed}) {
PRODUCT_NAME = 'Tracker';
MODULE = 'API';
}
Place a button on a Related Issue Display which executes an action to update the issue on the row of the Related Issue Display. For example, you might want an action button that, when pressed, alters the STATUS of the issue to Closed. Let's say the menubar button is named MENU_UPDATE_STATUS
. The pressing of this button causes a business rule to trigger, thereby updating the issue:
window.doGridEditRIDRefresh('$$LAYOUT_ID$$');
When the user clicks the button, the action replaces $$LAYOUT_ID$$
with the name of the current layout, and the business rule picks up the change. Your business rule might then be:
<== preupdate ==>
if (PROJECT = 'Actions' && MENU_UPDATE_STATUS.{changed} {
STATUS 'Closed';
}
Given this update is on a single row of the Related Issue Display, you might want to communicate this action to the parent record via a subsequent rule:
<== postupdate ==>
## use the childActions link to let the parent know that at least one child exists
if (PROJECT='Actions' && (childActions
).ID.{is not null}) {
{UPDATE: childActions CHILDREN_EXIST
= 'YES'}
}
# Define the link for child actions to the parent record
<== link childActions
==> RG(RG_NAME = RELATED_RESULTS, RG_TYPE = PARENTS)