When you write rules in AMODIT you need to be careful when using dates. AMODIT supports multiple languages and it influences how dates are shown and interpreted. In US English date format is mm/dd/yyyy but for example in Polish it is yyyy-mm-dd. Therefore it is risky to write:
[DateTo]>="5/2/2014"
It is better to write:
[DateTo]>=DateTime(2014,5,2)
This way you can avoid problems when user switches to another language.
Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts
Wednesday, November 19, 2014
Tuesday, April 8, 2014
AddUserToRole - new function
New function have been added to help control permissions more precisely. This function can change user's role. Therefore now you can use rules to give or reject permissions. For example if you want to take away someone's permissions you can add user to role "forbidden".
- cc - keep informed by email + read-only rights
- contributor - keep informed by email + read-write rights
- reader - read-only rights, without notifications
- forbidden - no access
Note: After you change users role it is stored in database.
Thursday, October 10, 2013
New function: FillFieldsFromString
This function is very useful when you want to store many parts of information ia a string and then save it to proper fields. It makes it easy to have tricky effect. Lets say you have a list of customers. Every customer is described with fields like "name","street","city" and "numer of employees". So you can set it up in AMODIT as an external dictionary. But dictionaries have just two fields; "name" and "description". But you can store "street","city" and "numer of employees" in dictionatry item's "description" using separator, f.e. "Hollywood Blvd|Los Angeles|3500". Using new function your can easily read such a string and save pieces of information into proper fields.
Another example is a scenario when you have your customers in external database. You want to query it for additional data every time user types-in customer number and store it in proper fields on a form. You can do it with an example code below:
cs="DSN=BAZA;UID=user;PWD=pa$$";
sql="select SYS_DAO.f_get_Customer([CUST_ID]) from DUAL";
res=ExecuteSQL(cs,sql);
FillFieldsFromString(res,"##","Client name","Client name","Tax number","Registry number","Client address"," Client address "," Client address "," Client address ");
This rule retrieve customer data from database in the form of string with values separated by ## string. Ex:
ASTRAFOX##sp. z o.o.##5252171560##13928533##UL. TABOROWA##8##02-699##WARSZAWA
FillFieldsFromString function splits retrieved string and puts values into given fields. You can add as many fields names as you wish (input string can contain any number of values separated by given separator). If you want to omit specified position you can pass empty field name "". If one field is specified more than once, then values from specific positions are concatenated into this field.
Another example is a scenario when you have your customers in external database. You want to query it for additional data every time user types-in customer number and store it in proper fields on a form. You can do it with an example code below:
cs="DSN=BAZA;UID=user;PWD=pa$$";
sql="select SYS_DAO.f_get_Customer([CUST_ID]) from DUAL";
res=ExecuteSQL(cs,sql);
FillFieldsFromString(res,"##","Client name","Client name","Tax number","Registry number","Client address"," Client address "," Client address "," Client address ");
This rule retrieve customer data from database in the form of string with values separated by ## string. Ex:
ASTRAFOX##sp. z o.o.##5252171560##13928533##UL. TABOROWA##8##02-699##WARSZAWA
FillFieldsFromString function splits retrieved string and puts values into given fields. You can add as many fields names as you wish (input string can contain any number of values separated by given separator). If you want to omit specified position you can pass empty field name "". If one field is specified more than once, then values from specific positions are concatenated into this field.
Wednesday, August 14, 2013
Formatting rules
In new version there is a new buton in rules editing window. It is simply called "Format" and clicking it results in "nice" reformatting of a rule. See example below:
And after clicking the button rule gets reformatted:
It is especially visible in part with {}.
Simple and useful :)
And after clicking the button rule gets reformatted:
It is especially visible in part with {}.
Simple and useful :)
AddTableRow & RemoveTableRow
We have added 2 new functions to use in rules:
AddTableRow("table")
Adds row to a given table. Returns index of added row (index can be used in Set function to fill data)
Function arguments:
- table - names of table field.
RemoveTableRow("table",(first|last|row number))
Remove given row fromo a given table.
Function arguments:
- table - names of table field.
- (first|last|row number) - which row.
Saturday, May 11, 2013
ShowSection() and HideSection()
Two new functions have been introduced to rules engine. They allow hiding and showing sections of a web form depending on certain conditions, f.e. value of other fields of a form and stage of a process.
So now there is a full set of such functions:
ShowSection(sectionName)
HideSection(sectionName)
ShowField(fieldName)
HideField(fieldName)
So now there is a full set of such functions:
ShowSection(sectionName)
HideSection(sectionName)
ShowField(fieldName)
HideField(fieldName)
Extended "Get" function
Recently we have introduced new feature which is "Reference" field type. So now one case can reference another case. We think it can be useful to get some data from "referenced" case. Therefore "Get" function was extended to support it. Full desctiption of the function is shown below:
Get("table (>table>table...) | reference field","field title","(first|last|row number)")
Returns value of the given field from given row (by default first) of given table or from the case referenced in given field.
Function arguments:
- "table (>table>table...)" - names of table fields. You can specify nested tables by separating them by ">"
- "reference field" - name of the field with reference type
- "field title" - name of the field from table or from referenced case
- "(first|last|row number)" - (optional) from which row you want to get value. By default system return value from first row. For reference field this parameter is ignored.
Example 1:
Get("Positions","amount");
Positions is the name of table field.
Returns value of amount field from first row of positions table
Example 2:
Get("People","Name",3);
People is the name of table field.
Returns value of Name field from third row of People table. If there are less than 3 rows in this table, system will return value from last row.
You can use CountRows() function to determine how many rows are in this table.
Example 3:
Get("Invoices>Positions","ammount","last");
Invoices and Positions are table fields. Positions table is definied inside Invoices table.
Returns value of ammount field from last row of positions table definied inside invoices table (if there are many invoice rows, system will returns value from last invoice row).
Example 4:
Get("Customer","Address");
Customer is the name of reference field.
Returns value of Address field from case selected in Customer field.
Thursday, April 4, 2013
AMODIT 1.9
There is new version of AMODIT available. There is one important new feature in this version: modification locking. This feature forbids editing same case by two persons simultaneously. It can be helpful if there are many users working on group of cases. When this feature is turned on, then opening a case by one user for editing will lock a case, so other users will be able to open this case just in read-only mode. They will be able to see who is editing the case at the moment.
Case will be unlocked when user exits from case. Additionally lock will expire after 30 minutes (or other time set in settings).
To turn this feature on you need to go to "System settings":
There is also one minor new feature in this version of AMODIT. It is ConditionalGet function. It gets values from one column of a table from selected rows. It has following syntax:
ConditionalGet ( "table (>table>table...)", "Field/column name", "Conditional field name", "Operator =, ==, !=, <>, <, >, <=, >=", "Conditional value/field name", "Separator" )
For example...
Case will be unlocked when user exits from case. Additionally lock will expire after 30 minutes (or other time set in settings).
To turn this feature on you need to go to "System settings":
There is also one minor new feature in this version of AMODIT. It is ConditionalGet function. It gets values from one column of a table from selected rows. It has following syntax:
ConditionalGet ( "table (>table>table...)", "Field/column name", "Conditional field name", "Operator =, ==, !=, <>, <, >, <=, >=", "Conditional value/field name", "Separator" )
For example...
ConditionalGet(„People”,”email”,”city”,”==”,”London”,”;„);
... will get values from column "email" from table "People" from rows where "city" is equal to "London" and will separate these values with semicolon.
Wednesday, October 24, 2012
Programming trick
Here is some example how you can use sofisticated programming features of AMODIT.
Let's say you want users to choose option from dropdown list and then set some parameters value depending on that choise. Of course you can use bunch of "if-then" statements to achieve it. But it will make code of the rule quite long and not so easy to maintain and to make changes.
Smarter and more tricky way is to put different value of parameters in descriptions of dictionary items. Look at picture below. It is in Polish but focus on syntax of descriptions (column "Opis").
OK, but how to extract value of parameters from it. You can do it using proper Regular Expression:
desc=GetDictionaryDescription("DictionaryName");
parameter=RegExp(desc,"param1=(?<param1>[0-9,. ]*)","param1");
It looks pretty complex but saves a lot of code and makes changes easy...
Let's say you want users to choose option from dropdown list and then set some parameters value depending on that choise. Of course you can use bunch of "if-then" statements to achieve it. But it will make code of the rule quite long and not so easy to maintain and to make changes.
Smarter and more tricky way is to put different value of parameters in descriptions of dictionary items. Look at picture below. It is in Polish but focus on syntax of descriptions (column "Opis").
OK, but how to extract value of parameters from it. You can do it using proper Regular Expression:
desc=GetDictionaryDescription("DictionaryName");
parameter=RegExp(desc,"param1=(?<param1>[0-9,. ]*)","param1");
It looks pretty complex but saves a lot of code and makes changes easy...
Thursday, August 9, 2012
Sending emails from case and receiving responses
AMODIT gives you ability to send email from case using rules.
There are two functions which allow it.
SendMessage ( "userLogin" | "login@address.com", "Subject", "Text" [, "from@address.com"] )
,which sends simple email and
SendCasePrintMail ( "userLogin" | "login@address.com", "Subject", "Text", headers?, signatures?, attachments?, history? [, "Chosen Section", "from@address.com"] )
which can send email with form, attachments, signatures and history.
Important thing is that you can reply to such an email and AMODIT will receive it and store as a new comment into proper case. To achieve it AMODIT stores case ID in email header.
There is one more interesting thing. You can check who have sent the response. There are special fields that can be read in rules:
There are two functions which allow it.
SendMessage ( "userLogin" | "login@address.com", "Subject", "Text" [, "from@address.com"] )
,which sends simple email and
SendCasePrintMail ( "userLogin" | "login@address.com", "Subject", "Text", headers?, signatures?, attachments?, history? [, "Chosen Section", "from@address.com"] )
which can send email with form, attachments, signatures and history.
Important thing is that you can reply to such an email and AMODIT will receive it and store as a new comment into proper case. To achieve it AMODIT stores case ID in email header.
There is one more interesting thing. You can check who have sent the response. There are special fields that can be read in rules:
- [CaseLastMailFrom] - sender of a last email (full name and address, like John Smith <john.smith@abc.com>)
- [CaseLastMailFromAddress] - sender of a last email (address only, like john.smith@abc.com )
- [LastMailFromTitle] - title of last email response received
All these features give you possibility to support sending and receiving emails inside AMODIT system and associate them with cases.
Monday, July 9, 2012
Signing, forwarding, form validating etc.
There are some small changes we have introduced in AMODIT 1.6.8 (which will be perhaps 1.7 stable version) in area of signing and forwarding.
The point is you sometimes want to make some manual rules to accept or reject using just one click. Rejecting is simple but when you want to accept from rule there are several options. You may want to sign one field on a form and then change stage of case. Problem is that you may want to have some required fields.
So if you put simply:
SignField("FieldName","Some comment");
ForwardCase("Someone","New stage");
If there are some required fields empty then you will get signature but forwaring will fail (and show proper explanation to a user). So this is not something you would like.
So there are two new changes:
1. Function IsFormValid() which returns if all required fields are filled-in. So you can write:
if (IsFormValid()) { SignField("FieldName","Some comment"); }
2. You can choose to define rules by just clicking checkbox "Sign case after successful rule evaluation" and choose a field (till now it was possible to sign whole case only).
Tuesday, June 19, 2012
Error tolerant programming
One of principles of AMODIT is to make it as easy as possible. You can start using workflow in a few minutes and end users can propose new procedure giving it just a name and names of possible stages.
However, later some procedures get more mature and stable and we want to add some automation. This is why AMODIT is equipped with rules engine and special scripting language. Syntax is similar to C#, but is simplified. For example there are no loops, not to let user a chance to make infinite loop.
For those who are familiar with C# it is known that you have to put semicolon ";" after every statement.
For example:
a = a + 1;
b = a * 2;
But we assume that AMODIT users don't have to be experienced programmers and they can forget about semicolons. So compiler is trying to guess if there should be a semicolor and put it there itself. Thus previous example can be simply writtten as:
a = a + 1
b = a * 2
Another thing that is made simple is referring to form fields. Generally if you want to refer to a field you use its name in square brackets:
From syntax point of view it is error. But it is common error and we decided to make compiler smarter.
So now you can use all combinations:
Just the first one is really valid, but all others are tollerated because compiler can clearly recognize user's intention. And this is what I call "error tolerant programming"!
However, later some procedures get more mature and stable and we want to add some automation. This is why AMODIT is equipped with rules engine and special scripting language. Syntax is similar to C#, but is simplified. For example there are no loops, not to let user a chance to make infinite loop.
For those who are familiar with C# it is known that you have to put semicolon ";" after every statement.
For example:
a = a + 1;
b = a * 2;
But we assume that AMODIT users don't have to be experienced programmers and they can forget about semicolons. So compiler is trying to guess if there should be a semicolor and put it there itself. Thus previous example can be simply writtten as:
a = a + 1
b = a * 2
[field1] = [fields2] + 1;
However, there are some functions which perform special actions with fields. For example SignField(field,comment) function puts a signature into a sign field. First parameter is a name of a field (not its value) so you have to put is as a string:
SignField("field1","my comment");
But users very often make mistakes writing:
SignField([field1],"my comment")
or
SignField("[field1]","my comment")
From syntax point of view it is error. But it is common error and we decided to make compiler smarter.
So now you can use all combinations:
- SignField("field1","my comment");
- SignField([field1],"my comment")
- SignField("[field1]","my comment")
Just the first one is really valid, but all others are tollerated because compiler can clearly recognize user's intention. And this is what I call "error tolerant programming"!
Subscribe to:
Posts (Atom)