How to control execution of Actions in a Rule? and what is the correct syntax for Constraints expressions?

Hi.
Firstly a little introduction …
Here in Thailand we use up to 5 languages in the restaurant: Thai, Khmer, Burmese, Lao and English.
SambaPOS is the only system I found which can handle our special needs and provide us the flexibility we need. Thanks to all the forum members who have shared such a lot of useful information, and especially Emre for making this amazing software!

right now am struggling to get some automation logic working.
I’m slowly getting familiar with using Automation Commands, Rules, and Actions and have set up an Accounting system which models our operation. It’s starting to come together … but have run into an awkward problem handling some custom accounting operations which we need to do after a new Work Period starts and before a Work Period is closed.

I am wanting to keep one set of accounts which tracks the cash going in and out of the cashier’s Cash Drawer during that staff’s work shift (i have called these “Cashier WP Accounts”) and another set of accounts which keep track of money kept in the Cashier’s safe (called “Cashier Safe Accounts”). The safe is where we keep spare change money, cashier Deposits together with their cash reports, and the Float remaining from the previous shift during the night.

After a Work Period is started in the morning, I transfer the amount in the Float (a Cashier Safe Account) to the Cashier Cashbox account using a “Create Account Transaction Document” with a Document Type called “Cashier WP Start”. This works fine using [:Balance] as the Default Amount field in the Document.

In the morning, the cashier presses a “Start Work Period” button which runs a rule called “WP Start (Cashier)” which contains a sequence of actions …

  1. “ac Start WP” to start the Work Period.
  2. “ac Create Start WP Txn using Float balance (Cashier)” moves the Float to the Cashbox
  3. Allow cashier to either confirm or back out of the operation causing the WP to close (not yet working properly)
  4. Open the Cashier Accounts

actually i had to remove step 4 because it seems that Actions don’t wait until data entry has been completed, so the Navigate Module action (which come later) switches to another screen thus preventing the user to enter any Amount.

The End WP workflow contains similar logic but in reverse order … the cashier makes a Deposit Transaction (which moves money from Cashbox to Deposit a/c) then the “Cashier End WP” Account Transaction Doc is created for moving the remaining balance back to Float (in Safe a/cs) then finally the WP is ended.

This example here is a simplification of the actual logic i wanted which allows the cashier to back out of the whole deal, and also needs to handle the case when the Owner opens his accounts screen to do Bank Deposits, pay Suppliers, pay Salaries or whatever and that operation could occur during an existing WP started by the cashier (an easy case) , or it might happen after the close of business for the day. In this case I want a WP to start automatically (if needed) when opening the Owner Accounts and end that WP again (but only if is was previously opened.)

I attempted to keep track of the WP state by using a ProgramSetting called WPState but found that when it was read back using {:WPState}, the value often didn’t reflect the most recently value written. So i decided to keep a local copy called WPStateLocal, and then i updated both copies whenever setting the state.

After getting very confused by rule behavior I added in a bunch of debugging Show messages to show both these state values to try and understand what was happening. I also inserted conditional messages to show cases when the 2 copies of my WPState were being read as different values.

For that i used an action Constraint such as {:WPState}<>{:WPStateLocal} and inside the Show message action i displayed the 2 values …

WPState={:WPState}\r
WPStateLocal={:WPStateLocal}

Then i was amazed to see the 2 values showing the same but inside an action having a Constraint expression which i thought would only be TRUE if the 2 values were different!
I also tried quoting the values in the Constraint expression like this…

‘{:WPState}’<>’{:WPStateLocal}’

but i continued to get erratic results. (So far this was using version 5.1.59)

I started to think there was some uncertainly about reading a SETTING and it had something to do with data caching. Could the evaluation of a Constraint expression, cause the data to change? something like a ‘heisenberg’ effect on the cached data? or is my syntax completely wrong or what?

I felt like start pulling my hair at this point … if i had any left that is …lol

After upgrading to 5160 I was excited to start using the new {GLOBAL SETTING:X} and {LOCAL SETTING:X} features but everything broke and I got even more confused.

I am struggling to implement some basic workflow using Rules and Actions.
Constraint expressions using numbers seems to work as expected, but when checking if 2 strings are equal there seems to be ambiguity relating to using quotes or not.

Which of the following Constraint expressions would be valid if i want an action to execute only if a work period is closed? …

  1. {:ISCURRENTWORKPERIODOPEN}==FALSE
  2. ‘{:ISCURRENTWORKPERIODOPEN}’==‘FALSE’
  3. !{:ISCURRENTWORKPERIODOPEN}
  4. {:ISCURRENTWORKPERIODOPEN}<>'TRUE
  5. ‘{:ISCURRENTWORKPERIODOPEN}’<>‘TRUE’

and what about …
[={:ISCURRENTWORKPERIODOPEN} && {LOCAL SETTING:X}]

There are many possibilities here but i didn’t yet see a clear definition of how these expressions are evaluated. I am using the quoted syntax like #2 and #5 but still get erratic results.

What am i doing wrong?
Thanks in advance!

Your best friend when learning what works and what doesnt is show message action. Use it in all of your automation to test and to see what is available.

Use simple rule and test constraints on show message action.

Something you should know about action conztraints is they evaluate at the same time not seqjentially.

Ps: sorry for spelling i am on my mobile.

1 Like

Hello @philbkk. In addition to Kendash’s recommendations simplifying your question under a different context will increase the chance of getting better help. When your case is really complex it is hard for us to understand as we’re not familiar to your workflow.

For example this one… Normally actions waits until data entry completes otherwise it will be impossible to use that feature for any case. Maybe you meant something else here. [quote=“philbkk, post:1, topic:11545”]
‘{:WPState}’<>‘{:WPStateLocal}’
[/quote]

All tags and variables always gets processes before executing actions. So you can’t update a setting and read updated value with a tag on next action in the context of a rule. Execute Automation Command action implemented to solve that issue. For example you can receive inputs from user, update settings and call execute automation command with a specific command name to trigger a second rule. In that rule you can handle “automation command executed” event and you can access updated settings & variables here. By chaining multiple rules you can implement any custom workflow that works conditionally depending on user inputs.

2 Likes

As an adon in reference to our list of example constraints at the end there;
< and > are numerical bases so would only work with constrint against a number.
Using ‘quotes’ is standard arround string based tags ‘{xxxx}’
Similarly when using numbers you woudl omit the quotes as these would cause the number to be treated as a string.
When using numbers your are best to wrap any {} tags in a TN() even if returning a number to ensure it is handeled as a number rather than a sting.

Ahh yes! Now some of the ‘strange’ behaviors start to make sense.
These specifics are important to know before designing and implementing workflows.
Is there a reference article which describes the rule evaluation logic and syntax for expressions?

list of Operators?
when to use quotes for strings?
can we use {:somestringvar}!=‘xx’
or we must use quotes on both sides of comparison to compare strings?

Regarding the waiting for input, there seems to be an issue.
If i have an Action which uses a [?Enter some data] and that is followed by an action which has Navigate Module, the prompt for input doesn’t show. But i will test again to be sure …

Thanks for your help!

Execute automation command with background=true will probably be a useful thing for you, it makes the command wait untill other actions have finnished.
I use allot for close ticket and logout to protect from user issues and that ticket is not closed and user logged out until any actions have been finished.

As for expressions there are many examples etc on the forum.
Many tags are listed in the printer template help (on the right where preview is if help not selected)
Many of these are only valid on certain rule events which often are logical, like you can’t use order based expression on ticket level event and ticket info tags need a ticket to be open/loaded.

Quotes would typically be on both sides where the values are sting/text where numbers must be haneled as such perticularly using sum type constraints like > and <, they are included in the string value. However for == it can likely be either with or without where they are identical. However as numerical values 0.00 would = 0 but as stings they obviously would not be the same.
As kendash said your best thing to learn is add an ask question or show message without constraint into your flow into which you copy and paste your constraint. It will show you the ‘rendered’ values each side of the == etc.
There is not full list of everything in one place I am aware of, but tbh a bit of trial and error will be more valuable to you to see and understand how all goes.

As for the flow…

->Events
→ rules based on events in rule order
—> action constraints evaluated at start of rule
—> actions happen in sequence but only based on constraints before starting, or action constraint cannot be based on a value changed by another action in the same rule

Execute automation command is good way to break down complex flows in to sections.
A value updated in one rule which also has an action to trigger a command of a second rule can be used in the constraints of the 2nd rule.

1 Like

Thanks for all of your suggestions, and sorry for taking so long to reply.

Regarding the Constraint expression issue, i had some other confusion regarding the use of quoted strings which is worth sharing:

I am using some generic “Update Program Setting” Actions which take parameters for Setting Name and Setting Value.
In the rules containing these actions, i had used quotation marks in the Setting Value i was storing.
Example: in the setting called WPActor i was storing the value as ‘Owner’ (including those single quotation marks)

Now i know that i shouldn’t do that and simply use the unquoted string value: Owner

If we use a quotes around a parameter value, those quotes are passed into the action (in this case stored into the Program Setting field. in my example here the database field contains ‘Owner’)
If using quoted strings this way, an expression containing a setting tag needs to use quotes such as:

‘{SETTING:MyStringValue}’==‘TestValue’

but if the string value was stored without the quotes, the expression:
{SETTING:MyStringSetting}==‘TestValue’ works fine.

in V5.1.60 is would be {GLOBAL SETTING:MyStringValue}==‘TestValue’ which also works fine.

It seems the quotes are also needed when testing boolean tag references with quoted 'TRUE" or ‘FALSE’

Example: ‘{ISCURRENTWORKPERIODOPEN}’==‘TRUE’

My conclusion here is that everything works fine when you are intimately familiar with the syntax, and that is ok for those experienced enough to know, but for newbies these things are likely to get confused, so clear documentation is needed.

@Emre, if possible in future versions I suggest making the expression parser more tolerant to avoid confusion for beginners and to make expressions as simple as possible. Example … when testing for true or false, perhaps it could match any case, TRUE, True, true could all represent the same thing, and a single tag value placed in a constraint could be implicitly interpreted as a boolean value and compared to ‘TRUE’ or ‘FALSE’ internally.

So in the above example the constraint expression:

‘{ISCURRENTWORKPERIODOPEN}’==‘TRUE’

could be simply replaced by

{ISCURRENTWORKPERIODOPEN}

I use this case only as an example, and is not particularly important to experienced users i’m sure, but the idea is to somehow allow people to be able to quickly implement work flows without having to learn such a strict syntax.

Timeout for today … I have some more suggestions coming regarding other aspects of SambaPOS, but it will take a while as i am also busy managing a restaurant.

Thanks again Emre for this awesome software! It’s exciting to envisage all the possibilities …

1 Like