Ejemplo n.º 1
0
        /// <summary>
        /// информация о состоянии смены
        /// </summary>
        /// <param name="StageStateString"></param>
        private static void CashDesk_StageStateReceived(StageProperties StageState)
        {
            try
            {
                //SystemState.KKTStageOpened = (StageState.CurrentStageState == StageProperties.StageState.Opened);
                StartPage.SystemState.KKTStageOver24h            = (StageState.CurrentStageState == StageProperties.StageState.Over24h);
                StartPage.SystemState.LastStageClosedDateTime    = Convert.ToInt64(StageState.StageClosedDateTime.ToString("yyyyMMddHHmmss"));
                StartPage.SystemState.LastStageClosedDateTimeStr = StageState.StageClosedDateTime.ToString("dd.MM.yyyy HH:mm:ss");
                if (StartPage.CurrentState != StartPage.States.Init && StartPage.CurrentState != StartPage.States.OutOfService && StartPage.CurrentState != StartPage.States.ServiceMode && StartPage.SystemState.KKTStageOver24h)
                {
                    StartPage.CurrentState = StartPage.States.OutOfService;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    MDB.DisableCashDevicesAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        var frame = Window.Current.Content as Frame;
                        frame.Navigate(typeof(OutOfServicePage));
                    });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    StartPage.AddItemToLogBox("Длительность смены превысила 24ч, устройство переведено в режим \"Не обслуживает\"");
                }
            }
            catch
            {
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Второй этап запуска - стартуем асинхронные задачи
        /// </summary>
        /// <returns></returns>
        private void RunAfterInit()
        {
            if (CurrentDeviceSettings.UseKKT)
            {
                CashDeskHelper.CashDesk_Init();
            }
            MDB.ConnectMDBSerialPort(CashDeskDeviceID);
            I2c_Init();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            ServiceTasks.UpdateWaterCounter(0);
            ServiceTasks.UpdateCashCounter(0, 0, 0, 0);
#pragma warning restore CS4014             // Because this call is not awaited, execution of the current method continues before the call is completed
            AddItemToLogBox("Управляющее устройство успешно инициализировано, продолжаем...");
            int initdelaymillisec = 10000; //подождем немного, винде нужно время, чтобы выделить память, отсвопиться своим гавном
                                           //на SD-карту и успокоиться.
            while (initdelaymillisec > 0)
            {
                AddItemToLogBox("Ожидание запуска задач " + (initdelaymillisec / 1000).ToString() + "с...");
                int count = 0;
                while (count < 100)
                {
                    Task.Delay(100).Wait();
                    count++;
                }
                initdelaymillisec -= 10000;
            }
            //Task.Run(CCC, GlobalCancellationTokenSource.Token);
            ServiceTasks.StartAll();
            AddItemToLogBox("Задачи запущены");
            Task.Run(MDBHelper.Init_MDB);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Критическая ошибка устройств приема наличных
        /// </summary>
        /// <param name="ErrorMessage"></param>
        private static void CashDevices_MDBError(string ErrorMessage)
        {
            if ((StartPage.CurrentState == StartPage.States.ReadyToServe) || (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater) || (StartPage.CurrentState == StartPage.States.DispenseChange))
            {
                StartPage.CurrentState = StartPage.States.OutOfService;
                MDB.MDBInitStep        = 6;
                MDB.DisableCashDevices();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    var frame = Window.Current.Content as Frame;
                    frame.Navigate(typeof(OutOfServicePage));
                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                StartPage.AddItemToLogBox("Устройства приема наличных принудительно отключены из-за ошибки.");
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// MDB устройства включены
 /// </summary>
 private static void CashDevices_MDBStarted()
 {
     Task.Run(() =>
     {
         StartPage.UpdateProgress(10);
         StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Green);
         StartPage.AddItemToLogBox("Найден адаптер MDB-RS232");
         int count = 0;
         while (count < 10)
         {
             Task.Delay(100).Wait();
             count++;
         }
         MDB.MDBInitStep = 1;
         MDB.ResetCashDevices();
     });
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Прибавляет 50мл к счетчику отгруженной водички
        /// </summary>
        /// <returns></returns>
        public static void WaterCounterTicked()
        {
            if (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater || StartPage.CurrentState == StartPage.States.ServiceMode)
            {
                watercountertickerSemaphore.Wait();
                if (!(StartPage.CurrentState == StartPage.States.ReadyToDispenseWater || StartPage.CurrentState == StartPage.States.ServiceMode))
                {
                    watercountertickerSemaphore.Release();
                    return;
                }
                StartPage.WaterFlowPulseCounter++;
                if (StartPage.WaterFlowPulseCounter >= 17)//50ml dispensed
                {
                    StartPage.WaterFlowPulseCounter = 0;
                    if (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater)
                    {
                        StartPage.UserDeposit -= Math.Round(StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE * 0.0005, 2);
                        StartPage.CurrentSaleSession.Quantity += 0.05;
                        if (Math.Round(StartPage.CurrentSaleSession.UserCash, 2) <= Math.Round(StartPage.CurrentSaleSession.Quantity * StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE * 0.01, 2))
                        {
                            StartPage.CurrentState = StartPage.States.DispenseChange;
                            StartPage.WaterValvePin.Write(GpioPinValue.High);
                            StartPage.PumpPin.Write(GpioPinValue.High);
                            StartPage.StartLEDPin.Write(GpioPinValue.High);
                            StartPage.StopLEDPin.Write(GpioPinValue.High);
                            StartPage.EndLEDPin.Write(GpioPinValue.High);
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            MDB.DisableCashDevicesAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                var frame = Window.Current.Content as Frame;
                                frame.Navigate(typeof(ChangePage));
                            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        }
                    }
                }
                watercountertickerSemaphore.Release();
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// MDB устройства включены
        /// </summary>
        private static void CashDevices_MDBStarted()
        {
            Task.Run(() =>
            {
                StartPage.UpdateProgress(15);
                StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBLED, Colors.Green);
                StartPage.UpdateStartLEDs(StartPage.StartPageInstance.UART0LED, Colors.Green);
                StartPage.AddItemToLogBox("Найден адаптер MDB-RS232");
                int count = 0;
                while (count < 10)
                {
                    Task.Delay(100).Wait();
                    count++;
                }
                MDBInitStep = 1;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                MDB.ResetCashDevicesAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            });
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Критическая ошибка устройств приема наличных
        /// </summary>
        /// <param name="ErrorMessage"></param>
        private static void CashDevices_MDBError(string ErrorMessage)
        {
            if ((StartPage.CurrentState == StartPage.States.ReadyToServe) || (StartPage.CurrentState == StartPage.States.ReadyToDispenseWater) || (StartPage.CurrentState == StartPage.States.DispenseChange))
            {
                ChangePage.ChangeModeSemaphore.Wait();    //надо убедиться, что выдача сдачи так или иначе завершена и сессия продажи закрыта
                ChangePage.ChangeModeSemaphore.Release(); //удерживать флаг эксклюзивного доступа ни к чему, освобождаем
                StartPage.CurrentState = StartPage.States.OutOfService;
                MDBInitStep            = 6;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                MDB.DisableCashDevicesAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    var frame = Window.Current.Content as Frame;
                    frame.Navigate(typeof(OutOfServicePage));
                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                StartPage.AddItemToLogBox("Устройства приема наличных принудительно отключены из-за ошибки.");
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// произведен сброс купюроприемника
        /// </summary>
        private static void CashDevices_MDBBAReseted()
        {
            Task.Run(() =>
            {
                Mutex m2 = new Mutex(true, "MDBDeviceResetHandlerMutex", out bool mutexWasCreated);
                if (!mutexWasCreated)
                {
                    try
                    {
                        m2.WaitOne();
                    }
                    catch (AbandonedMutexException)
                    {
                    }
                }
                try
                {
                    if ((!StartPage.bareset) && (MDB.MDBInitStep == 3 || MDB.MDBInitStep == 4))
                    {
                        MDB.MDBInitStep++;
                        StartPage.UpdateProgress(5);
                        StartPage.bareset = true;
                        StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBBALED, Colors.Green);
                        StartPage.AddItemToLogBox("Купюроприемник готов к работе");
                        if (StartPage.ccreset)
                        {
                            string oosfilename     = ApplicationData.Current.LocalFolder.Path + "\\" + GlobalVars.HardWareID + ".031";
                            StartPage.CurrentState = StartPage.States.OutOfService;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                var frame = Window.Current.Content as Frame;
                                frame.Navigate(typeof(OutOfServicePage));
                            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            StartPage.AddItemToLogBox("Ожидание полной инициализации...");
                            int count = 0;
                            while (count < 100)
                            {
                                Task.Delay(100).Wait();
                                count++;
                            }
                            MDB.MDBInitStep = 5;
                            StartPage.AddItemToLogBox("Устройства приема наличных обнаружены и настроены");
                        }
                    }
                    if ((!StartPage.bainit) && (MDB.MDBInitStep == 1 || MDB.MDBInitStep == 2))
                    {
                        MDB.MDBInitStep++;
                        StartPage.UpdateProgress(5);
                        StartPage.bainit = true;
                        StartPage.UpdateStartLEDs(StartPage.StartPageInstance.MDBBALED, Colors.Yellow);
                        StartPage.AddItemToLogBox("Купюроприемник инициализирован");
                        StartPage.UpdateProgress(5);
                        int count = 0;
                        while (count < 20)
                        {
                            Task.Delay(100).Wait();
                            count++;
                        }
                        MDB.ResetBA();
                    }
                }
                catch (Exception ex)
                {
                    StartPage.AddItemToLogBox("Ошибка: " + ex.Message);
                }
                finally
                {
                }
                m2.ReleaseMutex();
                m2.Dispose();
            });
        }
Ejemplo n.º 9
0
        /// <summary>
        /// выдаем сдачу пока депозит не станет равен 0
        /// </summary>
        private void DispenseChange()
        {
            ChangeModeSemaphore.Wait();
            if (StartPage.CurrentState != StartPage.States.DispenseChange)
            {
                ChangeModeSemaphore.Release();
                return;
            }
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                dispenselabel.Text = Math.Round(StartPage.UserDeposit, 0, MidpointRounding.AwayFromZero).ToString().PadLeft(3, '0');
            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            if (StartPage.CurrentDeviceSettings.UseKKT && Math.Round(StartPage.CurrentSaleSession.Quantity, 3) > 0)
            {
                try
                {
                    StartPage.CurrentSaleSession.ReceiptNumber  = StartPage.SystemState.KKTReceiptNextNumber;
                    StartPage.CurrentSaleSession.StageNumber    = Convert.ToInt16(StartPage.SystemState.KKTStageNumber);
                    StartPage.CurrentSaleSession.TaxSystemInUse = StartPage.CurrentDeviceSettings.TaxSystem;
                    if (Math.Round(StartPage.UserDeposit, 2, MidpointRounding.AwayFromZero) == 0)
                    {
                        CashDesk.PrintReceipt(GlobalVars.ReceiptLinesToPrint, (((int)(Math.Round(StartPage.CurrentSaleSession.UserCash, 2) * 100)) * 1.00 / StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE),
                                              StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE, (int)(Math.Round(StartPage.CurrentSaleSession.UserCash, 2) * 100));
                    }
                    else
                    {
                        CashDesk.PrintReceipt(GlobalVars.ReceiptLinesToPrint, Math.Round(StartPage.CurrentSaleSession.Quantity, 3), StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE,
                                              (int)(Math.Round(StartPage.CurrentSaleSession.UserCash, 2) * 100));
                    }
                }
                catch
                {
                }
            }
            Task.Delay(15000).Wait();
            try
            {
                CashDesk.GetCurrentStageParameters();
                StartPage.CurrentSaleSession.ActualChangeDispensed = (int)Math.Round(StartPage.UserDeposit, 0, MidpointRounding.AwayFromZero);
                StartPage.CurrentSaleSession.ChangeActualDiff      = StartPage.CurrentSaleSession.ActualChangeDispensed - StartPage.UserDeposit;
                StartPage.CurrentSaleSession.CompleteSession();
                ServiceTasks.UpdateWaterCounter(StartPage.CurrentSaleSession.Quantity);
                StartPage.UserDeposit = Math.Round(StartPage.UserDeposit, 0, MidpointRounding.AwayFromZero);
                while ((int)StartPage.UserDeposit > 0)
                {
                    while (MDB.DispenseInProgress || MDB.CheckDispenseResult)
                    {
                        Task.Delay(1000).Wait();
                    }
                    int _change = (int)StartPage.UserDeposit;
                    if (_change > 127)//не более 127 рублей в одной порции сдачи, ограничение монетоприемника
                    {
                        _change = 127;
                    }
                    MDB.Dispensetimeout = DateTime.Now.AddSeconds(10);
                    MDB.PayoutCoins(_change);//выдаем сдачу монетами
                    StartPage.UserDeposit -= _change;
                    Task.Delay(2000).Wait();
                }
                string oosfilename = ApplicationData.Current.LocalFolder.Path + "\\" + GlobalVars.HardWareID + ".031";
                if (File.Exists(oosfilename))
                {
                    StartPage.CurrentState = StartPage.States.OutOfService;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        var frame = Window.Current.Content as Frame;
                        frame.Navigate(typeof(OutOfServicePage));
                    });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    return;
                }
                StartPage.CurrentState = StartPage.States.ReadyToServe;
                MDB.EnableCashDevices();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    var frame = Window.Current.Content as Frame;
                    frame.Navigate(typeof(MainPage));
                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
            catch
            {
            }
            ChangeModeSemaphore.Release();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Нажата кнопка Сдача
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void EndButtonPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args)
        {
            if (args.Edge == GpioPinEdge.RisingEdge)
            {
                try
                {
                    switch (CurrentState)
                    {
                    case States.ReadyToDispenseWater:
                    {
                        CurrentState = States.DispenseChange;
                        MDB.DisableCashDevices();
                        WaterValvePin.Write(GpioPinValue.High);
                        PumpPin.Write(GpioPinValue.High);
                        StartLEDPin.Write(GpioPinValue.High);
                        StopLEDPin.Write(GpioPinValue.High);
                        EndLEDPin.Write(GpioPinValue.High);
                        ReadyToStartPage.ChangeWaterValveStatus(false);
                        AddItemToLogBox("Сеанс продажи закончен по инициативе покупателя (нажата кнопка \"Конец\"), остаток " + UserDeposit.ToString("N2") + ", выдаем сдачу в размере " + Math.Round(UserDeposit, MidpointRounding.AwayFromZero).ToString("N2"));
                        AddItemToLogBox("Выдача сдачи");
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                var frame2 = Window.Current.Content as Frame;
                                frame2.Navigate(typeof(ChangePage));
                            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        while (ChangePage.ChangePageInstance == null)
                        {
                            Task.Delay(100).Wait();
                        }
                        break;
                    }

                    case States.ServiceMode:
                    {
                        WaterValvePin.Write(GpioPinValue.High);
                        PumpPin.Write(GpioPinValue.High);
                        StartLEDPin.Write(GpioPinValue.High);
                        StopLEDPin.Write(GpioPinValue.High);
                        EndLEDPin.Write(GpioPinValue.High);
                        ReadyToStartPage.ChangeWaterValveStatus(false);
                        string oosfilename = ApplicationData.Current.LocalFolder.Path + "\\" + GlobalVars.HardWareID + ".031";
                        if (File.Exists(oosfilename))
                        {
                            CurrentState = States.OutOfService;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                {
                                    var frame = Window.Current.Content as Frame;
                                    frame.Navigate(typeof(OutOfServicePage));
                                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            AddItemToLogBox("Временно не обслуживает");
                            return;
                        }
                        CurrentState = States.ReadyToServe;
                        MDB.EnableCashDevices();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                var frame = Window.Current.Content as Frame;
                                frame.Navigate(typeof(MainPage));
                            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        while (MainPage.MainPageInstance == null)
                        {
                            Task.Delay(100).Wait();
                        }
                        AddItemToLogBox("Выход из служебного режима по инициативе оператора (нажата кнопка \"Конец\")");
                        break;
                    }

                    default:
                    {
                        AddItemToLogBox("Кнопка \"Конец\" нажата вне контекста продажи или служебного режима, действие не требуется.");
                        break;
                    }
                    }
                }
                catch
                {
                }
                finally
                {
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// выдаем сдачу пока депозит не станет равен 0
        /// </summary>
        private void DispenseChange()
        {
            ChangeModeSemaphore.Wait();
            if (StartPage.CurrentState != StartPage.States.DispenseChange)
            {
                ChangeModeSemaphore.Release();
                return;
            }
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                dispenselabel.Text = Math.Round(StartPage.UserDeposit, 0, MidpointRounding.AwayFromZero).ToString().PadLeft(3, '0');
            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            if (StartPage.CurrentDeviceSettings.UseKKT && Math.Round(StartPage.CurrentSaleSession.Quantity, 3) > 0)
            {
                try
                {
                    StartPage.CurrentSaleSession.ReceiptNumber  = StartPage.SystemState.KKTReceiptNextNumber;
                    StartPage.CurrentSaleSession.StageNumber    = Convert.ToInt16(StartPage.SystemState.KKTStageNumber);
                    StartPage.CurrentSaleSession.TaxSystemInUse = StartPage.CurrentDeviceSettings.TaxSystem;
                    if (Math.Round(StartPage.UserDeposit, 2, MidpointRounding.AwayFromZero) == 0)
                    {
                        CashDesk.PrintReceipt(GlobalVars.ReceiptLinesToPrint, (((int)(Math.Round(StartPage.CurrentSaleSession.UserCash, 2) * 100)) * 1.00 / StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE),
                                              StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE, (int)(Math.Round(StartPage.CurrentSaleSession.UserCash, 2) * 100));
                    }
                    else
                    {
                        CashDesk.PrintReceipt(GlobalVars.ReceiptLinesToPrint, Math.Round(StartPage.CurrentSaleSession.Quantity, 3), StartPage.CurrentSaleSession.PRICE_PER_ITEM_MDE,
                                              (int)(Math.Round(StartPage.CurrentSaleSession.UserCash, 2) * 100));
                    }
                }
                catch
                {
                }
            }
            while (CashDesk.PendingTasks.Count(x => x.Status != CashDesk.KKTTaskStatus.Completed) > 0)
            {
                Task.Delay(100).Wait();
            }
            try
            {
                CashDesk.GetCurrentStageParameters();
                ServiceTasks.UpdateWaterCounter(StartPage.CurrentSaleSession.Quantity);
                StartPage.UserDeposit = Math.Round(StartPage.UserDeposit, 0, MidpointRounding.AwayFromZero);
                int ExpectedDeposit = (int)StartPage.UserDeposit;
                while ((int)StartPage.UserDeposit > 0)
                {
                    while (MDB.DispenseInProgress || MDB.AwaitDispenseResult)
                    {
                        Task.Delay(1000).Wait();
                    }
                    if (ExpectedDeposit == (int)StartPage.UserDeposit)
                    {
                        ExpectedDeposit = (int)StartPage.UserDeposit - (int)StartPage.UserDeposit & 0x7f;
                        MDB.PayoutCoinsAsync((int)StartPage.UserDeposit & 0x7f).Wait();//выдаем сдачу монетами, не более 127 рублей за раз
                    }
                    else
                    {
                        if ((int)StartPage.UserDeposit > 0)
                        {
                            //это не очень хорошая ситуация, часть сдачи или всю мы не отдали,
                            //либо отдали, но монетоприемник не прислал об этом никакой информации по какой-то причине
                            //в отведенное для этого время (см MDBHelper.CashDevices_MDBChangeDispensed).
                            //Информация об этом будет видна в личном кабинете, в таблице продаж отражается
                            //выданная сдача и разница между расчетным и реальнно выданным значением.
                            //Если монетоприемник пришлет ошибку, автомат перейдет в режим OutOfService автоматически (см MDBHelper.CashDevices_MDBError)
                            //выходим из процедуры выдачи сдачи, не будем разбрасывать зря бабло.
                            break;
                        }
                    }
                }
            }
            catch
            {
            }
            finally
            {
                StartPage.CurrentSaleSession.ChangeActualDiff = StartPage.CurrentSaleSession.ActualChangeDispensed - StartPage.CurrentSaleSession.UserCash; //пишем разницу между расчетным и реальнно выданным значением сдачи
                StartPage.CurrentSaleSession.CompleteSession();                                                                                             //закрываем продажу
                string oosfilename = ApplicationData.Current.LocalFolder.Path + "\\" + GlobalVars.HardWareID + ".031";
                if (File.Exists(oosfilename))
                {
                    StartPage.CurrentState = StartPage.States.OutOfService;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        var frame = Window.Current.Content as Frame;
                        frame.Navigate(typeof(OutOfServicePage));
                    });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                }
                else
                {
                    StartPage.CurrentState = StartPage.States.ReadyToServe;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    MDB.EnableCashDevicesAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        var frame = Window.Current.Content as Frame;
                        frame.Navigate(typeof(MainPage));
                    });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                }
                ChangeModeSemaphore.Release();
            }
        }