Easy Update Daily Specials from POS on Entity Screen without Admin/Management Login

At the hotel here we have daily specials that are updated at least twice a day for lunch and dinner. Sometimes also do afternoon specials.
I didnt want access to management section and navigation action couldnt be selective enough to just one specific order tag group.
So my solution is to use a custom entity screen;

Currently i have slots for 4 starters, 6 mains and 4 desserts.
The first two columns are just labels calling the setting values for the name and price of the specials.
Then two buttons for update and clear.
Settings are stored in pairs so for 1st starter would be SpecialStarter1Name and SpecialStarter1Price.
The buttons have comman names of UpdateSpecial and ClearSpecial. Then each row has command value for the special number ie. SpecialStarter1 and SpecialMain3

These buttons go to these rules;

image

The UpdateSpecial command rule has two update global program settings actions where name is the numbered special name suffixed by Name and Price to create the pair of settings.
The values are set by a pair of [?Prompt] functions. (plan to add validation on the price either with mask or other automation to make sure its a number.
This then results in the following prompt;

Clear empties the setting values for the two settings for that numbered special setting.

Then using these settings and custom menu item buttons and couple of short scripts these settings are then used to mimic actual products of those names without updating products etc.

Starter as an example, I have 4 custom menu buttons;

They have command names and values as below;

image

This script called from the header dynamically sets the header using the corasponding setting values;

function specialMenuItemHeader(specialName,specialPrice){

	if ( specialName == '' || specialPrice == '' ){
		
		return '';
	
	} else {
	
		return specialName+'\r£'+specialPrice;
	
	}

}

So if name and price is set it shows a formatted name and price for header and if not it shows nothing.

All special custom buttons trigger the same rule;

image
image

The rule constraints cover command names for starters, mains and desserts and checks the corasponding setting name and price are not null so if not set it doesnt add the product with 0 value…

The add order actions add a ‘dummy’ special product for starter/main/dessert. Which is defined by an action constraint using a script to trim the number from the command value to match say ‘SpecialStarter’

image

It adds the product and sets the price using the setting name based on command value with Price suffix.
Then the order tag action adds an order tag for specials which is a fee tag using the setting for name.

image

image

I formatted the display format to invisible colour with 0 size to hie visually as best as possible as this tag will be used to visually replace the actual order/product name.

This order is actually a product of ‘Special Starter’

To achieve this I have used order state display format and another script to set the name using either the order name or the special free tag depending on the product.

This would usually be New state but i have created a custom state flow to set special formatting for other parts of my setup so mine is FNew (Formatted New)
This would need to be applied to all order state formats to set for new, submitted and void orders etc.

This is that script;

image

It checks if the product is a Special which needs name replacing which is it is it uses the input Special Free Tag value.
The other section is what I use to seperate product name and portion for non normal portions with a space rather than with a . like default.
Like this for example where the product is Carlsberg and portion is Pint.

So using similar principle for prints the printer templates will have a ternary expression to show either the normal order name or for specials the special free tag in place of the order name.;

This ticket for example;

Would print like this without the order name adjustment, with Special Starter for order and Starter 1 as an order tag;

image

First setting an empty section for [ORDER TAGS:Special Tag] hides the special tag;

image

Then by changing the [ORDERS] and [ORDERS:Gift] sections using a ternary expression to check the order product name to again display either the normal name or the special tag if a special product.

image

This is the exact same ticket.
These adaptions are more applicable to the kitchen printer but normal receipt is also then kept clean and in similar format to any other product.

2 Likes

Reserved for updates …

Tidied up the entity screen a little;

1 Like

Added additional dummy buttons for headers and hidden buttons to create sections for a new special category

Though I might get creating and rather than just set header to blank for unset/unused special buttons a small script and little SQL i could update the button appearance as part of the update and clear automation.
Also took this as opportunity to validate the values of prompts.

So using this script I can now change the custom button appearance option;

@RickH this might be of interest to you for some of you fancie menu setups if you havnt done something similar already.

function changeButtonAppearance(buttonName,appearance){

if( appearance == 'Image And Text')
var appearanceInt = 0;
if( appearance == 'Image Only')
var appearanceInt = 1;
if( appearance == 'Hidden')
var appearanceInt = 2;

qry = "UPDATE [ScreenMenuItems] SET [Appearance] = '"+appearanceInt+"' WHERE [Name] = '"+buttonName+"'";
var execute = sql.ExecSql(qry);
}

So first i added the script to set to hidden on clear special automation rule along with a refresh cache to reload the menu with the updated appearance;

Then to set to show the button and validate the update values i added an execute automation command action to the update specials rule so that the program settings can be called and validated after they are updated in the prompts;

image

Then created the Validate and update automation command rule;

Using action constraints it checks that special has had a name set and that the price (converted to force number) is larger than 0 and if so sets that specials button to Image And Text then refreshes cache.

If either the name is null or the price (converted to number) is equal or less than 0 triggers that same clear special command via an ask question to notify of the issue using its command name field and re-passing the command value on which is the ‘SpecialStarter1’ type value.

This not gives a specials category which only shows buttons for active and valid special settings pairs.;

Added a basic script call in the validation rule to try and set names to Title Case.

function titleCase(inputString) {
	var wordsArray = inputString.split(' ');
	var titleCase = '';
	for (w = 0; w < wordsArray.length ; w++) {
		var capitalised = wordsArray[w].substring(0, 1).toUpperCase() + wordsArray[w].substring(1).toLowerCase();
	var titleCase = titleCase+capitalised+' ';
	}
	return titleCase.substring(0,titleCase.length-1)
}

So now;

Unfortunately ’ single quotes screw up the script but it means script either results in null/returns null which updates setting to null which fails validation.

2 Likes

Use double quotes " to surround the string in the titleCase function within the {CALL:X} and that should solve that (of course then you it will not work if a double quote character is in the string but I’d guess the chance of that is less.)

1 Like

Interesting concept.
I can see where this can come in and become very handy.

In fact I think I know a few who can benefit from this.

Thanks for sharing :slight_smile:

2 Likes

Yet, it’s one hay or the other. Tried to get head round masks but it’s confusing as f**k.

1 Like

Yet, I think it turned out well. It needs a recent version to work. Last time I tested the theory there were glitches but seems slick now.

Previously we have just used open priced products for specials but as we are finally moving forward with tablets and kitchen printer everything needs to be well named for kitchen.
Going RDP with ipads, pretty sure this type of setup isn’t going to play well with Android app.

UPDATE

Though I best add some validation to the SQL for the menu item appearance.
So if appearance variable isnt one of the defined values it defaults to the samba default of 0 (Image And Text)

function changeButtonAppearance(buttonName,appearance){

if( appearance == 'Image And Text') {
	var appearanceInt = 0;
} else if( appearance == 'Image Only') {
	var appearanceInt = 1;
} else if( appearance == 'Hidden') {
	var appearanceInt = 2;
} else {
	//if not valid appearance name default to normal Image And Text
	var appearanceInt = 0;
}
	
qry = "UPDATE [ScreenMenuItems] SET [Appearance] = '"+appearanceInt+"' WHERE [Name] = '"+buttonName+"'";
var execute = sql.ExecSql(qry);

}

lol yes I have never understood it. I just try stuff till it comes out lol.

2 Likes

Seems like allot of different standards. Thought there would be an online builder of sorts or decent list of common examples but struggled to find anything clear enough for newbie

I find tons of examples and people saying thats easy just do this… and I look at it and im like wtf how does an apple equal an orange… thats impossible.

I struggled to find something simple for open lengthens title case which would have through would have been fairly common/simple. Would be similar to full name.

On next update we’ll hide custom buttons automatically when there is no caption.

4 Likes

Nice, any thoughts on a mask or helper script for title case?

@emre will that be rendered header though? Obviously in senarios like this there is content in the header cell but it’s returning null

Is it possible to have blank buttons other than rendering content?

I mean a spacer custom button would have no header and be set to hidden.
Waa probably a silly ent