Remove item when answering no to question

When adding first bar item to ticket my message box appears, when clicking “YES/ID Verified” button item is added to ticket and sale can continue. However when i click “NO ID Cancel Sale” button i dont want the item to be added to the ticket (or if it is added to automatically remove it) so i can then cancel the sale. I cant find or create an action that will automatically remove the item from the ticket when pressing the NO button. Ideally when clicking the NO button i want the order to automatically cancel, then the built in autologout feature to kick in and log the user out

Any ideas?

my rule for when NO is pressed is as follows, and ive tried various combinations of actions after the two shown but nothing seems to work

Did you tried cancel order action?

i just added cancel order to my NO rule and i got this error


[General Info]

Application: SambaPOS
Version: 4.1.58
Region: en
DB: SQ
Machine: RICKS-LAPTOP
User: Rick
Date: 20/09/2014
Time: 23:52

User Explanation:

Rick 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.b__7(ActionData x)
at Samba.Services.Implementations.AutomationModule.ActionDataBuilder.InvokeFor(Action1 dataAction) at CallSite.Target(Closure , CallSite , Object , Action1 )
at Samba.Services.Implementations.AutomationModule.RuleExecutor.ExecuteWith(Object dataParameter, Action1 dataAction) at Samba.Services.Implementations.AutomationModule.NotificationService.NotifyEvent(String eventName, Object dataParameter, Int32 terminalId, Int32 departmentId, Int32 userRoleId, Int32 ticketTypeId, Action1 dataAction)
at Samba.Presentation.Common.Services.ApplicationState.NotifyEvent(String eventName, Object dataObject)
at Samba.Presentation.Services.Implementations.TicketModule.TicketService.CreateTicket()
at Samba.Presentation.Services.Implementations.TicketModule.TicketService.OpenTicket(Int32 ticketId)
at Samba.Modules.PosModule.PosViewModel.OpenTicket(Int32 id)
at Samba.Modules.PosModule.PosViewModel.OnMenuItemSelected(EventParameters1 obj) at Microsoft.Practices.Prism.Events.EventSubscription1.InvokeAction(Action1 action, TPayload argument) at Microsoft.Practices.Prism.Events.EventSubscription1.<>c__DisplayClass2.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.b__7(ActionData x)
at Samba.Services.Implementations.AutomationModule.ActionDataBuilder.InvokeFor(Action1 dataAction) at CallSite.Target(Closure , CallSite , Object , Action1 )
at Samba.Services.Implementations.AutomationModule.RuleExecutor.ExecuteWith(Object dataParameter, Action1 dataAction) at Samba.Services.Implementations.AutomationModule.NotificationService.NotifyEvent(String eventName, Object dataParameter, Int32 terminalId, Int32 departmentId, Int32 userRoleId, Int32 ticketTypeId, Action1 dataAction)
at Samba.Presentation.Common.Services.ApplicationState.NotifyEvent(String eventName, Object dataObject)
at CallSite.Target(Closure , CallSite , IApplicationState , String , Object )
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.b__2(EventParameters1 x) at Microsoft.Practices.Prism.Events.EventSubscription1.InvokeAction(Action1 action, TPayload argument) at Microsoft.Practices.Prism.Events.EventSubscription1.<>c__DisplayClass2.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.Modules.TicketModule
Stack Trace: at Samba.Modules.TicketModule.ActionProcessors.CancelOrders.b__0(Order x)
at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func2 predicate)
at Samba.Modules.TicketModule.ActionProcessors.CancelOrders.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.b__2(EventParameters1 x) at Microsoft.Practices.Prism.Events.EventSubscription1.InvokeAction(Action1 action, TPayload argument) at Microsoft.Practices.Prism.Events.EventSubscription1.<>c__DisplayClass2.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.5.0
DevExpress.Xpf.Grid.v14.1.Core, Version=14.1.5.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
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
DevExpress.Xpf.Core.v14.1, Version=14.1.5.0
PropertyTools, Version=2012.4.14.1


[System Info]

Operating System
-Microsoft Windows 8.1 Pro
–CodeSet = 1252
–CSDVersion =
–CurrentTimeZone = 60
–FreePhysicalMemory = 1738028
–OSArchitecture = 64-bit
–OSLanguage = 2057
–ServicePackMajorVersion = 0
–ServicePackMinorVersion = 0
–Version = 6.3.9600

Machine
-RICKS-LAPTOP
–Manufacturer = Hewlett-Packard
–Model = HP 650 Notebook PC
–TotalPhysicalMemory = 4176769024
–UserName = RICKS-LAPTOP\Rick


EDIT: this error happens when “Only Last Order” is set to true, if it i set it to false nothing happens the item is still added to the ticket and the sale can still be processed when i want it to cancel

Well sorry I missed you are doing it with “Order Added” event. So you want to remove order while SambaPOS trying to add the order :slight_smile: Great issue.

Do you display it when a drink added?

i probably didnt explain it very well, when adding the first age restricted bar item the cashier is prompted to check for ID, if the customer is of age the YES button of the message banner is clicked and the sale proceeds as normal and ticket tags are added to the ticket to say proof of age was verified

when the NO button is clicked, if customer is clearly under age or has no ID ticket tags are added to the ticket to say that NO ID was presented by the customer and that the order was cancelled. This all works fine, my next step is that when the NO button is presssed i want the ticket tags to add like they do but then i want the item that was originally being added to then be removed from the ticket and the cashier autologged out so this customer cannot be served. Cashier can then log back in to serve next customer

NO ID button selected

What does (should) happen when we add that age restricted order “After” adding a non restricted order?

I dont have separate age restricted and non age restricted items, its basically a check on any alcohol that is sold and the message only appears when an alcohol category item is selected so if someone under age tries to buy alcohol the ticket tags log the sale was cancelled (for trading standards evidence that ID is checked and sale are refused) i just then need the ticket to cancel the items off it and then log out

Let me understand one more thing. You can also display it when ticket first created. Did you preferred to do it when order added as you need to do it like that?

yes i prefer it only when order added as it only applies to alcohol so if the sale only has soft drinks or bar snacks i dont need the message to pop up

EDIT: however the message still shows when i non alcoholic category is selected, how to i ensure it on shows when an alcoholic category is selected? do i have to set a contraint somewhere with the categories i only want it to appear?

I know my English is not very good :slight_smile: but I want to be ensure if you have separate age restricted items or not. What I mean here

  • Beer > Age Restricted.
  • Water > Not Age Restricted.

So what I’m asking here what SambaPOS supposed to do when you add beer after adding water.

When I add Water > Does Nothing.
When I add Beer > Displays Popup.
When I select No > Cancel whole ticket or cancel just beer?

Yes, sorry ive probably not explain very well

Add water > i want it to do nothing (but at the moment the message still pops up)
Add beer > i want it to display message (which it does, but it does it for every item and not just for the ones i want it to)

When select no it would be good to just cancel the beer and leave the other items and complete sale (i hadnt thought of that i just thought of cancelling whole sale and starting again). I would in this case then need another message to appear to either just cancel last item added (the beer they cant have) or cancel whole ticket if customer then decides they dont want anything

More than likely it works like in the USA from talking to him. It does nothing if no age restricted items are added to ticket… when the first age restricted item is added it displays the popup and it reacts accordingly if No is pressed it simply does not add the item if Yes is pressed it adds the item with the ticket tag… Now we procede through the rest of the ticket adding age restricted or non age restricted items but if any extra AGE restricted items are added it does not prompt again as it has already been established they are of age. BUT if the first age restricted item the answer was NO… then it should display popup if another age restricted item is attempted to be added.

Is that accurate @RickH

it sounds like he needs a good order state flow for this and can use ticket state instead of ticket tag for designating it as an alcohol ticket after first age restricted item is added.

The popup can check for the ticket state.

yes thats it :smile:
i have the tickets tags on so that it records on the ticket that ID was checked and verified OR ID could not be checked or customer looked under age so there is a log that an age restricted item was refused to a customer on the ticket.

So if trading standards want to check anything i can pull up the tickets to show they were “aborted” and the tickets tags show on the ticket to show the cashier pressed the NO ID option on the message pop up

EDIT: sounds like you have a better setup for this?

oh ok I understood how it should flow. It seems we may need few additions so let me prepare a POC tomorrow. I’ll let you know how we should configure it.

Brill, thanks a lot for both of your help, as always greatly appreciated!! :slight_smile:

I dont really have a better setup but just thinking about it I have an idea. instead of making a bunch of aborted tickets you probably need something that just logs when you reject a sale. Maybe this is something @emre can design for you. I would be interested in it as well as I could use it for some things ive been thinking about.

Emre probably has better idea tho :stuck_out_tongue: He has inside knowledge hahah

Well wait… Should we store unconfirmed tickets? This is something different.

having a log for rejected sales would be good, but if there are a mixture of restricted and non restricted on the ticket we would just the the rejected restricted items logged and the rest of the ticket could proceed as normal

I really do not see any reason to store entire tickets. Really just a way to log ID checks that were rejected with a timestamp. So maybe just a way to store a specific value with timestamp that can be pulled up in a report.

yes that would be good, and if it could log the items that were rejected too even better!