Constraints with Data.Get() and Data.Set()

I meant to make a post regarding this a short while ago, when I was trying to use this “new knowledge” regarding Data.Set() and Data.Get().

I concluded that Data.Set() and Data.Get() are local to the Rule that they are used in. While they can be set and read using Actions and set and read in executed scripts in the same Rule, they do not survive traversing other Rules.

That is, if you SET something in one Rule, and then execute another Rule (ie. Automation Command), that other Rule does not have access using GET. The variable is empty (or rather non-existent), unfortunately.

So no, you cannot effectively use them as Constraints on the Rule or Action level.

I agree. And SET/GET can do this, but only if the script is called or executed in the same Rule that SETs the variable. As soon as you leave the Rule, the value is gone.

@emre, any possibility you could “expand the scope” of Data.Set/Get so we could access variables across Rules?

Hmm I don’t remember what was the reason I’ve recommended using Data.Get() but don’t we use local program settings to share data across rules?

Hey @emre

We started using Data.Get() because it was needed both Scripts and Rules, typically create a variable in a Script Data.Set() and then use it in a Rule, Data.Get().

Hi @QMcKay

I actually do have my Data.Set() moving across Rules?

The issue that I find difficult is using either {:LocalSetting} or Data.Get(‘Variable’) as a trational variable whereas you can increment or assign a value (even Boolean) to control Workflow.

For example in RULE processing:
RULE (constraint)
Action 1
Action 2 Do only if constraint = 0
Action 3 Do only if constraint > 0

I am trying to use Action 2 to reset “Sukasem’s Loop” to perform a Loop inside a Loop…

The Trouble with Data.Get()'s is that you cannot increment like you can {:Variables) so it would be Store to Jscript Variable; Increment; then Data.Set() new value.

Ok, but sorry, you need to prove that to me.

I thought I discovered GOLD when experimenting with Data.Set/Get because it works in the Rule and in Script. But my experiments were contained to a single Rule.

Then I did some more trials, because what could be better than a variable that is accessible in Rules and in Script, other than Global Program Settings which are written to the DB? In-memory variables accessible and modifiable, globally - what could be better? Why even have Local Program Settings at all?

So try this:

  • Do a Data.Set in a Rule, within some action.
  • Now call ExecAMC action right after it, in that same Rule, but do not pass any data in the command value!
  • In the Rule for the AMC, throw up a message box containing output for Data.Get for the var you just set in the previous Rule.
  • Show me your results and complete setup if it works.

Maybe, it is just that the following does not work, which we need to work for it to be of value:

[=Data.Get('myvar')]

Anyway, let me know how it goes. I really want this feature as much as you.

OK Q - I will take the challenge!

But to fair, I do the Data.Set() in a Script called from a Application Started RULE.
The RULE then does some initialization and called a EXEC ACM RULE which does a Data.Get() to retrieve the Data. It still 2 different RULES right?

I been working on this Looper thing for 2 days now, very complex due these variables. Just realised that I was relying on a Constraint {:Variable} which I was changing in a Action and expected the processing of the RULE to deviate :scream:
Fell for the “old 3 card trick” …

I will finish this RULE and drop a GIF later. :grinning:

Yes we do. However, Local Program Settings are not accessible in JS. Only Global Settings are available (via a DB query). We are looking for a feature where in-memory (local) variables are accessible across Rules and Scripts, without having to store them in the DB. Data.Set/Get appears to provide this, however …

If you do a Data.Set('myvar') in an Action within a Rule, then within the same Rule, subsequently fire Execute Script Action, or {CALL:X}, then the script can read the variable using Data.Get('myvar') and even modify it using Data.Set('myvar'). Subsequent Actions, within the same Rule, can then also read that using Data.Get('myvar').

But…

If the Rule contains Actions which invoke another Rule (ie. Execute Automation Command, or a State Update), it would be good to be able to access ‘myvar’ in the Rule that handles that AMC or State Update. But alas, this does not appear to be the case. ‘myvar’ does not exist any longer in the AMC Rule, or the State Updated Rule.

I discovered this with the Bump Bar when I was trying to track Card Position, and storing values in the DB was not “fast enough” to allow for JS to read the Global Program Settings. So I thought I could use Data.Set/Get instead. But because I was traversing Rules, it fell apart when I finally realized that the next Rule in line could not read my variables using GET.

Your just gonna make me do a GIF aren’t you…
Images coming now.

NOTE EDIT:
The Execute Automation Command is calling the 2nd Rule.
Now expanded below:

The Script:

2nd Rule:

Result: :sunglasses:

Do I win the door prize? Or have I misunderstood things…

1 Like

I don’t know what to say.

I just tested this myself. And it works today …

RULE #1

RULE #2

Message from Rule 1 & 2

#:grin:

(not very often will you see that line lol)

Data.X helper basically used to alter rule data (parameters). The first time I implemented this feature I used it to trim trailing question marks from swipe data. Later we found different uses. However it does not completely replace local settings. It’s context is different. @QMcKay is right. It may not work for all cases.

I already demonstrated how to access settings from JS…

function readSetting(settingName)
{
   var response = gql.Exec('{findGlobalSetting(name:'+settingName+'){name,value}}');
   var result = JSON.parse(response);
   return result.data.findGlobalSetting.value;
}

You can find more info under Uses in JScript section of this post. I think findLocalSetting and updateLocalSetting functions will do the job.

https://forum.sambapos.com/t/graphql-api-implementation/10534/18

2 Likes

This link
https://forum.sambapos.com/t/graphql-api-implementation/10534/18
can i look

Dear Emre, please, please do not change a thing with the way Data.Get() and Data.Set() currently work (unless it is an addition) as they are magnificent little keys to unlocking SambaPOS Power!

I am happy to say I just finished a 3 day stint (2 days looking at a piece of paper with a flowchart), and 1 day mapping, testing and repeating about 200 iterations - and BAM, works seamlessly and transparently.

Do not worry I have always stated I rather stay in “Default” mode and keep the use of Script and Variables down to a minimum.

Yes you did!

@QMcKay check out the Rule and script below. I found the {CALL:x} constraints that actually RETURN a Data.Get() (see script) are evaluated dynamically. I don’t really understand how or what but it just does and its wonderful :joy:

RULE:

CALL SCRIPT:

I am putting here in the public domain to be enjoyed and put on the record that this functionality goes to the core of what I require to deliver SambaPOS to out Marketplace.

I will eventually look at GraphQL but any more information going into my very hurting brain which has reached overload for the last 6 months will be too much right now. :grinning:

What does the Rule do?
The Rule runs in a recursive loop “Sukasems Loop”, processing different transactions files, creating Multiple Entities & Accounts on the Fly, and then creating any Account Transaction Documents for Invoices and Receipts.

These transactions can be absorbed immediately effecting transparent integration if a SambaPOS instance is running OR picked up on an Instance Instantiation. All of this is done behind the seems without any User Input - yah.

Friday night 10.30pm and its that time :beer:

1 Like

What do you mean by this exactly? Are you saying that the Rule processor does not “short list” the Actions if they have a {CALL:X} in their Constraint?

Also curious to know why you are forking to a script in the first place? Why not just do this in a Constraint?

'[=Data.Get('HasDoneFile')]' == 'Yes'

Does that ^ not work? Maybe this would?

'[=Data.Get("HasDoneFile")]' == 'Yes'

Or this?

"[=Data.Get('HasDoneFile')]" == "Yes"

Maybe those types of operations don’t work as Constraints? Maybe that is why I was sure that Set/Get were not traversing Rules? I can’t remember now exactly, but I think I was trying to update a counter - that is, I was attempting to increment a variable.

It seems so.
I tested time and time again because I originally used an incremented variable {:countervariable} in the RULE to constraint Actions i.e. Don’t do this action if {:countervarible} > 0. After a few hours and lots of show messages I realised the best test was:

RULE
Action = Add 1 to {:countervariable}

Contraint = {:countervariable} > 0
Action = Show Message with value of {:countervariable} which was 0 :negative_squared_cross_mark:

I know you know this but many others do not. The thing is when I did:

Contraint = {:CALL:x} > 0
Action = Show Message with value of {:CALL:x} which was 1 :white_check_mark:
They were always in sync and the Action never triggered if the value was 0! Go figure…

Could not get that to work with any syntax - see title of this thread :slight_smile:

Constraints gets evaluated once before executing actions so a previous action won’t affect next action’s constraint. That won’t change.

There is no need to create a constraint for execute script as you can pass constraint parameters to script and make that constraint check inside script.

On next update you’ll be able to execute automation commands inside script. As we have a method to read / set local settings inside script there won’t be a need for constraint for execute automation command action too.

I hope that will help a bit.

4 Likes

Hi @emre

Sorry to bump an old post but what was your resolution here? Did you implement a method or was GraphQL your solution?

Graphql allowed execution of automation commands in script.

2 Likes

Can I see this post Please ?

https://forum.sambapos.com/t/graphql-api-implementation/10534/18

GQL variable may be changed check with http://localhost:9000 to confirm