Kitchen/Bar Display using Task Printer - separate displays for Food and Drink

Or you can load a backup… or erase transaction data. If you did these changes on a live production system then you may have committed murder on your system… always backup and be prepared for the worse.

That may not clear tasks but unzipping this file under My Documents\SambaPOS5\Database Tasks folder and executing Database Tools > Clear Tasks will clear tasks. Also restart SambaPOS to ensure Task Caches are completely cleared.

[CBL]Clear Tasks.zip (197 Bytes)

2 Likes

Nice!

1 Like

PS: Also on next update size tag will set Font Size as 0.1 when it set as 0.

1 Like

LOL your right I completely forgot it doesn’t erase tasks. I edited mine so it would and just took that for granted and forgot it doesn’t.

2 Likes

thank you so much, it work perfect!!!

it was just a write mistake, i dont know exactly where it was because i did not fix it
but it is a good exercise to give the problem to another to check it step by step

Regarding the bug with parameter names, I had a similar problem with Execute Automation Command action using [:CommandValue] as a parameter whereby the passed in value was ignored, so now using [:CmdVal] instead and replacing all actions having parameter names matching internal ones. Lots of state update confusion resolved!

i am wondering if this was fixed in .61, as i still have lots of actions to update to avoid possible problems in future. Often action parameters were defined but not yet used, so not causing trouble at present.

I don’t think it was “fixed” persay in .61 but it does display warnings now and does not allow you to save Rules that violate this restriction.

For Automation already in place, you won’t know about the violation unless you open a Rule and try to save it, but it is definitely a step in the right direction.

.61 also has Rule validation so you check/verify your Rules. It also logs issues with Rule execution in the log file if it encounters a problem, even if the problem is not detrimental to actual functionality. This allows you to fix problems that it detects, so theoretically you get down to having no Rule errors in your logs. I had a few Rules that were logging errors and fixed them quite quickly. They were in the VIP/HH setup, and did not affect it’s functionality at all, but I fixed them anyway to get rid of the incessant logging :wink:

More on OP topic.
I recently implemented this Kitchen and Bar display using Task Printer which is working great!

But now i am having trouble with updating the order state when the Task is completed.
I want to keep track of state to update Order line colors and Table entity formatting as part of a course scheduling system.

I am firing a command with the Completed event ok, but how to update state of a single order?

The Update Order State action doesn’t let you specify ORDER ID, or ORDER UID, so how to single out a specific order when various orders on the ticket have the same state?

i was thinking to execute or call a JS function to update the state directly using sql. This would probably do the job, except i would prefer to get states to update real time and also concerned about possible conflict with other state update actions which could be running at the same time. possible caching issues also?

is there a simpler way to do it which i am overlooking?

@QMcKay That Rule validation feature will be very useful i think, upgraded to .61 today, so will be looking at those logs!

Solution for selecting specific order:
Make sure “More Ticket Actions” module is installed in Samba Market!
Somehow this module was uninstalled without me actively choosing to do so, and is required to enable “Select Orders” Action.

2 Likes

@QMcKay I’m still having some trouble with Kitchen/Bar Display regarding Voids (cancellation of submitted orders).

I have an Id line in Void section of template as specified:
(Id={ORDER ID}-{NAME}-{TICKET ID}-{ORDER UID})

and getting red cards okay, except the problem is that sometimes the original order card and the voided card are merged into the one card correctly, but mostly the voided order is a new card which makes the display confusing.

This variable behavior occurs while using the same template and seems to be related to the formatted content part of the card. I’m only guessing this because results are inconsistent and the behavior sometimes changes when i change the formatting tags within the body data of the card.

Could there be an issue with how the way the Voided card is merged into the card with matching Id?
or is the Id string not reliably matching sometimes for some strange reason?

In this example, the cancelled Spring Rolls (A2) stanza was merged into the original card correctly but when the Mixed Salad (A51) was cancelled, a new card was created. Both were done within 4 minutes of each other using exactly the same templates and automation.

Here is top section of the Template:
[LAYOUT]
{ORDERS}
[ORDERS]
++{ORDER TIME} Table: {ENTITY NAME:Table}
(Color=#FF333333)
(Id={ORDER ID}-{NAME}-{TICKET ID}-{ORDER UID})
<color #FFFFFF00><size 36>[=(’{QUANTITY}’>1 ? (’{QUANTITY}’+’ x ‘).substr(0,4) : ’ ‘)]<size 48>{ITEM TAG:MenuCode} <color #FFFFFFFF><size 30> T:{ENTITY NAME:Table}
<color #FFFFFFFF><size 16>{PRODUCT NAME}
<color #FFFFFF00><size 36>{ITEM TAG:Thai}
<color #FFFFFF00><size 34>{ITEM TAG:Khmer}
[=’{PORTION}’==’’ ? ‘’ : ’ <color #FF55FF33><size 34>{PORTION}’]
{SORTED ORDER TAGS}

[ORDERS:Gift]
(Id={ORDER ID}-{NAME}-{TICKET ID}-{ORDER UID})
<size 30>{ITEM TAG:MenuCode} T:{ENTITY NAME:Table} FREE GIFT!
{SORTED ORDER TAGS}

[ORDERS:Void]
++{ORDER TIME} Table: {ENTITY NAME:Table}
(Id={ORDER ID}-{NAME}-{TICKET ID}-{ORDER UID})
(Color=Red)
<size 30>{ITEM TAG:MenuCode} T:{ENTITY NAME:Table} CANCELLED
{SORTED ORDER TAGS}

Any ideas?

Another issue with KD I’m having is that i can’t send the Id field as a parameter in my Task Complete Command call back.
The event and rule is executed fine when the command name is specified without the [id] parameter suffix.

I need to receive status updates so i can update the table entity display which is showing important state information for service staff. I could implement another Task Editor entity screen for showing Ready status to service staff, as you have shown, but I’m already showing the state of tables and other info on the main screen relating to course scheduling and this data needs to be kept in sync to avoid confusion.

Regarding the inconsistent card merging on Void, i was thinking that perhaps {ORDER UID} sometimes changes, so tried defining an id without that part. But the result from that experiment was that voided orders always create a new card.
I was thinking that {ORDER ID} would be the database row Id so should be unique as well.

@Emre What is the purpose of the {ORDER UID} value and how is it derived? It it possible that it changes after Order states are changed or some other internal factor?

You are correct. It is the DB Id and it is unique, and it is sequential. However, the Id is not generated until the Order is submitted, so on first print of the Task Card, the Id is null. So it is not reliable, especially in the case of Voids.

The UID does not change, even with Order modification. It is a random alpha-numeric string generated in-memory when the Order is added to the Ticket. This happens immediately, even before Order Submission, and when the Order is submitted, the UID is written to the DB. Because of this, the UID is actually the reliable identifier.

I have since changed this setup to omit the Order ID and use the UID and Name only. You could also just use the UID. So in all sections of your Template ([ORDERS], [ORDERS:Void], etc), change the Identifier to something like this:

(Id={NAME}-{ORDER UID})

I think that should be [Id] not [id]

Also, your syntax is not quite correct. The syntax to pass a value with the command is:

CommandName:CommandValue
... or ...
CommandName:[CustomFieldName]

… so your Task complete command should probably look like this:

cmd TKT KBD Kitchen Order Ready:[Id]

The [Id] shown above is the Task Identifier (the [Identifier] field in the [Tasks] table in the DB), which is defined in your Template and is normally not visible on the Card.

1 Like

@QMcKay Thank you for the detailed response.
Got it working now! Using {PRODUCT NAME} - {ORDER UID} as the Identifier as you suggested, the Voids are now reliably displayed on the original card.

Strange how the TicketId would be different though as I thought the Task editor is printed on Ticket Closing event when {TICKET ID} should be available and deterministic.

Now having difficulty selecting the order to update states on.
I see the need to receive Ticket Id on the Task Completed command to make it easy to determine the Ticket to load and select the matching order, so was thinking about making the task Identifier a JSON string containing the references I want to know about during completion processing. I’m already using a field extraction function using JSON.Parse in JS elsewhere so trivial to make it. But I assume that would lead to the same problem with split voided cards fixed here.

I’m still struggling with appropriate usage of Select Orders, and Update Order State. Is it possible to select orders based on Order UID or only Order ID?
Or is there a way to Update order state of orders having a common State but different State Value? I am trying to save a parent ticket id in an order state but can’t have unpredictable state names otherwise they can’t be hidden. So was looking at using an Order State group called TicketId with just one state of TicketId having a value set to the TicketId which would be updated during Ticket Closing based on similar logic to the KD Print request. (as per FPrinting in your tutorial) .

But while writing this I still dont know if Update Order State can filter on state values. Need to go try some stuff…

Is there an easier way to update order state for one specific order?

It seems I’m chasing my tail here!!
Maybe I’m just confused.

I think you are correct - the Ticket Id should be usable as part of your Identifier. Would need to test that by looking at the [Tasks] table in the DB. The only way the Ticket Id might change is if you move the Order to another Ticket (ie. split the Ticket)… then your Ticket Id reference will be incorrect in the Task, so you would need to find a way to update it. GQL would be the only way to do such a thing at this time, because we don’t have the required Actions in automation to make that happen.

By that logic, we might assume the Order Id is also available, but it is not necessarily unique. Try adding an Order, then add that same Order again in the same session, then submit the ticket. What do you see in the [Orders] table? What do you see in the [Tasks] table when you include Order Id as part of the Identifier?

Interesting idea. It might work. Not sure that is the best solution though.

AFAIK, only by Id. Need to look at the Action to verify.

Not sure. Need to try that. Probably.

The only way the Ticket Id might change is if you move the Order to another Ticket (ie. split the Ticket).

As a simplification, we could prohibit a ticket SPLIT until all orders on the ticket are completed, although that would prevent split payment for prepaid orders such as takeaway. hmmm. not ideal but okay for a version 1 now.

so in my setup i could use:

{REPORT ORDER DETAILS:OS.KBD_ReadyState.Count :(OS.KBD_ReadyState=Drink Displayed) || (OS.KBD_ReadyState=Bar Food Displayed) || (OS.KBD_ReadyState=Starter Displayed) || (OS.KBD_ReadyState=Main Displayed) || (OS.KBD_ReadyState=Dessert Displayed) && T.Id=nnnnn }

to return the number of orders ‘Displayed’ and not yet ‘Ready’ for the ticket
to use within the Constraint for SPLIT rule like: '<report above>' == '0'

In my Completed callback rule I would update an extra state called KBD_ReadyState
from "<Course> Displayed"
to "<Course> Ready"

In the Printer Template i define the Identifier like as JSON such as:

(Id={"item":"{NAME}","tid":"{TICKET ID}","oid":"{ORDER ID}","ouid":"{ORDER UID}"})

and in the Completed callback rule i could extract the Ticket Id using:

{CALL:sys.getJSONField('tid','[:CommandValue]')}

The script in handler called “sys” for that is already there:

// Get field data from simple JSON string function getJSONField(sField,jsonData) { if (typeof(sField)=="undefined" || sField=='') return 'Invalid field name:'+sField; var oFields = JSON.parse(jsonData); var sData = oFields[sField]; if (typeof(sData)=="undefined") return 'not found: '+sField; return oFields[sField]; }

That’s my plan right now. Let’s see how it goes …

I’m wondering if it is possible to isolate the Identifier string from a value only used to pass back in [:CommandValue]

in other words, have an extra line in template like:

(MyCustomDisplayData={“item”:"{NAME}",“tid”:"{TICKET ID}",“oid”:"{ORDER ID}",“ouid”:"{ORDER UID}"})

making it separate from the Id definition which could be simplified down to:

(Id={ORDER UID})

maybe i will just try it … such is the way with trying to use vague undocumented SambaPOS functions :wink: