using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Xml.Serialization; using System.Windows.Threading; using System.Diagnostics; using System.Collections.ObjectModel; using SafeBagDE70.Model; using HandyControl.Tools; using System.Drawing.Printing; using System.Drawing; using static HandyControl.Tools.Interop.InteropValues; using SafeBagDE70.API; using Newtonsoft.Json; using System.IO; using System.Reflection; using DE70_CMDv2; using System.Configuration; namespace SafeBagDE70 { //Summary public partial class DepositUC : UserControl { SerialPort serialPortDE70 = new SerialPort(); SerialPort serialPortSensor= new SerialPort(); List sessions = new List(); ObservableCollection lvCountItems = new ObservableCollection(); private DispatcherTimer timer; private DispatcherTimer sensorTimer; int countTimer = 0; CCmdRsp cCmdRsp = null; bool bInitialized = false; public DepositUC() { InitializeComponent(); } private void UserControl_Loaded(object sender, RoutedEventArgs e) { InitTransaction(); } public void InitTransaction() { try { if (AppData.IsAuthenticated) { lblUser.Content = $"Xin chào khách hàng: {AppData.CurrentCustomerAccount.Name} (Gian hàng {AppData.CurrentCustomerAccount.CustomerId})"; } // LoginUsingQRCode(); if (serialPortDE70.IsOpen) serialPortDE70.Close(); if (serialPortSensor.IsOpen) serialPortSensor.Close(); serialPortDE70.ReadBufferSize = 4096; serialPortDE70.WriteBufferSize = 4096; cCmdRsp = new CCmdRsp(serialPortDE70); AppData.cCmdRsp = cCmdRsp; serialPortDE70.PortName = "COM4"; serialPortDE70.BaudRate = 9600; serialPortDE70.Parity = Parity.Even; serialPortDE70.DataBits = 8; serialPortDE70.StopBits = StopBits.One; serialPortDE70.ReadTimeout = 10000; serialPortDE70.WriteTimeout = 10000; serialPortSensor.PortName = "COM3"; serialPortSensor.BaudRate = 9600; serialPortSensor.Parity = Parity.None; serialPortSensor.DataBits = 8; serialPortSensor.StopBits = StopBits.One; serialPortSensor.ReadTimeout = 1000; serialPortSensor.WriteTimeout = 1000; //Subscrible to the DataReveied event if (!serialPortDE70.IsOpen) serialPortDE70.Open(); if (!serialPortSensor.IsOpen) serialPortSensor.Open(); bInitialized = InitSession(); timer = new DispatcherTimer(); timer.Interval = new TimeSpan(0, 0, 10); //10 seconds timer.Tick += Timer_Tick; timer.Start(); sensorTimer = new DispatcherTimer(); sensorTimer.Interval = new TimeSpan(0, 0, 1); //1 seconds sensorTimer.Tick += SensorTimer_Tick; sensorTimer.Start(); } catch (Exception ex) { ShowError("LỖI CỔNG KẾT NỐI, VUI LÒNG KIỂM TRA LẠI CỔNG KẾT NỐI"); } } public void EndTransaction() { try { AppData.IsInTransaction = false; if (timer != null) { timer.Tick -= Timer_Tick; timer.Stop(); } if (sensorTimer != null) { sensorTimer.Tick -= SensorTimer_Tick; sensorTimer.Stop(); } } catch (Exception ex) { } } public void SetStep(int step) { switch(step) { case 0: btnStart.IsEnabled = true; btnCheck.IsEnabled = false; btnCountStart.IsEnabled = false; btnStoreStart.IsEnabled = false; btnEnd.IsEnabled = false; break; case 1: btnStart.IsEnabled = false; btnCheck.IsEnabled = false; btnCountStart.IsEnabled = true; btnStoreStart.IsEnabled = false; btnEnd.IsEnabled =false; break; case 2: btnStart.IsEnabled = false; btnCheck.IsEnabled = true; btnCountStart.IsEnabled = true; btnStoreStart.IsEnabled = true; btnEnd.IsEnabled = false; break; case 3: btnStart.IsEnabled = false; btnCheck.IsEnabled = true; btnCountStart.IsEnabled = true; btnStoreStart.IsEnabled = true; btnEnd.IsEnabled = true; break; } } public void InitSessionCount() { if (lvCount.Items.Count == 11) { foreach(var item in lvCountItems) { item.Quantity = "0"; } } else { lvCountItems.Add(new LvCountItem { Name = "500", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "1000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "2000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "5000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "10000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "20000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "50000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "100000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "200000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "500000", Quantity = "0" }); lvCountItems.Add(new LvCountItem { Name = "Tổng", Quantity = "0" }); lvCountItems[10].Quantity = "0"; lvCountItems[10].Value = "0"; } lvCount.ItemsSource = lvCountItems; //lvCountItems[0].Quantity = "10"; } public long maxQuantitySheet = 10000; public int quantityStored = 0; public int totalAllDenominations = 0; public int posDenomi; public bool printerFlag = false; public static string? recvDataString; public int[] TempQuantity = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; public int[] TempNote = new int[5] { 0, 0, 0, 0, 0 }; public int[] Notes = new int[5] { 0, 0, 0, 0, 0 }; private void SensorTimer_Tick(object? sender, EventArgs e) { try { timer.IsEnabled = false; GetSensorValue(); if (AppData.IsInTransaction) { if (AppData.WDTCount == 30) { ((MainWindow)Application.Current.MainWindow).ShowTimeoutScreen(); } else if (AppData.WDTCount == 60) { //Nhận tiền và Kết thúc StoreStart(); EndSession(); ((MainWindow)Application.Current.MainWindow).ShowWelcomeScreen(); AppData.IsInTransaction = false; AppData.WDTCount = 0; } AppData.WDTCount++; } else { AppData.WDTCount = 0; } timer.IsEnabled = true; } catch (Exception) { } } Stopwatch watch = new Stopwatch(); private void GetSensorValue() { try { int state = 0; if (serialPortSensor.IsOpen == true) { //serialPortSensor.DiscardInBuffer(); //serialPortSensor.DiscardOutBuffer(); serialPortSensor.Write(new byte[] { (byte)'S', 13, 10 }, 0, 3); var buffer = new byte[16]; int n = serialPortSensor.Read(buffer, 0, buffer.Length); for (int i = 1; i < n - 1; i++) { if ((buffer[i] == 13) && (buffer[i + 1] == 10)) { state = buffer[i - 1] - 48; if (bInitialized) { if (state != 0) gridMain.IsEnabled = false; else gridMain.IsEnabled = true; } switch (state) { case 0: lblStatus.Content = "NGĂN KÉT: ĐÓNG, NGĂN TÚI: ĐÓNG"; break; case 1: lblStatus.Content = "NGĂN KÉT: ĐÓNG, NGĂN TÚI: MỞ"; break; case 2: lblStatus.Content = "NGĂN KÉT: MỞ, NGĂN TÚI: ĐÓNG"; break; case 3: lblStatus.Content = "NGĂN KÉT: MỞ, NGĂN TÚI: MỞ"; break; } break; } } // the code that you want to measure comes here watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Debug.WriteLine(elapsedMs); watch.Start(); } } catch (Exception ex) { AppData.LogException("GetSensorValue", ex.ToString()); if(serialPortSensor.IsOpen) serialPortSensor.Close(); serialPortSensor.Open(); serialPortSensor.DiscardInBuffer(); serialPortSensor.DiscardOutBuffer(); } } private void Timer_Tick(object? sender, EventArgs e) { timer.IsEnabled = false; APIModels.SendHealthCheck(); timer.IsEnabled = true; } public int UpdateTotalQuantity() { int total = 0; foreach (var item in lvCountItems) { if (item.Name != "Tổng") { int quantity = 0; if (int.TryParse(item.Quantity, out quantity)) { total += quantity; } } } return total; } public int AutoSerialGet(SerialPort serialPort) { int ret; ushort seri_num = 0; ushort get_num = 0; bool endflg = false; while (true) { ret = cCmdRsp.SendSerialSense(); if (ret == Constants.E_OK) { ret = cCmdRsp.GetSerialNum(out seri_num); if (ret == Constants.E_OK) { // Serial number acquisition if (cCmdRsp.ChkCntEnd()) { endflg = true; Debug.WriteLine("END FLAG: "+cCmdRsp.recv_dat.dat[1]); } Debug.WriteLine("START"); Debug.WriteLine($"Num Serial: {seri_num}"); while (get_num < seri_num) { get_num++; ret = cCmdRsp.SendGetSerial(get_num); switch (cCmdRsp.recv_dat.dat[18]) { case 0x00: TempNote[0] ++; Notes[0] += TempNote[0]; break; case 0x02: //TempNote[1] ++; switch (cCmdRsp.recv_dat.dat[17]) { case 0x00: TempQuantity[0]++; break; case 0x01: TempQuantity[1]++; break; case 0x02: TempQuantity[2]++; break; case 0x03: TempQuantity[3]++; break; case 0x04: TempQuantity[4]++; break; case 0x05: TempQuantity[5]++; break; case 0x06: TempQuantity[6]++; break; case 0x07: TempQuantity[7]++; break; case 0x08: TempQuantity[8]++; break; case 0x09: TempQuantity[9]++; break; } break; case 0x03: TempNote[2] ++; Notes[2] += TempNote[2]; break; case 0x0b: TempNote[3] ++; Notes[3] += TempNote[3]; break; case 0x0c: TempNote[4] ++; Notes[4] += TempNote[4]; break; } } Debug.WriteLine("END"); //Debug.WriteLine("Ellapsed Time: " + timeSpan.TotalSeconds); if (endflg) { break; } } else { Debug.WriteLine("END GET SERIAL: "+ret); break; } } else { Debug.WriteLine("END SEND SERIAL: "+ret); break; } } return 0; } public void btnCountStart_Click(object sender, RoutedEventArgs e) { CountStart(); AppData.WDTCount = 0; } private void CountStart() { printerFlag = false; string currentMethod = MethodBase.GetCurrentMethod().Name; try { serialPortDE70.DiscardInBuffer(); serialPortDE70.DiscardOutBuffer(); AppData.LogAction(currentMethod, null); cCmdRsp.SendXXCmd((byte)Command.CMD_DE_CNTSTART); //var recvData = DE70_CMD.SendxxCmd((byte)CMD_BYTE.CMD_DE_CNTSTART, serialPort); //Thread.Sleep(20000); if (cCmdRsp.recv_dat != null && cCmdRsp.recv_dat.dat[2] != 43) { } do { serialPortDE70.DiscardInBuffer(); serialPortDE70.DiscardOutBuffer(); cCmdRsp.SendXXCmd((byte)Command.CMD_SENSE); } while (cCmdRsp.recv_dat != null && cCmdRsp.recv_dat.dat[1] == 0x09); //SR2 = 0x09 : Counting Status //SR3 = 0x43 : Stacker full AutoSerialGet(serialPortDE70); if (sessions == null || sessions.Count == 0) { double tempSum = 0; for (int i = 0; i < 10; i++) { lvCountItems[i].Quantity = TempQuantity[9 - i].ToString(); tempSum += lvCountItems[i].getValue(); } lvCountItems[10].Quantity = UpdateTotalQuantity().ToString(); lvCountItems[10].Value = tempSum.ToString(); } else { InitSessionCount(); double sum = 0; for (int i = 0; i < 10; i++) { int a = 0; for (int j = 0; j < sessions.Count; j++) { a += sessions[j].QuantityDenomi[9 - i]; } a += TempQuantity[9 - i]; lvCountItems[i].Quantity = a.ToString(); sum += lvCountItems[i].getValue(); } //Update amount of money lvCountItems[10].Quantity = UpdateTotalQuantity().ToString(); lvCountItems[10].Value = sum.ToString(); } SetStep(2); } catch (Exception ex) { AppData.LogException(currentMethod, ex.ToString()); } } private void btnCheck_Click(object sender, RoutedEventArgs e) { string currentMethod = MethodBase.GetCurrentMethod().Name; try { serialPortDE70.DiscardInBuffer(); serialPortDE70.DiscardOutBuffer(); AppData.LogAction(currentMethod, null); Array.Clear(TempQuantity, 0, TempQuantity.Length); cCmdRsp.SendXXCmd((byte)Command.CMD_DE_CANCEL); double sumStored; //TempNote[1] = 0; if (sessions != null) { sumStored = 0; for (int i = 0; i < 10; i++) { int a = 0; for (int j = 0; j < sessions.Count; j++) { a += sessions[j].QuantityDenomi[9 - i]; //quantityStored += lvCountItems[i].getQuantity(); } lvCountItems[i].Quantity = a.ToString(); sumStored += lvCountItems[i].getValue(); } lvCountItems[10].Quantity = UpdateTotalQuantity().ToString(); lvCountItems[10].Value = sumStored.ToString(); } else { InitSessionCount(); } } catch (Exception ex) { AppData.LogException(currentMethod, ex.ToString()); } AppData.WDTCount = 0; } private void btnStoreStart_Click(object sender, RoutedEventArgs e) { StoreStart(); AppData.WDTCount = 0; } private void StoreStart() { printerFlag = true; string currentMethod = MethodBase.GetCurrentMethod().Name; try { serialPortDE70.DiscardInBuffer(); serialPortDE70.DiscardOutBuffer(); AppData.LogAction(currentMethod, null); sessions.Add(new CountSession()); sessions[sessions.Count - 1].QuantityDenomi = (int[])TempQuantity.Clone(); quantityStored = UpdateTotalQuantity(); Debug.WriteLine(quantityStored); Array.Clear(TempQuantity, 0, TempQuantity.Length); cCmdRsp.SendXXCmd((byte)Command.CMD_DE_STORESTART); SetStep(3); } catch (Exception ex) { AppData.LogException(currentMethod, ex.ToString()); } } private void btnStart_Click(object sender, RoutedEventArgs e) { string currentMethod = MethodBase.GetCurrentMethod().Name; InitSession(); AppData.IsInTransaction= true; try { serialPortDE70.DiscardInBuffer(); serialPortDE70.DiscardOutBuffer(); AppData.LogAction(currentMethod, null); cCmdRsp.SendXXCmd((byte)Command.CMD_DE_SENSE); var recvData = cCmdRsp.recv_dat; if (recvData.dat[14] == recvData.dat[16]) { cCmdRsp.SendLock(); } else { cCmdRsp.SendEventFix(recvData.dat[16]); cCmdRsp.SendLock(); } SetStep(1); } catch (Exception ex) { AppData.LogException(currentMethod, ex.ToString()); } AppData.WDTCount = 0; } private void btnEnd_Click(object sender, RoutedEventArgs e) { AppData.IsInTransaction = false; AppData.WDTCount = 0; EndSession(); } private void EndSession() { string currentMethod = MethodBase.GetCurrentMethod().Name; var totalQuantity = lvCountItems[10].Quantity; var totalValue = lvCountItems[10].Value; try { AppData.LogAction(currentMethod, null); serialPortDE70.DiscardInBuffer(); serialPortDE70.DiscardOutBuffer(); //SendData2Server var data2Send = new CountingData2Send { Sessions = sessions, MachineId = null, UserId = AppData.CurrentCustomerAccount.CustomerId, MachineTime = DateTime.Now.ToString("yyyyMMddHHmmss"), RejectNotes = Notes[0], GenuineNotes = quantityStored, UnfitNotes = Notes[2], CounterfeitNotes = Notes[3], SuspendNotes = Notes[4] }; var str = JsonConvert.SerializeObject(data2Send); APIModels.SendCountingData(data2Send); //Reset all and ready to next session if (printerFlag == true) { PrintReceipt(); printerFlag = false; } InitSession(); //Debug.WriteLine("Reject Note: " + Notes[0] ); //Debug.WriteLine("Genuine note stored: " + quantityStored); //Debug.WriteLine("Unfit note: " + Notes[2]); //Debug.WriteLine("Counterfeit: " + Notes[3]); //Debug.WriteLine("Suspend: " + Notes[4]); } catch (Exception ex) { AppData.LogException(currentMethod, ex.ToString()); } String strNotify = $"BẠN VỪA THỰC HIỆN TIỀN VÀO MÁY CDM:\r\n" + $"SỐ LƯỢNG TỜ: {totalQuantity}\r\n" + $"SỐ TIỀN: {totalValue} VND\r\n"; ((MainWindow)Application.Current.MainWindow).ShowInformationScreen(strNotify); } private void ShowError(string strError) { //gridMain.IsEnabled = false; //btnCollect2.Visibility=Visibility.Collapsed; //panelError.Visibility = Visibility.Visible; //lblError.Text = strError; //((MainWindow)Application.Current.MainWindow).ShowWelcomeScreen(); ((MainWindow)Application.Current.MainWindow).ShowErrorScreen(strError); } private bool InitSession() { try { //Check status cCmdRsp.SendDeSense(); var data = cCmdRsp.recv_dat.dat; int IsCassetteFull = 0; int IsNotesInEscrow = 0; IsCassetteFull = data[17] & 0x08; IsNotesInEscrow = data[4] & 0x01; if (IsCassetteFull != 0) { ((MainWindow)Application.Current.MainWindow).ShowCollectionScreen(); return false; } else if (IsNotesInEscrow != 0) { ((MainWindow)Application.Current.MainWindow).ShowInformationScreen("ĐỀ NGHỊ BỎ TIỀN TRONG NGĂN PHỤ ĐỂ TIẾP TỤC"); } else { InitSessionCount(); sessions.Clear(); Array.Clear(TempNote, 0, TempNote.Length); Array.Clear(Notes, 0, Notes.Length); quantityStored = 0; maxQuantitySheet = 0; cCmdRsp.SendXXCmd((byte)Command.CMD_DE_UNLOCK); SetStep(0); return true; } } catch(Exception ex) { AppData.LogException("InitSession", ex.ToString()); } return false; } private void PrintReceipt() { var shopName = AppData.CurrentCustomerAccount.Name; var shopCode = AppData.CurrentCustomerAccount.CustomerId; var tradingCode = "TRA04052024CDM"; var storeAccountNumber = 686868686688; var currentTime = DateTime.Now; var printDocument = new PrintDocument(); printDocument.PrinterSettings.PrinterName = "CUSTOM K80"; printDocument.PrintPage += (sender, e) => { e.Graphics.DrawString("Biên nhận nộp tiền", new Font("Arial", 15), System.Drawing.Brushes.Black, new PointF(80, 10)); e.Graphics.DrawString("Mã máy CDM: ", new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 60)); e.Graphics.DrawString("Batch no: ", new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 90)); e.Graphics.DrawString("Thời gian GD: " + currentTime.ToString("dd/MM/yyyy HH:mm:ss"), new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 120)); e.Graphics.DrawString("Mã GD: " + tradingCode, new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 150)); e.Graphics.DrawString("Mã gian hàng: " + shopCode, new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 180)); e.Graphics.DrawString("Tên gian hàng: " + shopName, new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 210)); e.Graphics.DrawString("STK gian hàng: " + storeAccountNumber, new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 240)); e.Graphics.DrawString("Số tiền nộp: " + lvCountItems[10].Value, new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(50, 270)); e.Graphics.DrawString("*****Xin cám ơn******", new Font("Arial", 9), System.Drawing.Brushes.Black, new PointF(100, 300)); // To send raw ESC/POS commands, you'd typically use e.Graphics.DrawString() with the command string, // or for more complex scenarios, directly manipulate the byte stream sent to the printer. }; printDocument.Print(); } private void UserControl_Unloaded(object sender, RoutedEventArgs e) { EndTransaction(); } } }