SambaPOS API Integration with NewBook PMS/Booking System

Cant believe I missed that one but using tasks for API logging, much better plan than the original discussed ages ago using txt files.

Note to self;

Using tasks.

1 Like

Hmmm, another thought, ticket log would be better place, tasks for api request runs, responces logged in ticket log, sounds ideal :slight_smile:ā€¦ now though, do we have script helper for ticket log? if not maybe it would be good to go in to graphql if not already.

I donā€™ think there is API for Ticket Log, But with Script and GraphQL, you have a lot of power over Tasks - much more than the single Add Task action that we have in Automation. GQL letā€™s you do just about anything with Tasks.

Both the KD and Timeclock in GQL Modules use Tasks and the power of GQL to manipulate them. Itā€™s all done in Javascript code, which is pretty much the same as JScript in SambaPOS. All the GQL Queries and Mutations are available in Script via the gql.Exec() API command.

1 Like

Made an update to handle calculations.


var ticketDiscountIdList							= '';
	var ticketDiscountIdList							= ticketDiscountList(inputTicketId);																				//--query ticket discount total
	var ticketDiscountIdCount							= '';
	var ticketDiscountIdCount							= ticketDiscountCount(inputTicketId);
	if (ticketDiscountList) {																																				//--if discount defined
		for (d = 0; d < ticketDiscountIdCount ; d++) {
			var discountId								= ticketDiscountIdList[d];
			var discountDetailsArray					= ticketDiscountDetails(discountId).split('~');
			var discountName							= discountDetailsArray[0];
			var discountDecrease						= discountDetailsArray[1];
			var discountAmount							= discountDetailsArray[2];
			
			var discountGLAccountHashIndex				= discountName.indexOf('#');
			
			if (discountGLAccountHashIndex>-1){
				var discountGLAccountNumber				= discountName.slice(discountGLAccountHashIndex+1);
			} else {
				var discountGLAccountNumber				= discountGLAccount;
			}
			
			if (discountAmount<0){
				var discountValue							= discountAmount*-1;
			} else {
				var discountValue							= discountAmount*1;
			}
		//	return discountValue;
			var postDesctiption 						= 'Ticket: '+ticketNumberDescription+' - '+discountName;															//--built post description
			var postGLAccount	 						= discountGLAccountNumber;																							//--post gl_account code
			var postAmount 								= discountValue.toFixed(2);																							//--post amount to two d.places
			var postTaxFree 							= '0';																												//--post taxable number 0/1
			var postJsonData 							= new Object();																										//--define object for json post
			postJsonData.description 					= postDesctiption;																									//--json.description
			postJsonData.gl_account_code 				= postGLAccount;																									//--json.gl_account_code
			postJsonData.amount 						= postAmount;																										//--json.amount
			postJsonData.tax_free 						= postTaxFree;																										//--json.tax_free
			var postJson 								= JSON.stringify(postJsonData);																						//--stringify json object
		//	if(d==1){
		//		return discountDetailsArray[2];
		//	}
			if (discountDecrease==='True'){
				creditsArray							+= postJson+',';
			} else if(discountDecrease==='False'){
				chargesArray							+= postJson+',';																									//--add to credits variable
			}
		}
	}		//--end discount if

function ticketDiscountCount(inputTicketId) {																																//--Discounts on ticket by ticket id
	qry =  "SELECT COUNT([Id]) as [CT]										";
	qry	+= "FROM [Calculations]												";
	qry	+= "WHERE [TicketId] = '"+inputTicketId+"'							"	;																							//--QRY Variable + inputDate + inputPaymentType
	var discountCount = sql.Query(qry).First;																													//--SQL Query responce -> payment totals for work period exc payments
	return discountCount;																																					//--return discounts total
}	

function ticketDiscountList(inputTicketId) {																																//--Discounts on ticket by ticket id
	qry =  "SELECT [Id]														";
	qry	+= "FROM [Calculations]												";
	qry	+= "WHERE [TicketId] = '"+inputTicketId+"'							"	;																							//--QRY Variable + inputDate + inputPaymentType
	var discountList = sql.Query(qry).Delimit('~').All;																													//--SQL Query responce -> payment totals for work period exc payments
	return discountList;																																					//--return discounts total
}																																											//--end function

function ticketDiscountDetails(inputDiscountId) {																															//--Discounts on ticket by ticket id
	qry =  "SELECT [Name],[DecreaseAmount],[CalculationAmount]				";
	qry	+= "FROM [Calculations]												";
	qry	+= "WHERE [Id] = '"+inputDiscountId+"'"	;																															//--QRY Variable + inputDate + inputPaymentType
	var ticketDiscountDetails = sql.Query(qry).Delimit('~').First;																											//--SQL Query responce -> payment totals for work period exc payments
	return ticketDiscountDetails;																																			//--return discounts total
}							

Particularly like this bit;

var discountGLAccountHashIndex				= discountName.indexOf('#');
			
			if (discountGLAccountHashIndex>-1){
				var discountGLAccountNumber				= discountName.slice(discountGLAccountHashIndex+1);
			} else {
				var discountGLAccountNumber				= discountGLAccount;
			}

Which takes the number following the # on the calculation name to set which accounting department the charge/credit is created in NewBook.

So Regular Drinks Discount #2301 discount goes to GLAccount 2301 which is grouped under wet sales on 2101.
The if catches general other calculation should they get used for some reason like round and original discount.

2 Likes

Exactly what I am looking for, but I donā€™t even know where to start :smile:

Are you looking to use NewBook?
This all would give a near full intergration, you could get away with just posting room sales but personally prefer sending over all so there is a single point of reporting.
The current setup will have had some tweeks from scripts documented here. They also have updated API moving the request type to a value in the array with a single endpoint buy continuing old methods for now.
There could also be some improvements using the graphql calls to avoid some of the direct SQL scripts however the hotels here are still running a pre ql version of samba.

1 Like

I am looking for a solution that I can use for bookings and food sales at the same time. This post looks like it covered all that but it requires some time to grasp the flow. Is there a way we can use Samba itself without intergrating NewBook?

The other room entities topic did in house rooms but not a booking calander for future bookings.
As I have told others if there are enough rooms and plan to use channels like booking.com etc a propper PMS like newbook is the way to go.
For a little B&B or pub with rooms could get by but even our 7 room pub/inn uses newbook and booking.com.
Booking.com etc a counts for arround 40% of our bookings up over 50% sometimes.
Plus online bookings direct? Is this wanted, newbook and other PMS will have this. You can use booking.coms sytem for lower fees on direct refered bookings I guess.

The company I work for is somehow linked to another system called the booking factory.
I pestered them for an API last year and they now have one and are much cheaper than newbook or at least were. There API is pretty basic compaired to newbook but they have the key room details and charging posts available.

1 Like

I think this other tutorial you did here will help me for now since the customer doesnā€™t have future bookings they just want to handle walk in bookings. I am going to try and implement it.

Just checked and this integration has now processed over 1 million itemized charge lines to the PMS between the 3 sites currently installed at :slight_smile:

2 Likes

Ī—ello,
I would like some helpā€¦
I would like to add to each proof to update the database and the AADE Electronic Books

hi there i was told i can make contact with you for some help

What kind of help you looking for?

i want to implement samba for a hotel i was trying to get your contact info from your website but did not find it can you email me dm.narsingh@gmail.com

Im not in a position to take on a bigger project like a new intergration at the minute, got several on the go already.
If you have questions or after advice ask but cant offer to do it for you.

well the client is using room master i dont thing this works but can you advice on setting up the entitiy for charge to room and them let it send out an email to front desk with the bill
and breakfast can we creat a coupon for the client so they can use that

Got a link?
Any details for their api and documentation for it?
Youll need api info to even see if its posible, not all systems will offer api info openly and some dont have endpoints for adding charges - often more making bookings etc for ota intergrations etc.
If they dont you could look to just make accounts for rooms in samba but as stand alone seperate to PMS itself which sounds more like what your sugesting but if they have suitable api is counter productive to automating.

If your not going down route of intergrated, there was another fairly bit topic for a basic stand alone setup. Think it was this one;