Modify Account Balance Externally

Hi Guys! I am finishing up a setup to sync my account balances [customer accounts] with external systems. I am doing this using a crafty node.js script. Initially I wanted to use GQL for this but could not find any mutation to modify the accounts balance [sambacard].

I started modifying the DB directly [I know, inefficient] which works well but I notice a curious anamoly:

If I edit dbo.AccountTransactions and insert a new row with a new Id – the balance for the entity updates when using ticket tags to display it however if I go into SambaPOS -> Customer Search -> [Entity] -> Account Details the manually added transaction will not appear. It’s almost like SambaPOS knows I added it manually and ignores it.

Can anyone let me know why this may be or a better way to accomplish my goal of modiying customer account balances externally?

Thanks!

Looks like I also need to insert a row into dbo.AccountTransactionValues for this to work which seems a bit sloppy as I am now modifying 3 tables externally :-\

Hey @Luis_Varsan - sorry I missed but lost my religion and do not come here as often as I did…

We have quite a few external systems pushing into SambaPOS. I created:

  1. Account Transaction
  2. Account Document
  3. Action for Creating Account Document
  4. Rule to use Account Document Action
  5. Script to call the Rule
  6. File Monitor to monitor transactions to absorb.

Works extremely fast and only exposed to Drive Disconnections so built stronger scripts to solve that.
It that what your interested in?

ACTION: Create Account Document is the Key for you as it does all the DB stuff correctly.
Cheers Paul.

1 Like

@pauln Precisely. What my goal is overall is to be able to poll an external system when an entity is loaded or before. So I want to have a custom screen or inside the same ticket when an Entity is selected it will:

Poll External System -> Check if data in remote system (I have an easy API) is newer -> Pull data -> Update Entity in Sambapos -> continue

So basically I have a remote cloudDB (Restdb) and it stores all my customers and balances. I can easily make it sync manually but I want to make this integrate well into SambaPOS, I can poll customer data from restdb super easy with a web api, I just need SambaPOS to create the proper accounting to make it work.

@pauln is correct. There a several things you need to do in order to have SambaPOS really understand there are new Transactions:

  • Create Account Transaction Document (1 row)
  • Create Account Transaction (1 row) tied to Document
  • Create Account Transaction Values (2 rows) tied to Account Transaction

I tell people to think about it like this:

  • the Document is like a folder, or an Invoice.
  • the Transaction is like a piece of paper in the folder, or a line-item on the Invoice. There can be multiple Transactions in a Document.
  • the Transaction Values are like ledger entries (generally in pairs, 1 for Debit and 1 for Credit) which have a reference to the Transaction.

That’s the basic way SambaPOS Accounting works. The Debit and Credit Values should be balanced for the Transaction which is why they are usually “pairs”, however that is not required. For example, you could Credit 1 Account for 100 and Debit 5 different Accounts for say 20 each, which would balance the Transaction Debit/Credit Values.


This can be done in SambaPOS via Rules and Actions, and with the help of JScript in SambaPOS, you can fetch/pull data from an external source, and subsequently trigger Rules (ie. Automation Command Executed event) that perform the pertinent Actions.

As @pauln mentions, the key Action is Create Account Transaction Document. That Action references a Document configuration that you should already have that contains the Transactions Type(s) required, and those Transaction Type(s) should be configured to contain the Source and Target Accounts. If all of that is configured properly, all you need to do is plug in the Amount for the Action, and the rest should be done for you.


It can also be done “manually” via direct DB manipulation. I have done this with an external PHP Inventory System to create Purchase Transactions.

1 Like

@QMcKay & Paul - Thanks!

I was going to create a node.js handler / use an exisiting one but I realized - my primary goal is to simply push and pull account balances when entities are loaded.

I can do this via a script in SambaPOS… all I really need to do is [psuedo code to follow]

Ticket Entity Changed Rule
-> Call Script

[script (entityname,timestamp,balance)]
->Check remote timestamp
->If localdata is newer -> push data to restdb (via web api / url call)
->If remotedata is newer -> pull data from restdb (via web api/url call)

->Fire action to create account transaction documents to adjust local balance
->Refresh ticket

@QMcKay - The “Scripts” function in Automation - What format is it expecting? Javascript or just plain java? Thanks.

It is 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).

See here for good reference on the Helper and API extensions that were added to the Scripting Engine in SambaPOS …

@QMcKay Outstanding. Thanks!

Do you by chance know much about - 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.

Specifically asking because I need to post data and get data but need to add customized header values for authentication, my header needs to contain:

"x-apikey": "498543908594385",
"cache-control": "no-cache"

Do you know if this is possible?

Maybe, not sure. I have never used those helpers.

If it turns out that it is not possible, here is a good Topic where we discussed using the host.X or lib.X helpers to make a custom “post” function …

https://forum.sambapos.com/t/jscript-helpers-web-upload-web-postdata-and-soap-requests/12300

Are you sure these are additional header and not part of the data?

This function is the main one used in my PMS intergration (see below);

And my api key is passed as json in the data variable.
The way you have formatted looks like json data rather than header…

Hmm in my original code (JS/Node) it’s handled this way:

var request = require(“request”);

var options = { method: ‘GET’,
url: ‘https://www.myurl.com’,
headers:
{ ‘cache-control’: ‘no-cache’,
‘x-apikey’: ‘KEYHERE’ } };

request(options, function (error, response, body) {
if (error) throw new Error(error);

console.log(body);
});

Worst case you could setup an intermediate script on webserver you post to from samba which posts to your service and returnes the response to samba.
Less than ideal but there is always a way.
Keep trying for now and if all else fails look at alternate solutions.

Thanks! I have considered this option, this is what I do to use “Square” as a payment processor, I made a script that integrates with their API and acts as an intermediate.

Another option I am considering:

Node.js locally using GraphQL calls – I can use QMckay’s awesome work with the “Hub” handler to broadcast a new event and set a new use case, process it with JS/Node and then return a response by firing an automation command and passing values. It would probably be easier if I could get the built in Script function to work but easy isn’t always best.

2 Likes