Waiter Screen / Ready Orders

@QMcKay thank you very much for backup. I debugged it and found:

It searching for item with id Donair Wrap.Wrap-cbEflBWTfUagdJe5xUahCg and task type KD Waiter - Food but the actual task type for that item is KD Task GUI - Food. So r.data.task becomes null in getTaskbyIdentifier function.

I hope that helps.

But, it works properly when you complete only 1 Task at a time.

The Duplicate Command copies KD Task GUI - Food to KD Waiter - Food.

Then the Automation command executes the Function to update KD Waiter - Food (the duplicate) by its Identifier, to change its Color.

The problem is that the Duplicate command is only duplicating a single Task. Additional Tasks are not duplicated.

If we disable the Script call, no error occurs. However, you can see that 1 Task is duplicated TWICE, and the 2nd Task is NOT duplicated. I just tested this by disabling the Script action.

If I test Completing 3 Tasks, the 1st Task is duplicated 3 times, and the 2nd and 3rd Tasks are NOT duplicated.

That is probably a different issue. I don’t think they are related. When I create a ticket that have two orders and select both to complete same error throws.

Where is the duplicate command?

In the Rule “KD Ready - Food” … maybe I am using it wrong, I have never used it before …

That is fired by the Widget Task Complete Commands section on the Kitchen Display, for the Food Widget …

I have another idea to go about it a different way, without duplicating or changing the Task Type. Will try different method later today or tomorrow.

EDIT: just tried my other idea, but the Color of the Task Card is ignored once the Task is Completed. In fact, all formatting is lost on Completed Task Cards…

1 Like

This is my original idea (even before the Duplicate idea) simply using the GQL addTask() mutation in Script to copy the all the Task details to a new Task Type.

I was having trouble getting this work last night, but today it is working!

I think it might be because yesterday I was using {CALL:X} to execute the function, but today I am using the Execute Script Action.

##TASK TYPE

Our new Task Type for Waiter Food Orders

##KD Waiter - Food (Task Type)##

Name: KD Waiter - Food
Custom Fields(none)

##SCRIPT

:warning: This script looks the same as previously posted, but one of the functions has been updated, so you need to update the Script functions. Specifically, the addTask() function has been updated.

##TSK Task Type Functions [tasks] (Script)##

Script Name: TSK Task Type Functions
Script Handler: tasks

Script:

function getTaskbyIdentifier(taskType,ident,field) {
  // getTaskbyIdentifier('KD Task GUI - Food','27751-Qure Burger.Burger-12837-j9tXI2XMRkq7Q446SFfroQ')
  taskType = typeof taskType==='undefined' ? '' : taskType;
  ident    = typeof ident==='undefined' ? '' : ident;
  field    = typeof field==='undefined' ? 'name' : field;

  if (taskType=='' || ident=='') {
   return false;
  }
  
  var qry = '{task:getTask(taskType:"'+taskType+'",identifier:"'+ident+'"){id,name,identifier,content}}';
  var r = gql.Exec(qry);
  r = JSON.parse(r);
  var task = r.data.task;
  
  //dlg.ShowMessage("tt:"+taskType+"\rid:"+ident+"\rname:"+task.name);

  return task[field];
}

function addTask(taskType,name,content,ident,color,taskTypeOld) {
  // addTask('KD Waiter - Food','','blah','27751-Qure Burger.Burger-12837-j9tXI2XMRkq7Q446SFfroQ','#FFFFFF00')
  taskType  = typeof taskType==='undefined' ? '' : taskType;
  taskTypeOld = typeof taskTypeOld==='undefined' ? '' : taskTypeOld;
  taskTypeOld = taskTypeOld=='' ? 'KD Task GUI - Food' : taskTypeOld;
  ident    = typeof ident==='undefined' ? '' : ident;
  name     = typeof name==='undefined' || name=='' ? getTaskbyIdentifier(taskTypeOld,ident,'name') : name;
  color    = typeof color==='undefined' ? '' : color;

  var oldContent = getTaskbyIdentifier(taskTypeOld,ident,'content');
  oldContent = oldContent.replace(/"/g,"'"); // replace double-quotes so they do not make GQL error
  oldContent = oldContent.replace(/\r\n/g,'<br/>'); // replace linefeeds so they do not make GQL error
  content = oldContent + '<br/>' + content;

  //dlg.ShowMessage("tt:"+taskType+"\rid:"+ident+"\rname:"+name+"\rcontent:"+content);
  
  if (taskType=='' || name=='') {
    return false;
  }
  
  var qry='mutation m {addTask (task:{taskType:"'+taskType+'",name:"'+name+'",content:"'+content+'",isCompleted:false,identifier:"'+ident+'",customData:[{name:"Color",value:"'+color+'"}]}){id,name,isCompleted,content,identifier,customData{name,value}}}';
  var r = gql.Exec(qry);
  r = JSON.parse(r);
  var task = r.data.addTask;
  
  return task.name;
}

function updateTask(taskType,name,ident,color,complete,content) {
  // updateTask('KD Waiter - Food','','27755-Poutine-12841-swifCxkYVk6UDrmcd0JUmg','#FFFFFF00')
  taskType = typeof taskType==='undefined' ? '' : taskType;
  ident    = typeof ident==='undefined' ? '' : ident;
  name     = typeof name==='undefined' || name=='' ? getTaskbyIdentifier(taskType,ident,'name') : name;
  color    = typeof color==='undefined' ? '' : color;
  complete = typeof complete==='undefined' || complete==''? false : true;
  content  = typeof content==='undefined' ? '' : content;

  //dlg.ShowMessage("tt:"+taskType+"\rid:"+ident+"\rname:"+name+"\rcontent:"+content);
  
  if (taskType=='' || name=='') {
    return false;
  }
  
  var qry='mutation m {updateTask (taskType:"'+taskType+'",identifier:"'+ident+'",task:{taskType:"'+taskType+'",isCompleted:'+complete+',identifier:"'+ident+'",customData:[{name:"Color",value:"'+color+'"}]}){id,name,isCompleted,content,identifier,customData{name,value}}}';
  var r = gql.Exec(qry);
  r = JSON.parse(r);
  var task = r.data.updateTask;
  
  return task.name;
}


##ACTION

##KD ExecScript [Execute Script] (Action)##

Action Name: KD ExecScript
Action Type: Execute Script
###Parameters:###
Function: [:handler.func]
Command: [:cmd]
Run In Background: [:runBG]

##RULE

##KD Ready - Food [Automation Command Executed] (Rule)##

Rule Name: KD Ready - Food
Event Name: Automation Command Executed
Rule Tags:
Custom Constraint List (1):
Execute Rule if: Matches
Automation Command NameEqualsKD Ready - Food

##Actions (1):##

KD ExecScript

Constraint: (none)

handler.func: tasks.addTask('KD Waiter - Food','','XXXXX READY XXXXX','[:CommandValue]','#55007700','KD Task GUI - Food')
cmd:
runBG:

##NOTES:

This function call:

tasks.addTask('KD Waiter - Food','','XXXXX READY XXXXX','[:CommandValue]','#55007700','KD Task GUI - Food')

Has 6 parameters:

addTask(taskTypeNew,taskName,content,identifier,color,taskTypeOld)

Maps out like this:

taskTypeNew = 'KD Waiter - Food' // our new Task Type for the Waiter Display
taskName    = '' // optional, when left blank, it will use the same taskName as the KD Food Task
content     = 'XXXXX READY XXXXX' // optional, content will be appended to the Order on the Waiter Task Card
identifier  = '[:CommandValue]' // leave this alone, the value is passed as the [Id] for the KD Food Task Widget
color       = '#55007700' // medium Green color
taskTypeOld = 'KD Task GUI - Food' // the original KD Food Task Type (ie. 'FoodDisplayTask')

#DEMO

4 Likes

Thank you for the splendid and detailed responses. I was able to implement this feature and it made SambaPOS all the more valuable to me.

Hi @QMcKay i followed this tutorial too,
but i have an error…
i dont know if this helps…

[General Info]

Application: SambaPOS
Version: 5.1.60
Region: de
DB: SQ
Machine: LAPTOP
User: manue
Date: 25.11.2016
Time: 22:06

User Explanation:

manue said “”

[Exception Info 1]

Top-level Exception
Type: System.Reflection.TargetInvocationException
Message: Ein Aufrufziel hat einen Ausnahmefehler verursacht.
Source: mscorlib
Stack Trace: bei System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
bei System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
bei System.Delegate.DynamicInvokeImpl(Object[] args)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Inner Exception 1
Type: Microsoft.ClearScript.ScriptEngineException
Message: Nicht abgeschlossene Zeichenfolgenkonstante
Source: ClearScript
Stack Trace: bei Microsoft.ClearScript.ScriptEngine.ThrowScriptError(IScriptEngineException scriptError)
bei Microsoft.ClearScript.Windows.WindowsScriptEngine.ThrowScriptError(Exception exception)
bei Microsoft.ClearScript.Windows.WindowsScriptEngine.<>c__DisplayClass51_01.<ScriptInvoke>b__0() bei Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func1 func)
bei Microsoft.ClearScript.Windows.WindowsScriptEngine.ScriptInvoke[T](Func1 func) bei Microsoft.ClearScript.Windows.WindowsScriptEngine.Execute(String documentName, String code, Boolean evaluate, Boolean discard) bei Samba.Services.Implementations.ExpressionModule.ExpressionEngine.Invoke(String expression, String function, Object dataObject, Object[] args) bei Samba.Services.Implementations.ExpressionModule.ExpressionService.InvokeScript(String handlerFunction, Object dataObject) bei System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2) bei Samba.Modules.AutomationModule.ActionProcessors.ExecuteScript.Process(ActionData actionData) bei Samba.Services.Common.RuleActionTypeRegistry.ProcessAction(String actionType, ActionData actionData) bei Samba.Services.Implementations.AutomationModule.AutomationService.ProcessAction(String actionType, ActionData actionData) bei Samba.Modules.AutomationModule.AutomationModule.<OnInitialization>b__5_0(EventParameters1 x)
bei Microsoft.Practices.Prism.Events.EventSubscription1.InvokeAction(Action1 action, TPayload argument)
bei Microsoft.Practices.Prism.Events.EventSubscription1.<>c__DisplayClass2.<GetExecutionStrategy>b__0(Object[] arguments) bei Microsoft.Practices.Prism.Events.EventBase.InternalPublish(Object[] arguments) bei Microsoft.Practices.Prism.Events.CompositePresentationEvent1.Publish(TPayload payload)
bei Samba.Presentation.Services.Common.ExtensionMethods.Publish[TEventsubject](TEventsubject eventArgs, String eventTopic, Action expectedAction)


[Assembly Info]

mscorlib, Version=4.0.0.0
Samba.Services, Version=1.0.0.0
Samba.Domain, Version=1.0.0.0
Samba.Infrastructure.Data, Version=1.0.0.0
System.ComponentModel.Composition, Version=4.0.0.0
System.Core, Version=4.0.0.0
PresentationCore, Version=4.0.0.0
DevExpress.Xpf.LayoutControl.v14.1, Version=14.1.13.0
System.Xml, Version=4.0.0.0
DevExpress.Xpf.Grid.v14.1, Version=14.1.13.0
System, Version=4.0.0.0
DevExpress.Xpf.Grid.v14.1.Core, Version=14.1.13.0
WindowsBase, Version=4.0.0.0
System.Xaml, Version=4.0.0.0
PresentationFramework, Version=4.0.0.0
Samba.Infrastructure, Version=1.0.0.0
Microsoft.Practices.Prism, Version=4.0.0.0
System.Runtime.Serialization, Version=4.0.0.0
Microsoft.Practices.Prism.MefExtensions, Version=4.0.0.0
DevExpress.Xpf.Core.v14.1, Version=14.1.13.0
Samba.Presentation.Services, Version=1.0.0.0
System.Windows.Forms, Version=4.0.0.0
System.Drawing, Version=4.0.0.0
Stateless, Version=1.0.0.0
Samba.Persistance, Version=1.0.0.0
PropertyTools, Version=2012.4.14.1
Samba.Localization, Version=1.0.0.0
ReachFramework, Version=4.0.0.0
EntityFramework, Version=6.0.0.0
FluentValidation, Version=3.4.0.0
Omu.ValueInjecter, Version=2.3.0.0
Microsoft.Practices.ServiceLocation, Version=1.0.0.0
Microsoft.CSharp, Version=4.0.0.0


[System Info]

Operating System
-Microsoft Windows 10 Pro
–CodeSet = 1252
–CSDVersion =
–CurrentTimeZone = -180
–FreePhysicalMemory = 718804
–OSArchitecture = 64-Bit
–OSLanguage = 1031
–ServicePackMajorVersion = 0
–ServicePackMinorVersion = 0
–Version = 10.0.14393

Machine
-LAPTOP
–Manufacturer = HP
–Model = HP 250 G4 Notebook PC
–TotalPhysicalMemory = 4206252032
–UserName = LAPTOP\manue


a little bit is german :slight_smile:

This is something related with script but I can’t read the error message. It probably relates with string concatenation.

Please ensure you correctly copied entire script.

Hi emre,
this is the script i have copied:
function getTaskbyIdentifier(taskType,ident,field) {
// getTaskbyIdentifier(‘KD Task GUI - Food’,‘27751-Qure Burger.Burger-12837-j9tXI2XMRkq7Q446SFfroQ’)
taskType = typeof taskType===‘undefined’ ? ‘’ : taskType;
ident = typeof ident===‘undefined’ ? ‘’ : ident;
field = typeof field===‘undefined’ ? ‘name’ : field;

if (taskType==‘’ || ident==‘’) {
return false;
}

var qry = ‘{task:getTask(taskType:"’+taskType+‘“,identifier:”’+ident+‘"){id,name,identifier,content}}’;
var r = gql.Exec(qry);
r = JSON.parse(r);
var task = r.data.task;

//dlg.ShowMessage(“tt:”+taskType+“\rid:”+ident+“\rname:”+task.name);

return task[field];
}

function addTask(taskType,name,content,ident,color,taskTypeOld) {
// addTask(‘KD Waiter - Food’,‘’,‘blah’,‘27751-Qure Burger.Burger-12837-j9tXI2XMRkq7Q446SFfroQ’,‘#FFFFFF00’)
taskType = typeof taskType===‘undefined’ ? ‘’ : taskType;
taskTypeOld = typeof taskTypeOld===‘undefined’ ? ‘’ : taskTypeOld;
taskTypeOld = taskTypeOld==‘’ ? ‘KD Task GUI - Food’ : taskTypeOld;
ident = typeof ident===‘undefined’ ? ‘’ : ident;
name = typeof name===‘undefined’ || name==‘’ ? getTaskbyIdentifier(taskTypeOld,ident,‘name’) : name;
color = typeof color===‘undefined’ ? ‘’ : color;

var oldContent = getTaskbyIdentifier(taskTypeOld,ident,‘content’);
oldContent = oldContent.replace(/“/g,”‘");
oldContent = oldContent.replace(/\r\n/g,’<!rn>');
content = oldContent + ‘<!rn>’ + content;

//dlg.ShowMessage(“tt:”+taskType+“\rid:”+ident+“\rname:”+name+“\rcontent:”+content);

if (taskType==‘’ || name==‘’) {
return false;
}

var qry=‘mutation m {addTask (task:{taskType:"’+taskType+‘“,name:”’+name+‘“,content:”’+content+‘“,isCompleted:false,identifier:”’+ident+‘“,customData:[{name:“Color”,value:”’+color+‘"}]}){id,name,isCompleted,content,identifier,customData{name,value}}}’;
var r = gql.Exec(qry);
r = JSON.parse(r);
var task = r.data.addTask;

return task.name;
}

function updateTask(taskType,name,ident,color,content) {
// updateTask(‘KD Waiter - Food’,‘’,‘27755-Poutine-12841-swifCxkYVk6UDrmcd0JUmg’,‘#FFFFFF00’)
taskType = typeof taskType===‘undefined’ ? ‘’ : taskType;
ident = typeof ident===‘undefined’ ? ‘’ : ident;
name = typeof name===‘undefined’ || name==‘’ ? getTaskbyIdentifier(taskType,ident,‘name’) : name;
color = typeof color===‘undefined’ ? ‘’ : color;
content = typeof content===‘undefined’ ? ‘’ : content;

//dlg.ShowMessage(“tt:”+taskType+“\rid:”+ident+“\rname:”+name+“\rcontent:”+content);

if (taskType==‘’ || name==‘’) {
return false;
}

var qry=‘mutation m {updateTask (taskType:"’+taskType+‘“,identifier:”’+ident+‘“,task:{taskType:”’+taskType+‘“,isCompleted:false,identifier:”’+ident+‘“,customData:[{name:“Color”,value:”’+color+‘"}]}){id,name,isCompleted,content,identifier,customData{name,value}}}’;
var r = gql.Exec(qry);
r = JSON.parse(r);
var task = r.data.updateTask;

return task.name;
}

I dont know if i understand this part right…

Hi sir i follow this tutorial for waiter screen when we complete the order from kitchen screen it must come on waiter screen but it is not coming sir please help me for this sir

Please show what you have tried. Show your rules and actions etc.

do u want me to show all the rules and actions

Do you know what part is giving you trouble? You can show all of them if you like yes.

sure sir i will give

Start by showing the waiters entity screen and the widget settings.

here is the widget sir


Hi sir here is action and rules and the script also

function getTaskbyIdentifier(taskType,ident,field) {
// getTaskbyIdentifier(‘KD Task GUI - Food’,‘27751-Qure Burger.Burger-12837-j9tXI2XMRkq7Q446SFfroQ’)
taskType = typeof taskType===‘undefined’ ? ‘’ : taskType;
ident = typeof ident===‘undefined’ ? ‘’ : ident;
field = typeof field===‘undefined’ ? ‘name’ : field;

if (taskType==’’ || ident==’’) {
return false;
}

var qry = ‘{task:getTask(taskType:"’+taskType+’",identifier:"’+ident+’"){id,name,identifier,content}}’;
var r = gql.Exec(qry);
r = JSON.parse®;
var task = r.data.task;

//dlg.ShowMessage("tt:"+taskType+"\rid:"+ident+"\rname:"+task.name);

return task[field];
}

function addTask(taskType,name,content,ident,color,taskTypeOld) {
// addTask(‘KD Waiter - Food’,’’,‘blah’,‘27751-Qure Burger.Burger-12837-j9tXI2XMRkq7Q446SFfroQ’,’#FFFFFF00’)
taskType = typeof taskType===‘undefined’ ? ‘’ : taskType;
taskTypeOld = typeof taskTypeOld===‘undefined’ ? ‘’ : taskTypeOld;
taskTypeOld = taskTypeOld==’’ ? ‘KD Task GUI - Food’ : taskTypeOld;
ident = typeof ident===‘undefined’ ? ‘’ : ident;
name = typeof name===‘undefined’ || name==’’ ? getTaskbyIdentifier(taskTypeOld,ident,‘name’) : name;
color = typeof color===‘undefined’ ? ‘’ : color;

var oldContent = getTaskbyIdentifier(taskTypeOld,ident,‘content’);
oldContent = oldContent.replace(/"/g,"’");
oldContent = oldContent.replace(/\r\n/g,’<!rn>’);
content = oldContent + ‘<!rn>’ + content;

//dlg.ShowMessage("tt:"+taskType+"\rid:"+ident+"\rname:"+name+"\rcontent:"+content);

if (taskType==’’ || name==’’) {
return false;
}

var qry=‘mutation m {addTask (task:{taskType:"’+taskType+’",name:"’+name+’",content:"’+content+’",isCompleted:false,identifier:"’+ident+’",customData:[{name:“Color”,value:"’+color+’"}]}){id,name,isCompleted,content,identifier,customData{name,value}}}’;
var r = gql.Exec(qry);
r = JSON.parse®;
var task = r.data.addTask;

return task.name;
}

function updateTask(taskType,name,ident,color,content) {
// updateTask(‘KD Waiter - Food’,’’,‘27755-Poutine-12841-swifCxkYVk6UDrmcd0JUmg’,’#FFFFFF00’)
taskType = typeof taskType===‘undefined’ ? ‘’ : taskType;
ident = typeof ident===‘undefined’ ? ‘’ : ident;
name = typeof name===‘undefined’ || name==’’ ? getTaskbyIdentifier(taskType,ident,‘name’) : name;
color = typeof color===‘undefined’ ? ‘’ : color;
content = typeof content===‘undefined’ ? ‘’ : content;

//dlg.ShowMessage("tt:"+taskType+"\rid:"+ident+"\rname:"+name+"\rcontent:"+content);

if (taskType==’’ || name==’’) {
return false;
}

var qry=‘mutation m {updateTask (taskType:"’+taskType+’",identifier:"’+ident+’",task:{taskType:"’+taskType+’",isCompleted:false,identifier:"’+ident+’",customData:[{name:“Color”,value:"’+color+’"}]}){id,name,isCompleted,content,identifier,customData{name,value}}}’;
var r = gql.Exec(qry);
r = JSON.parse®;
var task = r.data.updateTask;

return task.name;
}






You have several mistakes that I can seee right off the bat for example Task complete commands you have a less than sign? What did you expect that to do? Also in your template you have [Content] I am fairly sure that is not accurate as well.

ok sir can u help me how to do this please