[New 4.1.78] Mandatory Portion Selection (and a contest for fun)

I’ve created a printer template tag that returns portion buttons for an order. As a convention if a printer template tag contains Button keyword in it that will produce a result that can be used with Ask Question action.

###New tags

{PORTION COUNT}: Returns portion count of an order.
{PORTION BUTTONS}:Returns button list for portions of an order.

By using these two tags we can implement a portion selection screen when an order that have multiple portions added to ticket.

###Implementation

This action changes portion of an order.

This action displays a button dialog. We’ll use {PORTION BUTTONS} tag as Buttons Parameter. When we click a button this action will execute Update Order Button automation command with selected portion name as command value. On next step we’ll create a rule that handles this command and updates portion.

This rule handles Update Order Portion command and executes MO_Update Order Portion action with [:CommandValue]. As we’ve configured in Ask Question action [:CommandValue] is selected Portion Name.

Finally we’ll execute Ask Question action when a new order is added to ticket.

I’ve used {PORTION COUNT} as a constraint so Ask Order Portion will execute if order have more than 1 portion.

###How it works

I’ve configured these portions for Coffee.

SambaPOS asks portion when coffee added.

###Further improvement

You can improve that by adding these two features.

  • Improve Ask Question action to display product name in question. For example make button dialog to display Select Portion for Coffee.
  • Improve Order Added rule to ask portion for selected products. Create a custom product tag as Ask Portion and ask portion if Ask Portion feature is enabled for that product.

###Share your solution
Post your improvement solution here with screen shots. The first solution that receives more than 5 likes will receive a samba market module of his/her choice for free.

9 Likes

Great feature @emre. I love it. I’ll be putting this into production quickly!

P.S. Let’s go guys! I want to see the improved solution!

1 Like

Waited long enough, methinks…

Define Custom Product Tag Caption called PortionMandatory to flag Items that require a Portion Selection:

Use Product Tag Editor to mark Items that require a Portion Selection:

Action - Ask Question using parameters which we will set in the Rule:

Action - Update Order:

Rule - Order Added, fire Ask Question:

Rule Constraints:
Execute Rule if Matches
{PORTION COUNT} Greater 1
{ITEM TAG:PortionMandatory} Greater 0

Question: Select a Portion for\r{NAME}
Buttons: {PORTION BUTTONS}
AMCname: AM MP Update Order Portion

Rule - Automation Command Executed, fire Update Order:

6 Likes

@emre Mandatory Portion Is Genius and implemented , Pls anybody can guide Mandatory Department before each new order starts this will solve my problem thanks emreen for u r support all times

Failed for me in both ways :expressionless:
It seens to need a automation command that is not mentioned in both ways.

Remember to add mappings to rules.

i added to both, a global mapping

Double and tripple check for typo’s a single character or capitalization can mess it up sometimes.

1 Like

I did, got a error on emre’s way:

sended it trough reporter

Click Detailed Report tab and press copy then paste it in the forum so we can see it. After you paste it highlight it and press the </> button

Be sure that the items you designated all have portions defined.

1 Like

An Automation Command Button is not required to raise the Rule Event called Automation Command Executed. In both of these examples, the Ask Question Action fires the Automation Command.

Ensure that you have exactly the same name for AMCname in the Ask Question Action as you have for the Constraint for the Rule that handles the Automation Command Executed Event.

1 Like

Ok, Im gonna re-create everything

I can pretty much guarantee that the detail of that report is “invalid token”. This refers to the BGcolor of the Ask Question Action. You must supply a valid value. Use something like Red, Green, Blue, etc.

2 Likes

Got the same error after changing BGcolor of ask question action
strange is that it seens to give more portions that i have. I have 6 Portions for the clicked product, and this comes up:


the 00 00 00 50 50 portions are not portions created by me


[General Info]

Application: SambaPOS
Version:     4.1.82
Region:      en
DB:          SQ
Machine:     STEELE-PC
User:        Free
Date:        08/04/2015
Time:        16:44

User Explanation:

Free said ""
-----------------------------

[Exception Info 1]

Top-level Exception
Type:        System.Reflection.TargetInvocationException
Message:     Exception has been thrown by the target of an invocation.
Source:      mscorlib
Stack Trace: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at Samba.Presentation.App.Main()

Inner Exception 1
Type:        System.Reflection.TargetInvocationException
Message:     Exception has been thrown by the target of an invocation.
Source:      mscorlib
Stack Trace: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at Samba.Presentation.Services.Common.ExtensionMethods.PublishEvent[TEventsubject](TEventsubject eventArgs, String eventTopic, Boolean wait)
   at Samba.Presentation.Common.Services.ApplicationState.<NotifyEvent>b__9(ActionData x)
   at Samba.Services.Implementations.AutomationModule.ActionDataBuilder.InvokeFor(Action`1 dataAction)
   at CallSite.Target(Closure , CallSite , Object , Action`1 )
   at Samba.Services.Implementations.AutomationModule.RuleExecutor.ExecuteWith(Object dataParameter, Action`1 dataAction)
   at Samba.Services.Implementations.AutomationModule.NotificationService.NotifyEvent(String eventName, Object dataParameter, Int32 terminalId, Int32 departmentId, Int32 userRoleId, Int32 ticketTypeId, Action`1 dataAction)
   at Samba.Presentation.Common.Services.ApplicationState.NotifyEvent(String eventName, Object dataObject)
   at Samba.Presentation.Services.Implementations.TicketModule.TicketService.AddOrder(Ticket ticket, Int32 menuItemId, Nullable`1 quantity, String portionName, String orderState)
   at Samba.Modules.PosModule.TicketOrdersViewModel.AddOrder(Int32 menuItemId, Nullable`1 quantity, String portionName)
   at Samba.Modules.PosModule.TicketOrdersViewModel.AddOrder(ScreenMenuItemData data)
   at Samba.Modules.PosModule.PosViewModel.OnMenuItemSelected(EventParameters`1 obj)
   at Microsoft.Practices.Prism.Events.EventSubscription`1.InvokeAction(Action`1 action, TPayload argument)
   at Microsoft.Practices.Prism.Events.EventSubscription`1.<>c__DisplayClass2.<GetExecutionStrategy>b__0(Object[] arguments)
   at Microsoft.Practices.Prism.Events.EventBase.InternalPublish(Object[] arguments)
   at Microsoft.Practices.Prism.Events.CompositePresentationEvent`1.Publish(TPayload payload)
   at Samba.Presentation.Services.Common.ExtensionMethods.Publish[TEventsubject](TEventsubject eventArgs, String eventTopic, Action expectedAction)

Inner Exception 2
Type:        System.Reflection.TargetInvocationException
Message:     Exception has been thrown by the target of an invocation.
Source:      mscorlib
Stack Trace: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at Samba.Presentation.Services.Common.ExtensionMethods.PublishEvent[TEventsubject](TEventsubject eventArgs, String eventTopic, Boolean wait)
   at Samba.Presentation.Common.Services.ApplicationState.<NotifyEvent>b__9(ActionData x)
   at Samba.Services.Implementations.AutomationModule.ActionDataBuilder.InvokeFor(Action`1 dataAction)
   at CallSite.Target(Closure , CallSite , Object , Action`1 )
   at Samba.Services.Implementations.AutomationModule.RuleExecutor.ExecuteWith(Object dataParameter, Action`1 dataAction)
   at Samba.Services.Implementations.AutomationModule.NotificationService.NotifyEvent(String eventName, Object dataParameter, Int32 terminalId, Int32 departmentId, Int32 userRoleId, Int32 ticketTypeId, Action`1 dataAction)
   at Samba.Presentation.Common.Services.ApplicationState.NotifyEvent(String eventName, Object dataObject)
   at CallSite.Target(Closure , CallSite , IApplicationState , String , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   at Samba.Presentation.Controls.ActionProcessors.AskQuestion.Process(ActionData actionData)
   at Samba.Services.Common.RuleActionTypeRegistry.ProcessAction(String actionType, ActionData actionData)
   at Samba.Services.Implementations.AutomationModule.AutomationService.ProcessAction(String actionType, ActionData actionData)
   at Samba.Modules.AutomationModule.AutomationModule.<OnInitialization>b__4(EventParameters`1 x)
   at Microsoft.Practices.Prism.Events.EventSubscription`1.InvokeAction(Action`1 action, TPayload argument)
   at Microsoft.Practices.Prism.Events.EventSubscription`1.<>c__DisplayClass2.<GetExecutionStrategy>b__0(Object[] arguments)
   at Microsoft.Practices.Prism.Events.EventBase.InternalPublish(Object[] arguments)
   at Microsoft.Practices.Prism.Events.CompositePresentationEvent`1.Publish(TPayload payload)
   at Samba.Presentation.Services.Common.ExtensionMethods.Publish[TEventsubject](TEventsubject eventArgs, String eventTopic, Action expectedAction)

Inner Exception 3
Type:        System.NullReferenceException
Message:     Object reference not set to an instance of an object.
Source:      Samba.Domain
Stack Trace: at Samba.Domain.Models.Tickets.Order.UpdatePortion(MenuItemPortion portion, String priceTag, IEnumerable`1 taxTemplates)
   at Samba.Presentation.Services.Implementations.TicketModule.TicketService.UpdateOrderPrice(Order order, String portionName, String priceTag)
   at Samba.Modules.TicketModule.ActionProcessors.UpdateOrder.Process(ActionData actionData)
   at Samba.Services.Common.RuleActionTypeRegistry.ProcessAction(String actionType, ActionData actionData)
   at Samba.Services.Implementations.AutomationModule.AutomationService.ProcessAction(String actionType, ActionData actionData)
   at Samba.Modules.AutomationModule.AutomationModule.<OnInitialization>b__4(EventParameters`1 x)
   at Microsoft.Practices.Prism.Events.EventSubscription`1.InvokeAction(Action`1 action, TPayload argument)
   at Microsoft.Practices.Prism.Events.EventSubscription`1.<>c__DisplayClass2.<GetExecutionStrategy>b__0(Object[] arguments)
   at Microsoft.Practices.Prism.Events.EventBase.InternalPublish(Object[] arguments)
   at Microsoft.Practices.Prism.Events.CompositePresentationEvent`1.Publish(TPayload payload)
   at Samba.Presentation.Services.Common.ExtensionMethods.Publish[TEventsubject](TEventsubject eventArgs, String eventTopic, Action expectedAction)

-----------------------------

[Assembly Info]

Samba.Services, Version=1.0.0.0
mscorlib, Version=4.0.0.0
System, Version=4.0.0.0
Microsoft.Practices.Prism, Version=4.0.0.0
WindowsBase, Version=4.0.0.0
Samba.Infrastructure, Version=1.0.0.0
Samba.Infrastructure.Data, Version=1.0.0.0
PresentationFramework, Version=4.0.0.0
System.Xaml, Version=4.0.0.0
Samba.Presentation.Services, Version=1.0.0.0
FluentValidation, Version=3.4.0.0
Samba.Domain, Version=1.0.0.0
DevExpress.Xpf.Grid.v14.1, Version=14.1.6.0
DevExpress.Xpf.Grid.v14.1.Core, Version=14.1.6.0
PresentationCore, Version=4.0.0.0
Stateless, Version=1.0.0.0
System.Core, Version=4.0.0.0
System.Drawing, Version=4.0.0.0
DevExpress.Xpf.Core.v14.1, Version=14.1.6.0
EntityFramework, Version=4.4.0.0
System.Windows.Forms, Version=4.0.0.0
System.ComponentModel.Composition, Version=4.0.0.0
Samba.Localization, Version=1.0.0.0
Microsoft.CSharp, Version=4.0.0.0
Microsoft.Practices.ServiceLocation, Version=1.0.0.0
Samba.Persistance, Version=1.0.0.0
Microsoft.Practices.Prism.MefExtensions, Version=4.0.0.0
PropertyTools, Version=2012.4.14.1

-----------------------------

[System Info]

Operating System
-Microsoft Windows 8.1 Pro
--CodeSet = 1252
--CSDVersion = 
--CurrentTimeZone = -180
--FreePhysicalMemory = 1463644
--OSArchitecture = 64-bit
--OSLanguage = 1033
--ServicePackMajorVersion = 0
--ServicePackMinorVersion = 0
--Version = 6.3.9600

Machine
-STEELE-PC
--Manufacturer = INTEL_
--Model = DH57DD__
--TotalPhysicalMemory = 4150317056
--UserName = Steele-PC\Free

-----------------------------

Show the product with defined portions?

Show your actions you made from the tutorial? Its crashing on Update Portion.

sure,


Now show your rules?

EDIT: Wait it has to do with a tax template.

Rules: