JScript Helpers and Functions

Compilation of the helpers that are available in JScript and [=expressions].

Background

The script engine currently implemented in SambaPOS 5 is actually Microsoft JScript (similar to JavaScript) which is ECMAScript 3 (ES3 (Dec 1999)) compatible. As such, some functionality that you might find on the internet does not apply, such as new functionality added in ES5 (Dec 2009), ES6 (2015), or ES7 (2016).

More information:


https://blogs.msdn.microsoft.com/jscript/2007/10/29/ecmascript-3-and-beyond/


Enhancements

The script engine in SambaPOS 5, while being ES3-based, has been enhanced to contain many helper Methods, so that we can develop more advanced scripts. This document serves to expose these hidden methods with descriptions and usage examples.


Helper.X

Helper.Format()

Formats output. Same as F().

Syntax:

Helper.Format(<string>[,format])

Examples:

Helper.Format('1234'); // 1234.00
Helper.Format('1234','{0,2}'); // pad value Right with 2 spaces
Helper.Format('1234','{0,-2}'); // pad value Left with 2 spaces
Helper.Format('1234','{0,2:0.00}'); // pad value Right with 2 spaces, and maintain 2 decimals

Reference:
http://www.csharp-examples.net/string-format-double/

Helper.GetUniqueString()

Generates a “unique” string using the current Date and Time in the format of yyyyMMddHHmmssfff, where:

yyyy = 4-digit Year
MM   = 2-digit Month (01-12)
dd   = 2-digit Date (01-31)
HH   = 2-digit Hour (24 hour format) (00-23)
mm   = 2-digit Minute (00-59)
ss   = 2-digit Second (00-59)
fff  = 3-digit MilliSecond (000-999)

Syntax:

Helper.GetUniqueString(); // generates a string like 20160417145248261
//                                                   yyyyMMddHHmmssfff

Helper.ToNumber()

Converts a String to a Number. Same as TN(). Returns 0 if the string contains non-numeric or blank/empty content.

Syntax:

Helper.ToNumber(<string>)

Examples:

Helper.ToNumber('1,234.50'); // 1234.5

sql.X

sql.Query()

Provides a fluent interface to construct date ranged SQL queries easily.

Syntax:

sql.Query(handlerOrQuery).[ByWorkPeriod].[Delimit(',')].Range.[First|All]

ByWorkPeriod
Using optional ByWorkPeriod converts date ranges to work period date ranges. For example ByWorkPeriod.ThisWeek aligns ThisWeek range to work period start, end times.

Delimit(’,’)
Using delimit will configure a delimiter for multi column queries. Optional.

Range
Can be Today,Yesterday,ThisMonth,PreviousMonth,ThisWeek,PreviousWeek.

Also Range(dateRange) can be used to configure custom ranges. For example

sql.Query('@@TicketCount').Range(dt.Day(-2)).First;

First | All | Join()
Method chains can end with First or All.
First returns first row.
All returns all rows as a string array.
Columns are always merged to a single string with delimiter.
Join(<delimiter>) joins All values to a delimited string using specified delimiter (comma by default).

sql.Exec()

Syntax:

sql.Exec(handlerOrScript,dateRange,[delimiter(',')])

Returns a string array (string[]). You can enter a script handler or SQL Query as handlerOrScript parameter. dateRange used to fill {Start} and {End} parameters of script. Delimiter() is used to convert multiple columns to a single string value. Use indexer if query returns multiple rows.

sql.ExecSql()

Syntax:

sql.ExecSql(handlerOrScript)

Executes Query and returns a string array (string[]). You can enter a script handler or SQL Query as handlerOrScript parameter.

sql.Exists()

Syntax:

sql.Exists(handlerOrScript)

Executes a SQL statement and returns true or false depending on whether the query returns a value/row. You can enter a script handler or SQL Query as handlerOrScript parameter.

Example:

sql.Exists("SELECT [Id] FROM [PaymentTypes] WHERE [Name] = 'Cash'");

cmd.X

cmd.Execute()

Syntax:

cmd.Execute('name:value');

Executes [:AutomationCommandName] called name and passes value as the [:CommandValue]


Data.X

Data.Set()

Syntax:

Data.Set(<varName>,<value>)

Examples:

Data.Set("description", paymentinfo);
Data.Set("canContinue",false);

Data.Get()

Syntax:

Data.Get(<varName>)

Examples:

var pt = Data.Get("paymentTypeName");
var tendered = Data.Get("tenderedAmount");
var an = Data.Get("accountName");
var an = Data.Get("AccountName");
var an = Data.Get("DocumentId");

file.X

file.ReadFromFile(fileName)
file.WriteToFile(fileName, content)
file.AppendToFile(fileName, content)

file.Starter()

This function returns the exit code for started process.
Instead of using .Execute() you can use .ShellExecute().

file.Starter(<filePath>).Execute();
file.Starter(<filePath>).Hidden.Execute();
file.Starter(<filePath>).With(<arguments>).Execute();
file.Starter(<filePath>).WorkOn(<workingDir>).Execute();
file.Starter(<filePath>).With(<arguments>).WorkOn(<working dir>).Hidden.ShellExecute();

file.For()

file.For('c:\\folder\\test.txt').Starter().Execute();
file.For('c:\\folder\\test.txt').CreateFolder().Write('test 123');
file.For('c:\\folder\\test.txt').CreateFolder().Append('test 123');
file.For('c:\\folder\\test.txt').CreateFolder().Read();
file.For('c:\\folder\\test.txt').Delete();

api.X

api.EntityType(name).Entities().State(name).Update(value);
api.EntityType(name).Fields(name).Exists();
api.EntityType(name).Fields(name).Create(fieldtype,[format],[valuesource],[hidden]);

api.Entity(name).State(name).Update(state);
api.Entity(name).State(name).Get();
api.Entity(name).Data(name).Update(value);
api.Entity(name).Data(name).Get();
api.Entity(name).Exists();
api.Entity(name).Create(entityTypeName);
api.Entity(name).CreateAccount([accountName]);

api.User(name).Create(role);
api.User(name).Exists();

api.UserRole(role).Create();
api.UserRole(role).Exists();

api.AccountType(name).Create([rule|'All','Credit','Debit']);
api.AccountType(name).Exists();

api.Account(name).Exists();
api.Account(name).Create(accountTypeName);

api.PaymentType(name).Processors(name).Exists();
api.PaymentType(name).Processors(name).Create();
api.PaymentType(name).Processors(name).Delete();

api.Rule(name).Exists();

api.AutomationCommand('name').Maps().SetUserRole(role);
api.AutomationCommand('name').Maps().SetTerminal(terminal);
api.AutomationCommand('name').Maps().SetDepartment(department);
api.AutomationCommand('name').Maps().SetTicketType(ticketype);
api.AutomationCommand('name').Maps().SetEnabledStates(states);
api.AutomationCommand('name').Maps().SetVisibleStates(states);
api.AutomationCommand('name').Maps().SetVisibility(visibility);

act.X

act.Execute()

Executes a Configuration Task

Syntax:

act.Execute(taskName,[key1=value1;key2=value2;...])

Example:

act.Execute('Switch Theme');

theme.X

Changes the SambaPOS Theme.

theme.UseDark();
theme.UseLight();

web.X

web.Download(url,[regex])

returns url content and optionally returns first group capture of given regex.

web.Upload(url,content)

uploads content to url with POST method.

web.PostJson(url,jsondata,username,password)

web.PostData(url,data,[user],[password])

Both functions web.PostData() and web.PostJson() are identical but web.PostJson() function adds "Content-Type", "application/json" header to the request.


JSON.X

JSON.parse()

Converts a JSON string into an Object.

JSON.Stringify()

Converts an Object into a JSON string.


xml.X

xml.Parse(xmlContent)

Returns a dynamic object that allows you access tag values with properties.


script.X

script.Load()

Loads a Function contained in an outside Handler

Syntax:

script.Load(<handler>,<functionA>[,<functionB>,<functionC>])

Examples:

var stringFuncs = script.Load("str","pad");
var w = stringFuncs.pad(w,'left',5,'0');

dlg.X

dlg.ShowMessage()

Behaves like the Show Message Action which produces a Message Box.

Examples:

dlg.ShowMessage("This is a test.");

dlg.AskQuestion()

Behaves like the Ask Question Action providing a list of choices to answer a question.

Examples:

var cctype = dlg.AskQuestion("Choose Credit Card type","Amex=AMEX,Master Card=MAST,Visa=VISA,Discover=DISC,Other=OTHR,CANCEL=CANCEL");

dlg.EditValue()

Behaves like [?prompt] syntax to allow user input.

Examples:

dlg.EditValue("Last 4 CC Digits;.{4};;ON","");

gql.X

gql.Exec()

Executes GraphQL Statements.


DateRange.X

This is a helper class that contains a date/time range. Do not use directly. We’ll use dt object to create date ranges.

DateRange.Start

Starting date time of the range.

DateRange.End

Ending date time of the range.

DateRange.Days

Returns total day count of range.

DateRange.MonthName

Returns month name for start date


dt.X

Contains helper functions to create date ranges (DateRange objects).

dt.Day(day=0)

returns a singe day range. All ranges starts at 00:00:00 and ends 23:59:59. Use day parameter to add / subtract days. dt.Day() returns today, dt.Day(-1) returns yesterday.

dt.Week(week=0)

returns single week date range. dt.Week() returns this week, dt.Week(-1) returns previous week.

dt.Month(month=0)

returns current Month range. dt.Month(-1) returns previous month.

dt.GetRange(start,end)

returns a range from given date strings.
var range = dt.GetRange(‘1.1.2015’,‘2.2.2015’);


tag.X

Helper methods for easy constructing formatted Tile content.

Syntax:

tag.[tagFunction]

Possible tag functions

Color(color,[content])         
Size(size,[content])           
Font(fontName,[content])  
Bold([content])
ExtraBold([content])
Thin([content])
Italic([content])
Underline([content])
Block([content])
Panel(color,[content])
Linebreak()
Sym(content)
Img(content)  
Add(content)    * does not terminate
Get([content])

host.X

host.lib()

Creates a reference to .Net assemblies.

Examples:

As PowerShell is installed separately it is not part of default .net framework. We need to use host.lib() to be able to reference the required assembly.

function getBatteryLevel_byPowershell(){
  var m = host.lib("System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
  var ps = m.System.Management.Automation.PowerShell.Create();
  ps.AddScript("return (Get-WMIObject Win32_Battery -ea 0).EstimatedChargeRemaining");
  var result = ps.Invoke();
  var result1= result[0];
  ps.Dispose();
  return result1;
}

Reference:

host.type()

Creates a reference to C# Types.

Examples:

var dir = host.type("System.IO.Directory")

function b64(input)
{
  var convert = host.type("System.Convert");
  var encoding = host.type("System.Text.Encoding");
  var inputBytes = encoding.UTF8.GetBytes(input);
  return convert.ToBase64String(inputBytes);
}

There is no strict difference for the following example. host.type() will work for most cases but host.lib() is useful when we need to access multiple assemblies.

function getBatteryLevel_byAssembly(){
  var m = host.lib("System.Windows.Forms");
  var p = m.System.Windows.Forms.SystemInformation.PowerStatus;
  return (p.BatteryLifePercent * 100).toFixed(0);
}

function getBatteryLevel_byType(){
  var m = host.type("System.Windows.Forms.SystemInformation","System.Windows.Forms");
  return (m.PowerStatus.BatteryLifePercent * 100).toFixed(0);
}
13 Likes

Actually, I never knew/used Helper. It make a lot of thing easier.
Thanks,

EDIT: Tip on debugging.
Use return to help debug by placing it before the code end so, you know from where you code went wrong.

Incredible compilation @QMcKay - really invaluable if you are trying to customize Samba!

QUESTION:

Your use of Square Brackets [..] infers the argument is optional? For example above .Range is mandatory but [First|All] is not?

That is what it is trying to infer, yes. However, in that case, Range is not mandatory, so that syntax needs correction. For example, we know this works without Range:

var q = "SELECT 'something'";
var r = sql.Query(q).First

Right now I am just scraping old posts and doing copy/paste to compile the list (thus the error above). I will go back and make corrections and provide more examples eventually. This will take some time.

1 Like

Take your time Q! - your efforts are always outstanding and appreciated very much. That command just caught my eye because I NEVER SEEN the [ByWorkPeriod] and was blow away at that and others you have graciously compiled. Just goes to show how invaluable threads like these are - “Any documentation is better than none” :smiley:

2 Likes

###2016-10-17

  • added a few updates
  • re-categorized as V5 Tutorial in Public Forum
  • bump for those who have not seen this before
1 Like

Do you know what would that be last (second) parameter for dlg.EditValue?

Another question, Now Ask Question has Description field but dig.AskQuestion still don’t have that parameter right.

dlg.AskQuestion take 4 params, 3rd is background color, 4th is transparent color.

It probably does have it we just have not discovered it yet.

I try 5 params but it said something like no overload 5 parameters.

Sorry, no, I don’t know what it is for or what it does.

I guess that just means the Action was updated but the API Helper was not.

1 Like

I updated this post to reflect some new api helpers available.

api.User(name).Create(role);
api.User(name).Exists();

api.UserRole(role).Create();
api.UserRole(role).Exists(); 

api.AutomationCommand('name').Maps().SetUserRole(role);
api.AutomationCommand('name').Maps().SetTerminal(terminal);
api.AutomationCommand('name').Maps().SetDepartment(department);
api.AutomationCommand('name').Maps().SetTicketType(ticketype);
api.AutomationCommand('name').Maps().SetEnabledStates(states);
api.AutomationCommand('name').Maps().SetVisibleStates(states);
api.AutomationCommand('name').Maps().SetVisibility(visibility);
2 Likes

Thanks @Jesse, just the thing I was after.
Do you have and samples of these in use yet? Can you set pin/password?

The only example is the new beta time clock config task. Yes you can set pin I’m pretty sure. I’ve not tried it yet.

Cool, will have a dig.
Hoping to use the login setup for using password and pin for dual login methods for the tablets (without RFID)
Was worrying about duplicate passwords as they would be allowed as meant to be used in combination with user so was thinking custom automation to create to validate password as pin to be unique but just thought RFID is 99.9999% going to be unique so if use RFID in password field and manual pi in pin it should be covered.

1 Like

But this will still be vital to the planned centeral managed user and loyalty site to add syncing users as well as loyalty entities between hotels.
Although will mean creating a custom flow for admin pin confirmation also but shouldn’t be to bad.

1 Like

There may be more helpers available I’ve not tried them. I derived these from looking at a few config tasks.

You can probably use the exists helper to confirm pin.

Presumeably they should be documented in the gql pages? Not check yet. The hotel is currently still on 1.58 so haven’t delved too deep in API as not had real life applications implimentable untill I update to 2.18 next week ready for the tablets and associated updates.

These are not part of the gql. These are different.

1 Like