1748 lines
68 KiB
C#
1748 lines
68 KiB
C#
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;
|
|
using Serilog;
|
|
using System.ComponentModel;
|
|
using SafeBagDE70.StateMachine;
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
|
|
using System.Runtime.Intrinsics.Arm;
|
|
using SafeBagDE70.Services;
|
|
using System.Windows.Forms;
|
|
using Button = System.Windows.Controls.Button;
|
|
using UserControl = System.Windows.Controls.UserControl;
|
|
using Application = System.Windows.Application;
|
|
using Control = System.Windows.Controls.Control;
|
|
using static Azure.Core.HttpHeader;
|
|
using System.Net.Http;
|
|
using Azure;
|
|
|
|
|
|
namespace SafeBagDE70
|
|
{ //Summary
|
|
|
|
|
|
public partial class DepositSMUCv2 : UserControl
|
|
{
|
|
SerialPort serialPortDE70 = new SerialPort();
|
|
SerialPort serialPortSensor= new SerialPort();
|
|
|
|
List<CountSession> sessions = new List<CountSession>();
|
|
public ObservableCollection<LvCountItem> lvCountItems = new ObservableCollection<LvCountItem>();
|
|
private DispatcherTimer sensorTimer;
|
|
DispatcherTimer? warningTimer = null;
|
|
DispatcherTimer? endsessionTimer = null;
|
|
DispatcherTimer? backToWelcomeTimer = null;
|
|
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 countSensorTimer = 0;
|
|
private PrinterManager printerManager = new PrinterManager();
|
|
|
|
private NotesInSession notesInSession= new NotesInSession();
|
|
//DispatcherTimer?
|
|
private volatile bool bIsCounted = false;
|
|
|
|
CCmdRsp cCmdRsp = null;
|
|
bool bInitialized = false;
|
|
bool bOpenPort = true;
|
|
|
|
bool bIsMaintain = false;
|
|
MainWindow mainWindow = null;
|
|
Task taskCounting = null;
|
|
|
|
bool isSensorActivated = true;
|
|
bool isPrinterActivated = true;
|
|
public DepositSMUCv2()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
private void UserControl_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
mainWindow=((MainWindow)Application.Current.MainWindow);
|
|
InitTransaction();
|
|
StopTimers();
|
|
}
|
|
public void InitTransaction()
|
|
{
|
|
try
|
|
{
|
|
lblName.Content= "Vietinbank " + Environment.MachineName;
|
|
string? transactionCode = null;
|
|
if (AppData.IsAuthenticated)
|
|
{
|
|
|
|
transactionCode = AppData.GetTransactionCode();
|
|
lblUser.Content = $"Xin chào khách hàng: {AppData.CurrentCustomerAccount.Name} (Gian hàng {AppData.CurrentCustomerAccount.CustomerId})";
|
|
lblTransactionCode.Content = $"Mã GD: {transactionCode}";
|
|
AppData.IsInTransaction = true;
|
|
|
|
var str = $"MÃ GD: {AppData.GetTransactionCode()} " +
|
|
$"\r\nMÁY: {Environment.MachineName}" +
|
|
$"\r\nMÃ NV: {AppData.CurrentCustomerAccount.CustomerId}";
|
|
Log.Information(str);
|
|
}
|
|
cCmdRsp = new CCmdRsp(serialPortDE70);
|
|
AppData.cCmdRsp = cCmdRsp;
|
|
bool bInitSP = InitSerialPorts();
|
|
if(bInitSP)
|
|
{
|
|
bInitialized = InitSession();
|
|
InitTimers();
|
|
|
|
notesInSession = new NotesInSession();
|
|
spNotesInSession.DataContext = notesInSession;
|
|
|
|
ResetButtons();
|
|
btnStart.IsEnabled = true;
|
|
btnLogout.IsEnabled = true;
|
|
ResetTimers();
|
|
var state = GetCDMState();
|
|
if (state.GetSR2() == 0x1C)
|
|
{
|
|
StopTimers();
|
|
ShowError(state.CDMStatus);
|
|
}
|
|
|
|
var data = AppData.GetCassetteData();
|
|
if (transactionCode != null)
|
|
{
|
|
AppData.DeviceStatus.Description = $"[CASSETTE]" + AppData.GetNotesString(data);
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AppData.DeviceStatus.Description = "LỖI KHỞI TẠO GIAO DỊCH";
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
Log.Fatal(ex, "LỖI KHỞI TẠO GIAO DỊCH");
|
|
ShowError("LỖI KHỞI TẠO GIAO DỊCH");
|
|
}
|
|
|
|
}
|
|
|
|
private bool InitSerialPorts()
|
|
{
|
|
var bInitDE70=InitSerialPortDE70();
|
|
|
|
if(isSensorActivated)
|
|
InitSerialPortSensor();
|
|
|
|
if (bInitDE70)
|
|
return true;
|
|
else
|
|
{
|
|
AppData.DeviceStatus.CDMStatus = (int)CDMStatusCode.DISCONNECT_SERIALPORT;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
Log.Fatal("LỖI CỔNG KẾT NỐI");
|
|
ShowError("LỖI CỔNG KẾT NỐI, VUI LÒNG KIỂM TRA LẠI CỔNG KẾT NỐI");
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
private bool InitSerialPortSensor()
|
|
{
|
|
try
|
|
{
|
|
if (serialPortSensor.IsOpen) serialPortSensor.Close();
|
|
|
|
serialPortSensor.PortName = AppData.SensorPort;
|
|
serialPortSensor.BaudRate = 9600;
|
|
serialPortSensor.Parity = Parity.None;
|
|
serialPortSensor.DataBits = 8;
|
|
serialPortSensor.StopBits = StopBits.One;
|
|
serialPortSensor.ReadTimeout = 1000;
|
|
serialPortSensor.WriteTimeout = 1000;
|
|
|
|
if (bOpenPort)
|
|
{
|
|
if (!serialPortSensor.IsOpen)
|
|
serialPortSensor.Open();
|
|
}
|
|
AppData.ADMINDEVICESTATUS.SensorStatus = "Sensor: OK";
|
|
return true;
|
|
}catch(Exception ex)
|
|
{
|
|
AppData.DeviceStatus.SensorStatus = (int)SensorStatusCode.ERROR;
|
|
AppData.DeviceStatus.Description = ex.Message;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
Log.Information(ex, "LỖI KẾT NỐI SENSOR");
|
|
AppData.ADMINDEVICESTATUS.SensorStatus = "Sensor: Error";
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool InitSerialPortDE70()
|
|
{
|
|
try
|
|
{
|
|
if (serialPortDE70.IsOpen) serialPortDE70.Close();
|
|
|
|
|
|
serialPortDE70.ReadBufferSize = 4096;
|
|
serialPortDE70.WriteBufferSize = 4096;
|
|
|
|
|
|
serialPortDE70.PortName = AppData.CDMPort;
|
|
serialPortDE70.BaudRate = 9600;
|
|
serialPortDE70.Parity = Parity.Even;
|
|
serialPortDE70.DataBits = 8;
|
|
serialPortDE70.StopBits = StopBits.One;
|
|
serialPortDE70.ReadTimeout = 10000;
|
|
serialPortDE70.WriteTimeout = 10000;
|
|
if (bOpenPort)
|
|
{
|
|
if (!serialPortDE70.IsOpen)
|
|
serialPortDE70.Open();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
AppData.DeviceStatus.CDMStatus = (int)CDMStatusCode.DISCONNECT_SERIALPORT;
|
|
AppData.DeviceStatus.Description = ex.Message;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
Log.Information(ex, "LỖI KẾT NỐI CDM");
|
|
AppData.CDMSTATE.CDMStatus = "CDM: Error";
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void InitTimers()
|
|
{
|
|
warningTimer = new DispatcherTimer(); // 30 seconds
|
|
warningTimer.Interval = new TimeSpan(0, 0, 30);
|
|
warningTimer.Tick += WarningTimer_Tick; ;
|
|
warningTimer.Stop();
|
|
|
|
endsessionTimer = new DispatcherTimer(); // 60 seconds
|
|
endsessionTimer.Interval = new TimeSpan(0, 0, 60);
|
|
endsessionTimer.Tick += EndSessionTimer_Tick;
|
|
endsessionTimer.Stop();
|
|
|
|
backToWelcomeTimer = new DispatcherTimer();
|
|
backToWelcomeTimer.Interval = new TimeSpan(0, 0, 15);
|
|
backToWelcomeTimer.Tick += BackToWelcomeTimer_Tick;
|
|
backToWelcomeTimer.Stop();
|
|
|
|
sensorTimer = new DispatcherTimer();
|
|
sensorTimer.Interval = new TimeSpan(0, 0, 1); //1 seconds
|
|
sensorTimer.Tick += SensorTimer_Tick;
|
|
sensorTimer.Start();
|
|
}
|
|
|
|
public void StopWelcomeTimer()
|
|
{
|
|
if(backToWelcomeTimer != null)
|
|
backToWelcomeTimer.Stop();
|
|
}
|
|
public void StartWelcomeTimer()
|
|
{
|
|
if (backToWelcomeTimer != null)
|
|
backToWelcomeTimer.Start();
|
|
}
|
|
private void BackToWelcomeTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
mainWindow.ShowWelcomeScreen();
|
|
}
|
|
|
|
private void EndSessionTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
Log.Information("7. Timeout starting");
|
|
mainWindow.ShowEndSessionScreen();
|
|
StopTimers();
|
|
DoStoreStart();
|
|
bIsCounted = false;
|
|
DoCountStart();
|
|
Task.Run(() =>
|
|
{
|
|
taskCounting.Wait();
|
|
DoStoreStart();
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
EndSession(COUNTINGSTATE.AUTOEND,"Tự động kết thúc");
|
|
});
|
|
|
|
Log.Information("7. Timeout completed");
|
|
});
|
|
}
|
|
|
|
private void BackToWelcomeScreen()
|
|
{
|
|
StopTimers();
|
|
|
|
var cdmState = GetCDMState();
|
|
var state = GetCDMState();
|
|
if (state.IsNotesInEscrow > 0)
|
|
{
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỀN RA KHỎI NGĂN PHỤ HOẶC ẤN LƯU TRỮ ĐỂ TIẾP TỤC", false, true);
|
|
}
|
|
else if (state.IsNotesInRejectPocket > 0 || state.IsRejectPocketFull > 0)
|
|
{
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỀN RA KHỎI NGĂN TIỀN KHÔNG HỢP LỆ ĐỂ TIẾP TỤC", false, true);
|
|
}
|
|
else if (state.IsNotesInHopper > 0)
|
|
{
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỀN RA KHỎI NGĂN NỘP ĐỂ TIẾP TỤC", false, true);
|
|
}
|
|
else if (state.IsCassetteFull != 0)
|
|
{
|
|
mainWindow.ShowCollectionScreen();
|
|
}
|
|
else
|
|
{
|
|
mainWindow.ShowWelcomeScreen();
|
|
}
|
|
}
|
|
|
|
private void WarningTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
|
|
mainWindow.ShowTimeoutScreen();
|
|
}
|
|
|
|
public void EndTransaction()
|
|
{
|
|
try
|
|
{
|
|
AppData.IsInTransaction = false;
|
|
|
|
if (sensorTimer != null)
|
|
{
|
|
sensorTimer.Tick -= SensorTimer_Tick;
|
|
sensorTimer.Stop();
|
|
}
|
|
if (warningTimer != null)
|
|
{
|
|
warningTimer.Tick -=WarningTimer_Tick;
|
|
warningTimer.Stop();
|
|
}
|
|
if (endsessionTimer != null)
|
|
{
|
|
endsessionTimer.Tick -=EndSessionTimer_Tick;
|
|
endsessionTimer.Stop();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
public void InitLvCountItems()
|
|
{
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
if (lvCount.Items.Count == 11)
|
|
{
|
|
foreach (var item in lvCountItems)
|
|
{
|
|
item.Quantity = "0";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lvCountItems = new ObservableCollection<LvCountItem>()
|
|
{
|
|
new LvCountItem{Name = "500",Quantity = "0"},
|
|
new LvCountItem{Name = "1000",Quantity = "0"},
|
|
new LvCountItem{Name = "2000",Quantity = "0"},
|
|
new LvCountItem{Name = "5000",Quantity = "0"},
|
|
new LvCountItem{Name = "10000",Quantity = "0"},
|
|
new LvCountItem{Name = "20000",Quantity = "0"},
|
|
new LvCountItem{Name = "50000",Quantity = "0"},
|
|
new LvCountItem{Name = "100000",Quantity = "0"},
|
|
new LvCountItem{Name = "200000",Quantity = "0"},
|
|
new LvCountItem{Name = "500000",Quantity = "0"},
|
|
new LvCountItem{Name = "Tổng",Quantity = "0",Value="0"},
|
|
};
|
|
}
|
|
lvCount.ItemsSource = lvCountItems;
|
|
});
|
|
//lvCountItems[0].Quantity = "10";
|
|
}
|
|
int prevPrinterStatus = -1;
|
|
int prevSensorStatus = -1;
|
|
int prevCDMState = -1;
|
|
private void SensorTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
sensorTimer.IsEnabled = false;
|
|
try
|
|
{
|
|
if (countSensorTimer % 10 == 0)
|
|
{
|
|
if(isPrinterActivated)
|
|
GetPrinterStatus();
|
|
|
|
GetCDMStatus();
|
|
AppData.GetandExecuteCommands();
|
|
|
|
|
|
//AppData.DeviceStatus.DeviceTime = DateTime.Now;
|
|
APIModels.SendHealthCheck(AppData.DeviceStatus);
|
|
}
|
|
if (countSensorTimer%5==0)
|
|
{
|
|
AppData.ADMINDEVICESTATUS.DeviceStatus = AppData.IsInternetOk == false ? "Kết nối Internet: Không" : "Kết nối Internet: OK";
|
|
}
|
|
if (countSensorTimer % 300 == 0)
|
|
{
|
|
AppData.ResendData();
|
|
}
|
|
countSensorTimer++;
|
|
sensorTimer.IsEnabled = false;
|
|
|
|
if (isSensorActivated)
|
|
GetSensorValue();
|
|
sensorTimer.IsEnabled = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Fatal(ex, "Sensor_Timer");
|
|
}
|
|
sensorTimer.IsEnabled = true;
|
|
}
|
|
int nTry2Reset = 0;
|
|
private void GetCDMStatus()
|
|
{
|
|
if (!AppData.IsInTransaction)
|
|
{
|
|
AppData.GetCDMState();
|
|
if (AppData.cCmdRsp==null || AppData.cCmdRsp.cmd_result == SendStatus.SEND_DAT_ERR || AppData.cCmdRsp.cmd_result == SendStatus.SEND_ERR)
|
|
{
|
|
AppData.CDMSTATE.CDMStatus = "CDM: LỖI KẾT NỐI";
|
|
AppData.DeviceStatus.CDMStatus = (int)CDMStatusCode.DISCONNECT_SERIALPORT;
|
|
AppData.DeviceStatus.Description = AppData.CDMSTATE.CDMStatus;
|
|
}
|
|
else if ((AppData.cCmdRsp.recv_dat.dat[18]&0xF0)==0xE0)
|
|
{
|
|
AppData.CDMSTATE.CDMStatus = "CDM: LỖI ABNORMAL STORAGE ERROR";
|
|
AppData.DeviceStatus.CDMStatus = (int)CDMStatusCode.ERROR;
|
|
AppData.DeviceStatus.Description = AppData.CDMSTATE.CDMStatus;
|
|
}
|
|
else if (AppData.cCmdRsp.recv_dat.dat[1]==0x1C)
|
|
{
|
|
AppData.CDMSTATE.CDMStatus = "CDM: LỖI INITIALIZATION ERROR";
|
|
AppData.DeviceStatus.CDMStatus = (int)CDMStatusCode.ERROR;
|
|
AppData.DeviceStatus.Description = AppData.CDMSTATE.CDMStatus;
|
|
|
|
if(nTry2Reset<2)
|
|
{
|
|
AppData.ResetCDMError();
|
|
nTry2Reset++;
|
|
|
|
AppData.GetCDMState();
|
|
var SR1 = AppData.cCmdRsp.recv_dat.dat[1];
|
|
if ((SR1 == 0x07) || (SR1 == 0x04))
|
|
{
|
|
AppData.CDMSTATE.CDMStatus = "CDM: LỖI INITIALIZATION ERROR --> RESET THÀNH CÔNG";
|
|
}
|
|
else
|
|
AppData.CDMSTATE.CDMStatus = "CDM: LỖI INITIALIZATION ERROR --> RESET KHÔNG THÀNH CÔNG";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nTry2Reset = 0;
|
|
AppData.DeviceStatus.CDMStatus = (int)CDMStatusCode.NORMAL;
|
|
AppData.DeviceStatus.Description = AppData.CDMSTATE.CDMStatus;
|
|
}
|
|
if (AppData.DeviceStatus.CDMStatus != prevCDMState)
|
|
{
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
|
|
if (AppData.DeviceStatus.CDMStatus==(int)CDMStatusCode.ERROR||
|
|
AppData.DeviceStatus.CDMStatus == (int)CDMStatusCode.DISCONNECT_SERIALPORT)
|
|
{
|
|
Log.Error(AppData.CDMSTATE.CDMStatus);
|
|
|
|
StopTimers();
|
|
ShowError(AppData.CDMSTATE.CDMStatus);
|
|
}
|
|
else
|
|
{
|
|
if(AppData.DeviceStatus.CDMStatus== (int)CDMStatusCode.NORMAL&&
|
|
( prevCDMState == (int)CDMStatusCode.ERROR ||
|
|
prevCDMState == (int)CDMStatusCode.DISCONNECT_SERIALPORT))
|
|
{
|
|
mainWindow.ShowWelcomeScreen();
|
|
}
|
|
}
|
|
prevCDMState = AppData.DeviceStatus.CDMStatus;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void GetPrinterStatus()
|
|
{
|
|
if(!AppData.IsInTransaction)
|
|
{
|
|
var status = printerManager.GetStatus();
|
|
var strPrinterMessage = "";
|
|
|
|
if (status != null)
|
|
{
|
|
bool StsNOPAPER = status.StsNOPAPER;
|
|
bool StsNEARENDPAP = status.StsNEARENDPAP;
|
|
if (StsNOPAPER || (StsNEARENDPAP && AppData.IsStopPrinting()))
|
|
{
|
|
AppData.DeviceStatus.PrinterStatus = (int)PrinterStatusCode.PAPEROUT;
|
|
StopTimers();
|
|
strPrinterMessage = "MÁY IN: HẾT GIẤY! ĐỀ NGHỊ THAY GIẤY";
|
|
ShowError(strPrinterMessage);
|
|
AppData.ADMINDEVICESTATUS.PrinterStatus = strPrinterMessage;
|
|
}
|
|
else if (StsNEARENDPAP)
|
|
{
|
|
AppData.UpdatePrinterStatus(true);
|
|
strPrinterMessage = "MÁY IN: GẦN HẾT GIẤY";
|
|
AppData.DeviceStatus.PrinterStatus = (int)PrinterStatusCode.NEARPAPEROUT;
|
|
AppData.ADMINDEVICESTATUS.PrinterStatus = strPrinterMessage;
|
|
}
|
|
else if (status.StsPAPERJAM || status.StsCUTERROR || status.StsOVERTEMP)
|
|
{
|
|
strPrinterMessage = "MÁY IN: LỖI";
|
|
AppData.DeviceStatus.PrinterStatus = (int)PrinterStatusCode.ERROR;
|
|
AppData.ADMINDEVICESTATUS.PrinterStatus = strPrinterMessage;
|
|
}
|
|
else
|
|
{
|
|
AppData.UpdatePrinterStatus(false);
|
|
strPrinterMessage = "MÁY IN: OK";
|
|
AppData.DeviceStatus.PrinterStatus = (int)PrinterStatusCode.NORMAL;
|
|
AppData.ADMINDEVICESTATUS.PrinterStatus = strPrinterMessage;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strPrinterMessage = "MÁY IN: LỖI";
|
|
AppData.DeviceStatus.PrinterStatus = (int)PrinterStatusCode.ERROR;
|
|
AppData.ADMINDEVICESTATUS.PrinterStatus = strPrinterMessage;
|
|
}
|
|
if (AppData.DeviceStatus.PrinterStatus != prevPrinterStatus)
|
|
{
|
|
if (AppData.DeviceStatus.PrinterStatus == (int)PrinterStatusCode.ERROR)
|
|
{
|
|
StopTimers();
|
|
ShowError(strPrinterMessage);
|
|
}
|
|
Log.Information(strPrinterMessage);
|
|
AppData.DeviceStatus.Description = strPrinterMessage;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
prevPrinterStatus = AppData.DeviceStatus.PrinterStatus;
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
string strSensorMessage = "";
|
|
switch (state)
|
|
{
|
|
case 0:
|
|
strSensorMessage = "NGĂN KÉT: ĐÓNG, NGĂN TÚI: ĐÓNG";
|
|
break;
|
|
case 1:
|
|
strSensorMessage = "NGĂN KÉT: ĐÓNG, NGĂN TÚI: MỞ";
|
|
break;
|
|
case 2:
|
|
strSensorMessage = "NGĂN KÉT: MỞ, NGĂN TÚI: ĐÓNG";
|
|
break;
|
|
case 3:
|
|
strSensorMessage = "NGĂN KÉT: MỞ, NGĂN TÚI: MỞ";
|
|
break;
|
|
}
|
|
lblStatus.Content = strSensorMessage;
|
|
if (state!=prevSensorStatus)
|
|
{
|
|
AppData.DeviceStatus.Description=strSensorMessage;
|
|
AppData.DeviceStatus.SensorStatus= state;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
prevSensorStatus = state;
|
|
}
|
|
if (state > 0)
|
|
{
|
|
if (!bIsMaintain)
|
|
{
|
|
bIsMaintain = true;
|
|
DoMaintaince();
|
|
}
|
|
// TransitionToState("Maintainance");
|
|
}
|
|
else
|
|
{
|
|
if(bIsMaintain)
|
|
{
|
|
bIsMaintain = false;
|
|
mainWindow.ShowWelcomeScreen();
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// the code that you want to measure comes here
|
|
watch.Stop();
|
|
|
|
var elapsedMs = watch.ElapsedMilliseconds;
|
|
Debug.WriteLine(elapsedMs);
|
|
watch.Start();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//Log.Fatal(ex,"GetSensorValue");
|
|
//if(serialPortSensor.IsOpen)
|
|
// serialPortSensor.Close();
|
|
//serialPortSensor.Open();
|
|
|
|
//serialPortSensor.DiscardInBuffer();
|
|
//serialPortSensor.DiscardOutBuffer();
|
|
InitSerialPortSensor();
|
|
}
|
|
}
|
|
private void DoMaintaince()
|
|
{
|
|
StopTimers();
|
|
mainWindow.ShowMaintainanceScreen();
|
|
}
|
|
|
|
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()
|
|
{
|
|
try
|
|
{
|
|
int ret;
|
|
ushort seri_num = 0;
|
|
ushort get_num = 0;
|
|
bool endflg = false;
|
|
|
|
var countSession = new CountSession();
|
|
countSession.IsStored = false;
|
|
sessions.Add(countSession);
|
|
while (true)
|
|
{
|
|
AppData.WDTCount = 0;
|
|
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;
|
|
}
|
|
|
|
while (get_num < seri_num)
|
|
{
|
|
|
|
AppData.WDTCount = 0;
|
|
get_num++;
|
|
|
|
Log.Information($"Serial Idx: {get_num}/{seri_num}");
|
|
ret = cCmdRsp.SendGetSerial(get_num);
|
|
Log.Information($"Serial Status: {cCmdRsp.recv_dat.dat[18]}");
|
|
byte noteVal = 0;
|
|
switch (cCmdRsp.recv_dat.dat[18])
|
|
{
|
|
case 0x00:
|
|
countSession.TempNotes[0]++;
|
|
break;
|
|
case 0x02:
|
|
//TempNote[1] ++;
|
|
noteVal = cCmdRsp.recv_dat.dat[17];
|
|
Log.Information($"Serial Value: {noteVal}");
|
|
switch (noteVal)
|
|
{
|
|
case 0x00: countSession.QuantityDenomi[0]++; break;
|
|
case 0x01: countSession.QuantityDenomi[1]++; break;
|
|
case 0x02: countSession.QuantityDenomi[2]++; break;
|
|
case 0x03: countSession.QuantityDenomi[3]++; break;
|
|
case 0x04: countSession.QuantityDenomi[4]++; break;
|
|
case 0x05: countSession.QuantityDenomi[5]++; break;
|
|
case 0x06: countSession.QuantityDenomi[6]++; break;
|
|
case 0x07: countSession.QuantityDenomi[7]++; break;
|
|
case 0x08: countSession.QuantityDenomi[8]++; break;
|
|
case 0x09: countSession.QuantityDenomi[9]++; break;
|
|
}
|
|
break;
|
|
case 0x03: countSession.TempNotes[2]++; break;
|
|
case 0x0b: countSession.TempNotes[3]++; break;
|
|
case 0x0c: countSession.TempNotes[4]++; break;
|
|
}
|
|
UpdateListViewCountItems();
|
|
}
|
|
//Debug.WriteLine("Ellapsed Time: " + timeSpan.TotalSeconds);
|
|
if (endflg)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (countSession.QuantityDenomi.Sum() == 0 && countSession.TempNotes.Sum() == 0)
|
|
{
|
|
sessions.Remove(countSession);
|
|
}
|
|
}catch(Exception ex)
|
|
{
|
|
Log.Fatal(ex, "AutoSerialGet");
|
|
}
|
|
|
|
//Log.Information(JsonConvert.SerializeObject(sessions));
|
|
return 0;
|
|
}
|
|
|
|
private static void UpdateCountSession(CountSession countSession, byte noteVal)
|
|
{
|
|
switch (noteVal)
|
|
{
|
|
case 0x00: countSession.QuantityDenomi[0]++; break;
|
|
case 0x01: countSession.QuantityDenomi[1]++; break;
|
|
case 0x02: countSession.QuantityDenomi[2]++; break;
|
|
case 0x03: countSession.QuantityDenomi[3]++; break;
|
|
case 0x04: countSession.QuantityDenomi[4]++; break;
|
|
case 0x05: countSession.QuantityDenomi[5]++; break;
|
|
case 0x06: countSession.QuantityDenomi[6]++; break;
|
|
case 0x07: countSession.QuantityDenomi[7]++; break;
|
|
case 0x08: countSession.QuantityDenomi[8]++; break;
|
|
case 0x09: countSession.QuantityDenomi[9]++; break;
|
|
}
|
|
}
|
|
|
|
|
|
private string GetShortInforFromCountItems()
|
|
{
|
|
return JsonConvert.SerializeObject(lvCountItems);
|
|
}
|
|
private string GetQuantityFromSessions(List<CountSession> countSessions,bool? btoreFlag=null)
|
|
{
|
|
var quantFromSession = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };//500.000->500
|
|
foreach (var session in countSessions)
|
|
{
|
|
if(btoreFlag == null)
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
quantFromSession[i] += session.QuantityDenomi[i];
|
|
}
|
|
else if ((session.IsStored == btoreFlag))
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
quantFromSession[i] += session.QuantityDenomi[i];
|
|
}
|
|
}
|
|
string str = "";
|
|
for (int i = 0; i < quantFromSession.Length; i++)
|
|
{
|
|
str += quantFromSession[i] + ",";
|
|
}
|
|
str = str.Trim(',');
|
|
return str;
|
|
}
|
|
|
|
private bool DoCountStart()
|
|
{
|
|
bool bSuccess = true;
|
|
|
|
string currentMethod = MethodBase.GetCurrentMethod().Name;
|
|
if (bOpenPort)
|
|
{
|
|
serialPortDE70.DiscardInBuffer();
|
|
serialPortDE70.DiscardOutBuffer();
|
|
|
|
cCmdRsp.SendXXCmd((byte)Command.CMD_DE_CNTSTART);
|
|
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
|
|
}
|
|
Thread.Sleep(1000);
|
|
try
|
|
{
|
|
taskCounting = Task.Run(() =>
|
|
{
|
|
|
|
|
|
var str = "BEFORE COUNT";
|
|
str+="\r\nSTORED: "+ GetQuantityFromSessions(sessions,true);
|
|
str += "\r\nSTACKER: " + GetQuantityFromSessions(sessions, false);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
|
|
Log.Information("Before AutoCount: " + GetShortInforFromCountItems());
|
|
bIsCounted = false;
|
|
AutoSerialGet();
|
|
bIsCounted = true;
|
|
Log.Information("After AutoCount: " + GetShortInforFromCountItems());
|
|
|
|
str = "AFTER COUNT";
|
|
str+= "\r\nSTORED: " + GetQuantityFromSessions(sessions, true);
|
|
str += "\r\nSTACKER: " + GetQuantityFromSessions(sessions, false);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
bSuccess = false;
|
|
Log.Fatal(ex,currentMethod);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
private int GetNotes(byte[] cassetData)
|
|
{
|
|
int notes = 0;
|
|
int offset = 14;
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
notes += cassetData[2 * i + offset] * 256 + cassetData[2 * i + 1 + offset];
|
|
}
|
|
return notes;
|
|
}
|
|
|
|
private bool CheckStoreValid(byte[] previousCassetData, byte[] newCassetData,List<CountSession> countSessions)
|
|
{
|
|
var quantFromSession = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };//500.000->500
|
|
foreach (var session in countSessions) {
|
|
if ((session.IsStored==false))
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
quantFromSession[i] += session.QuantityDenomi[i];
|
|
}
|
|
}
|
|
var nPreviousCassetData = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
var nNewCassetData = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
int offset = 14;
|
|
bool bValid = true;
|
|
for(int i=0;i<10;i++)
|
|
{
|
|
nPreviousCassetData[i] = previousCassetData[2*i + offset] * 256 + previousCassetData[2*i + 1 + offset];
|
|
nNewCassetData[i]=newCassetData[2*i + offset] * 256 + newCassetData[2*i+1+ offset];
|
|
if (nNewCassetData[i] - nPreviousCassetData[i]!=quantFromSession[i])
|
|
{
|
|
bValid = false;
|
|
break;
|
|
}
|
|
}
|
|
return bValid;
|
|
}
|
|
|
|
private bool CheckPreStoreValid(byte[] previousCassetData, int maxNotes, List<CountSession> countSessions)
|
|
{
|
|
var quantFromSession = 0;//500.000->500
|
|
var quantFromCasset = 0;
|
|
bool bValid = true;
|
|
foreach (var session in countSessions)
|
|
{
|
|
if ((session.IsStored == false))
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
quantFromSession += session.QuantityDenomi[i];
|
|
}
|
|
}
|
|
int offset = 14;
|
|
for (int i=0;i<10; i++)
|
|
{
|
|
quantFromCasset += previousCassetData[2 * i + offset] * 256 + previousCassetData[2 * i + 1 + offset];
|
|
}
|
|
if (quantFromCasset + quantFromSession > maxNotes)
|
|
bValid = false;
|
|
return bValid;
|
|
}
|
|
private void UpdateListViewCountItems()
|
|
{
|
|
Dispatcher.Invoke(DispatcherPriority.Normal, () =>
|
|
{
|
|
if (lvCountItems != null && lvCountItems.Count > 0)
|
|
{
|
|
double sum = 0;
|
|
if (sessions != null && sessions.Count > 0)
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
int quantity = 0;
|
|
for (int j = 0; j < sessions.Count; j++)
|
|
{
|
|
|
|
quantity += sessions[j].QuantityDenomi[9 - i];
|
|
|
|
}
|
|
lvCountItems[i].Quantity = quantity.ToString();
|
|
sum += lvCountItems[i].getValue();
|
|
|
|
}
|
|
//Update amount of money
|
|
lvCountItems[10].Quantity = UpdateTotalQuantity().ToString();
|
|
lvCountItems[10].Value = sum.ToString();
|
|
|
|
//Update Notes In Sesion
|
|
notesInSession.GenuineNotes = 0;
|
|
notesInSession.RejectNotes = 0;
|
|
|
|
for (int j = 0; j < sessions.Count; j++)
|
|
{
|
|
if (sessions[j].IsStored == false)
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
notesInSession.GenuineNotes += sessions[j].QuantityDenomi[9 - i];
|
|
}
|
|
notesInSession.RejectNotes += sessions[j].TempNotes.Sum();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < 11; i++)
|
|
{
|
|
lvCountItems[i].Quantity = "0";
|
|
lvCountItems[i].Value = "0";
|
|
}
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public bool DoCheck()
|
|
{
|
|
bool bSuccess = true;
|
|
string currentMethod = MethodBase.GetCurrentMethod().Name;
|
|
try
|
|
{
|
|
var str = "BEFORE CHECK";
|
|
str += "\r\nSTORED: " + GetQuantityFromSessions(sessions, true);
|
|
str += "\r\nSTACKER: " + GetQuantityFromSessions(sessions, false);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
|
|
Log.Information("Before Check: "+GetShortInforFromCountItems());
|
|
serialPortDE70.DiscardInBuffer();
|
|
serialPortDE70.DiscardOutBuffer();
|
|
|
|
|
|
cCmdRsp.SendXXCmd((byte)Command.CMD_DE_CANCEL);
|
|
|
|
Log.Information(JsonConvert.SerializeObject(sessions));
|
|
sessions.RemoveAll(item=>!item.IsStored);
|
|
Log.Information(JsonConvert.SerializeObject(sessions));
|
|
UpdateListViewCountItems();
|
|
|
|
|
|
Log.Information("After Check: "+GetShortInforFromCountItems());
|
|
|
|
str = "AFTER CHECK";
|
|
str += "\r\nSTORED: " + GetQuantityFromSessions(sessions, true);
|
|
str += "\r\nSTACKER: " + GetQuantityFromSessions(sessions, false);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
bSuccess = false;
|
|
Log.Fatal(ex, currentMethod);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
private bool WaitUntilCountReady(int nSecondTimeout)
|
|
{
|
|
CDMSTATE state = null;
|
|
int nTimes = 0;
|
|
bool bSuccess = false;
|
|
while (true)
|
|
{
|
|
state = GetCDMState();
|
|
if (state.GetSR2() == 0x07)
|
|
{
|
|
bSuccess = true;
|
|
break;
|
|
}
|
|
nTimes++;
|
|
Thread.Sleep(1000);
|
|
if ((nSecondTimeout > 0) && nTimes >= nSecondTimeout)
|
|
break;
|
|
}
|
|
return bSuccess;
|
|
}
|
|
private bool WaitUntilEnscrowEmpty(int nSecondTimeout)
|
|
{
|
|
CDMSTATE state = null;
|
|
int nTimes = 0;
|
|
bool bSuccess = false;
|
|
while(true)
|
|
{
|
|
state = GetCDMState();
|
|
if (state.IsNotesInEscrow == 0)
|
|
{
|
|
bSuccess = true;
|
|
break;
|
|
}
|
|
nTimes++;
|
|
Thread.Sleep(1000);
|
|
if ((nSecondTimeout > 0) && nTimes >= nSecondTimeout)
|
|
break;
|
|
}
|
|
return bSuccess;
|
|
}
|
|
private bool DoStoreStart()
|
|
{
|
|
|
|
bool bSuccess = true;
|
|
printerFlag = true;
|
|
|
|
string currentMethod = MethodBase.GetCurrentMethod().Name;
|
|
|
|
try
|
|
{
|
|
serialPortDE70.DiscardInBuffer();
|
|
serialPortDE70.DiscardOutBuffer();
|
|
//sessions.Add(new CountSession());
|
|
|
|
// sessions[sessions.Count - 1].QuantityDenomi = (int[])TempQuantity.Clone();
|
|
|
|
//Debug.WriteLine(quantityStored);
|
|
|
|
var previousCassetData = AppData.GetCassetteData();
|
|
|
|
var str = "BEFORE STORE \r\n[CASSETTE]" + AppData.GetNotesString(previousCassetData);
|
|
str += "\r\nSTORED: " + GetQuantityFromSessions(sessions, true);
|
|
str += "\r\nSTACKER: " + GetQuantityFromSessions(sessions, false);
|
|
Log.Information(str);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
|
|
if (CheckPreStoreValid(previousCassetData, AppData.MaxNotes, sessions))
|
|
{
|
|
cCmdRsp.SendXXCmd((byte)Command.CMD_DE_STORESTART);
|
|
bSuccess = WaitUntilCountReady(20);
|
|
if (!bSuccess)
|
|
{
|
|
cCmdRsp.SendXXCmd((byte)Command.CMD_DE_STORESTART);
|
|
bSuccess = WaitUntilCountReady(20);
|
|
}
|
|
|
|
var newCasstData = AppData.GetCassetteData();
|
|
|
|
str = "AFTER STORE \r\n[CASSETTE]" + AppData.GetNotesString(newCasstData);
|
|
Log.Information(str);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
|
|
bool bValid = CheckStoreValid(previousCassetData, newCasstData, sessions);
|
|
if (bValid)
|
|
{
|
|
if (bSuccess)
|
|
{
|
|
foreach (var item in sessions)
|
|
{
|
|
item.IsStored = true;
|
|
}
|
|
quantityStored = UpdateTotalQuantity();
|
|
Log.Information("STORE SUCCESS: " + GetShortInforFromCountItems());
|
|
}
|
|
else
|
|
{
|
|
Log.Error("STORE FAIL: " + GetShortInforFromCountItems());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
var customerId = AppData.CurrentCustomerAccount == null ? "" : AppData.CurrentCustomerAccount.CustomerId;
|
|
str = $"PHIÊN GIAO DỊCH KHÔNG HỢP LỆ (SỐ TIỀN GIAO DỊCH KHÔNG KHỚP), VUI LÒNG BÁO CÁO LẠI CHI NHÁNH" +
|
|
$"\r\nMÃ GD: {AppData.GetTransactionCode()} " +
|
|
$"\r\nMÁY: {Environment.MachineName}" +
|
|
$"\r\nMÃ NV: {customerId}";
|
|
Log.Information(str);
|
|
ShowError(str);
|
|
});
|
|
|
|
}
|
|
Thread.Sleep(1000);
|
|
}
|
|
else
|
|
{
|
|
str = "KÉT ĐÃ ĐẦY ĐỀ NGHỊ LẤY LẠI TIỀN VÀ KẾT THÚC GIAO DỊCH, VUI LÒNG BÁO CÁO LẠI CHI NHÁNH";
|
|
Log.Information(str);
|
|
DoCheck();
|
|
EndSession(COUNTINGSTATE.FULLIFSTORE,str);
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
bSuccess = false;
|
|
Log.Fatal(ex, currentMethod);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
private bool DoStart()
|
|
{
|
|
bool bSuccess = true;
|
|
InitSession();
|
|
string currentMethod = MethodBase.GetCurrentMethod().Name;
|
|
AppData.IsInTransaction = true;
|
|
try
|
|
{
|
|
|
|
serialPortDE70.DiscardInBuffer();
|
|
serialPortDE70.DiscardOutBuffer();
|
|
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();
|
|
}
|
|
if (cCmdRsp.recv_dat.dat[0]!=0x40)
|
|
{
|
|
var strRcvData = cCmdRsp.GetRecvDat();
|
|
bSuccess = false;
|
|
|
|
var state = GetCDMState();
|
|
var str = $"START_ERROR: {strRcvData}, STATUS: {state.GetFullStatus()}";
|
|
Log.Error(str);
|
|
AppData.DeviceStatus.Description = str;
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
bSuccess = false;
|
|
Log.Fatal(ex, currentMethod);
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
private bool DoEnd()
|
|
{
|
|
bool bSuccess = false;
|
|
var state = GetCDMState();
|
|
StopTimers();
|
|
Log.Information("CDM State: " + JsonConvert.SerializeObject(state));
|
|
var lstEnabledControls = new List<Control> { btnEnd, btnCountStart };
|
|
if (state.IsNotesInEscrow > 0)
|
|
{
|
|
btnEnd.IsEnabled = true;
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỂN RA KHỎI NGĂN PHỤ HOẶC ẤN LƯU TRỮ ĐỂ TIẾP TỤC", true,true);
|
|
}
|
|
else if (state.IsNotesInRejectPocket > 0 || state.IsRejectPocketFull > 0)
|
|
{
|
|
btnEnd.IsEnabled = true;
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỂN RA KHỎI NGĂN KHÔNG HỢP LỆ ĐỂ TIẾP TỤC", true, true);
|
|
}
|
|
else if(state.IsNotesInHopper>0)
|
|
{
|
|
btnEnd.IsEnabled = true;
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỂN RA KHỎI NGĂN NỘP ĐỂ TIẾP TỤC", true, true);
|
|
}
|
|
else
|
|
{
|
|
bSuccess = true;
|
|
AppData.WDTCount = 0;
|
|
EndSession();
|
|
|
|
btnStart.IsEnabled = true;
|
|
btnLogout.IsEnabled = true;
|
|
|
|
ResetTimers();
|
|
}
|
|
return bSuccess;
|
|
}
|
|
private bool DoLogout()
|
|
{
|
|
bool bSuccess = false;
|
|
var state = GetCDMState();
|
|
Log.Information("CDM State: " + JsonConvert.SerializeObject(state));
|
|
InitLvCountItems();
|
|
if (state.IsNotesInEscrow > 0)
|
|
{
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỂN RA KHỎI NGĂN PHỤ HOẶC ẤN LƯU TRỮ ĐỂ TIẾP TỤC", true);
|
|
}
|
|
else if (state.IsNotesInRejectPocket > 0 || state.IsRejectPocketFull > 0)
|
|
{
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỂN RA KHỎI NGĂN KHÔNG HỢP LỆ ĐỂ TIẾP TỤC", true);
|
|
}
|
|
else //if (double.Parse(lvCountItems[10].Value)== 0)
|
|
{
|
|
bSuccess = true;
|
|
ResetSessions();
|
|
BackToWelcomeScreen();
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
private void EndSession(COUNTINGSTATE _CountingState =0, string? strMessage=null)
|
|
{
|
|
string currentMethod = MethodBase.GetCurrentMethod().Name;
|
|
|
|
//Remove sessions with store flag is false
|
|
|
|
sessions.RemoveAll(item => !item.IsStored);//Xóa các GD chưa lưu
|
|
UpdateListViewCountItems(); //Cập nhật lại danh sách hiển thị
|
|
|
|
var totalQuantity = lvCountItems[10].Quantity;
|
|
var totalValue = lvCountItems[10].Value;
|
|
|
|
try
|
|
{
|
|
Log.Information(currentMethod);
|
|
serialPortDE70.DiscardInBuffer();
|
|
serialPortDE70.DiscardOutBuffer();
|
|
|
|
if (double.Parse(totalValue) > 0)
|
|
{
|
|
var data2Send = new CountingData2Send
|
|
{
|
|
TransactionCode = AppData.GetTransactionCode(),
|
|
Sessions = sessions,
|
|
MachineId = Environment.MachineName,
|
|
UserId = AppData.CurrentCustomerAccount.CustomerId,
|
|
MachineTime = DateTime.Now.ToString("yyyyMMddHHmmss"),
|
|
GenuineNotes = quantityStored,
|
|
CountingState= (int)_CountingState
|
|
};
|
|
|
|
SyncData(data2Send);//Lưu CSDL và đồng bộ
|
|
//Reset all and ready to next session
|
|
|
|
if (isPrinterActivated)
|
|
{
|
|
if (printerFlag == true)
|
|
{
|
|
if (double.Parse(totalValue) > 0)
|
|
PrintReceipt();
|
|
printerFlag = false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
String strNotify = $"BẠN VỪA THỰC HIỆN NỘP TIỀN VÀO MÁY CDM:\r\n"
|
|
+ $"SỐ LƯỢNG TỜ: {totalQuantity}\r\n"
|
|
+ $"SỐ TIỀN: {totalValue} VND\r\n";
|
|
if (AppData.CurrentCustomerAccount != null)
|
|
{
|
|
var strTransactionCode = AppData.GetTransactionCode();
|
|
strNotify = "MÃ GD: "+strTransactionCode + "\r\n" + strNotify;
|
|
|
|
}
|
|
if(strMessage!=null)
|
|
{
|
|
strNotify += strMessage;
|
|
}
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
mainWindow.ShowInformationScreen(strNotify, false, false);
|
|
});
|
|
ResetSessions();
|
|
StartWelcomeTimer();
|
|
}
|
|
else if(strMessage!=null)//Không nộp tiền nhưng yêu cầu thông báo trước khi kết thúc
|
|
{
|
|
var strNotify = "";
|
|
if (AppData.CurrentCustomerAccount != null)
|
|
{
|
|
var strTransactionCode = AppData.GetTransactionCode();
|
|
strNotify = "MÃ GD: "+strTransactionCode + "\r\n" + strNotify;
|
|
|
|
}
|
|
if (strMessage != null)
|
|
{
|
|
strNotify += strMessage;
|
|
}
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
mainWindow.ShowInformationScreen(strNotify, false, false);
|
|
});
|
|
ResetSessions();
|
|
StartWelcomeTimer();
|
|
}
|
|
else//Không nộp tiền và không có thông báo --> kết thúc luôn
|
|
{
|
|
mainWindow.ShowWelcomeScreen();
|
|
}
|
|
if (AppData.CurrentCustomerAccount != null)
|
|
AppData.CurrentCustomerAccount.TransactionCode = "";
|
|
|
|
AppData.IsInTransaction = false;
|
|
//SendData2Server
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Fatal(ex, currentMethod);
|
|
}
|
|
}
|
|
|
|
private async Task SyncData(CountingData2Send data2Send)
|
|
{
|
|
Log.Information("Saving data to DB: " + JsonConvert.SerializeObject(data2Send));
|
|
var history = Save2DB(data2Send);
|
|
Log.Information("Sending data to server: "+JsonConvert.SerializeObject(data2Send));
|
|
bool bSuccess = await APIModels.SendCountingData(data2Send);
|
|
if (bSuccess)
|
|
{
|
|
history.IsSent = true;
|
|
Update2DB(history);
|
|
Log.Information("Sending data to server successfully");
|
|
}
|
|
else
|
|
{
|
|
Log.Information("Sending data to server failed");
|
|
}
|
|
}
|
|
|
|
|
|
public History Save2DB(CountingData2Send data2Send)
|
|
{
|
|
var data = JsonConvert.SerializeObject(data2Send);
|
|
var history = new History
|
|
{
|
|
Data = data,
|
|
DepositTime = DateTime.Now,
|
|
IsSent = false,
|
|
UserCode = AppData.CurrentCustomerAccount.CustomerId
|
|
};
|
|
try
|
|
{
|
|
using (var db = new CDMDbContext())
|
|
{
|
|
db.Histories.Add(history);
|
|
db.SaveChanges();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Fatal(ex,"Save2DB Exception");
|
|
}
|
|
return history;
|
|
}
|
|
public History Update2DB(History history)
|
|
{
|
|
|
|
try
|
|
{
|
|
using (var db = new CDMDbContext())
|
|
{
|
|
db.Histories.Update(history);
|
|
db.SaveChanges();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Fatal(ex,"Update2DB Exception");
|
|
}
|
|
return history;
|
|
}
|
|
|
|
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.ShowErrorScreen(strError);
|
|
}
|
|
|
|
public CDMSTATE GetCDMState()
|
|
{
|
|
return AppData.GetCDMState();
|
|
}
|
|
private bool InitSession()
|
|
{
|
|
try
|
|
{
|
|
//Check status
|
|
var cdmState = GetCDMState();
|
|
|
|
if (cdmState.IsCassetteFull != 0)
|
|
{
|
|
mainWindow.ShowCollectionScreen();
|
|
return false;
|
|
}
|
|
else if (cdmState.IsNotesInEscrow != 0||cdmState.IsNotesInRejectPocket!=0||cdmState.IsNotesInHopper!=0)
|
|
{
|
|
mainWindow.ShowInformationScreen("ĐỀ NGHỊ LẤY TIỀN RA KHỎI NGĂN NỘP HOẶC NGĂN REJECT ĐỂ TIẾP TỤC");
|
|
}
|
|
else
|
|
{
|
|
ResetSessions();
|
|
return true;
|
|
}
|
|
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
Log.Fatal(ex,"InitSession");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void ResetSessions()
|
|
{
|
|
InitLvCountItems();
|
|
sessions.Clear();
|
|
quantityStored = 0;
|
|
maxQuantitySheet = 0;
|
|
cCmdRsp.SendXXCmd((byte)Command.CMD_DE_UNLOCK);
|
|
}
|
|
|
|
private void PrintReceipt()
|
|
{
|
|
Log.Information("PrintReceipt");
|
|
var shopName = AppData.CurrentCustomerAccount.Name;
|
|
var shopCode = AppData.CurrentCustomerAccount.CustomerId;
|
|
var tradingCode = AppData.GetTransactionCode();// "TRA04052024CDM";
|
|
var storeAccountNumber = AppData.CurrentCustomerAccount.CustomerId;
|
|
var currentTime = DateTime.Now;
|
|
var printDocument = new PrintDocument();
|
|
|
|
var strLogoAM= System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logo\\logoAeonmall.png");
|
|
var strLogoVietin = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logo\\logoVietin.png");
|
|
System.Drawing.Image LogoAeonMall = System.Drawing.Image.FromFile(strLogoAM);
|
|
System.Drawing.Image LogoVietin = System.Drawing.Image.FromFile(strLogoVietin);
|
|
|
|
printDocument.PrinterSettings.PrinterName = "CUSTOM K80";
|
|
printDocument.PrintPage += (sender, e) =>
|
|
{
|
|
int fontSize = 8;
|
|
int lineSpace = 20;
|
|
float marginLeft = 25;
|
|
float marginTop = 5;
|
|
float width = 275;
|
|
float height = 280;
|
|
|
|
float LogoAeonWidth = 90; // Chiều rộng của LogoAeon
|
|
float LogoAeonHeight = 30; // Chiều cao của LogoAeon
|
|
float LogoAeonX = marginLeft + 25; // Đặt LogoAeon ở giữa theo chiều ngang
|
|
float LogoAeonY = marginTop + 10; // Khoảng cách từ mép trên của viền đến LogoAeon
|
|
|
|
float LogoVietinWidth = 90; // Chiều rộng của LogoVietin
|
|
float LogoVietinHeight = 30; // Chiều cao của LogoVietin
|
|
float LogoVietinX = marginLeft + 165; // Đặt LogoVietin ở giữa theo chiều ngang
|
|
float LogoVietinY = marginTop + 10; // Khoảng cách từ mép trên của viền đến LogoVietin
|
|
|
|
e.Graphics.DrawImage(LogoVietin, LogoVietinX, LogoVietinY, LogoVietinWidth, LogoVietinHeight);
|
|
e.Graphics.DrawImage(LogoAeonMall, LogoAeonX, LogoAeonY, LogoAeonWidth, LogoAeonHeight);
|
|
|
|
|
|
e.Graphics.DrawImage(LogoVietin, LogoVietinX, LogoVietinY, LogoVietinWidth, LogoVietinHeight);
|
|
e.Graphics.DrawImage(LogoAeonMall, LogoAeonX, LogoAeonY, LogoAeonWidth, LogoAeonHeight);
|
|
|
|
e.Graphics.DrawRectangle(new System.Drawing.Pen(System.Drawing.Color.Black, 1), marginLeft, marginTop, width, height);
|
|
|
|
|
|
e.Graphics.DrawString("Biên nhận nộp tiền", new Font("Arial", 12, System.Drawing.FontStyle.Bold), System.Drawing.Brushes.Black, new PointF(80, 50));
|
|
e.Graphics.DrawString("Mã máy CDM: "+Environment.MachineName, new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 1 + 65));
|
|
e.Graphics.DrawString("Thời gian giao dịch: " + currentTime.ToString("dd/MM/yyyy HH:mm:ss"), new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 2 + 65));
|
|
e.Graphics.DrawString("Mã giao dịch: " + tradingCode, new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 3 + 65));
|
|
e.Graphics.DrawString("Mã Gian hàng: " + shopCode, new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 4 + 65));
|
|
e.Graphics.DrawString("Tên Gian hàng: " + shopName, new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 5 + 65));
|
|
e.Graphics.DrawString("Số tài khoản gian hàng: " + storeAccountNumber, new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 6 + 65));
|
|
e.Graphics.DrawString("Nội dung giao dịch: Nop doanh so tien mat_", new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 7 + 65));
|
|
e.Graphics.DrawString(AppData.GetNumberPartFromMerchantCode(shopCode), new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 8 + 65));
|
|
e.Graphics.DrawString("Số tiền nộp: " + lvCountItems[10].Value, new Font("Arial", fontSize), System.Drawing.Brushes.Black, new PointF(50, lineSpace * 9 + 65));
|
|
e.Graphics.DrawString("*****Xin cám ơn*****", new Font("Arial", 7), System.Drawing.Brushes.Black, new PointF(120, lineSpace * 10 + 65));
|
|
// 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();
|
|
AppData.UpdatePrintingCountToStatusFile();
|
|
}
|
|
|
|
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
|
|
{
|
|
EndTransaction();
|
|
}
|
|
public void ResetTimers()
|
|
{
|
|
StopTimers();
|
|
StartTimers();
|
|
}
|
|
|
|
public void StartTimers()
|
|
{
|
|
if(warningTimer!=null && endsessionTimer != null)
|
|
{
|
|
warningTimer.Start();
|
|
endsessionTimer.Start();
|
|
}
|
|
|
|
}
|
|
|
|
public void StopTimers()
|
|
{
|
|
if(warningTimer!=null && endsessionTimer !=null)
|
|
{
|
|
warningTimer.Stop();
|
|
endsessionTimer.Stop();
|
|
}
|
|
|
|
}
|
|
|
|
private void ResetButtons()
|
|
{
|
|
btnStart.IsEnabled = false;
|
|
btnCountStart.IsEnabled = false;
|
|
btnCheck.IsEnabled = false;
|
|
btnStoreStart.IsEnabled = false;
|
|
btnEnd.IsEnabled = false;
|
|
btnLogout.IsEnabled = false;
|
|
}
|
|
|
|
|
|
|
|
private Button _previousClickedButton = null;
|
|
private void btnCommon_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
|
|
var btn = sender as Button;
|
|
if (_previousClickedButton != null)
|
|
{
|
|
_previousClickedButton.BorderBrush = System.Windows.Media.Brushes.Transparent;
|
|
_previousClickedButton.BorderThickness = new Thickness(1);
|
|
}
|
|
|
|
// Set the border of the currently clicked button
|
|
btn.BorderBrush = System.Windows.Media.Brushes.DarkRed;
|
|
btn.BorderThickness = new Thickness(3);
|
|
|
|
// Update the previously clicked button reference
|
|
_previousClickedButton = btn;
|
|
SoundManager.StartButtonPressSound();
|
|
// Console.Beep(800, 200);
|
|
StopTimers();
|
|
bool bResult = false;
|
|
if (btn==btnStart)
|
|
{
|
|
Log.Information("Deposit starting");
|
|
Log.Information("User: " + AppData.CurrentCustomerAccount.CustomerId);
|
|
Log.Information("1. Start starting");
|
|
ResetButtons();
|
|
bResult = DoStart();
|
|
if (bResult)
|
|
{
|
|
btnCountStart.IsEnabled = true;
|
|
ResetTimers();
|
|
Log.Information("1. Start completed");
|
|
}
|
|
else
|
|
{
|
|
btnStart.IsEnabled = true;
|
|
btnLogout.IsEnabled = true;
|
|
|
|
Log.Information("1. Start failed");
|
|
}
|
|
}
|
|
else if(btn==btnCountStart)
|
|
{
|
|
|
|
Log.Information("2. Count starting");
|
|
ResetButtons();
|
|
bResult = DoCountStart();
|
|
Task.Run(() =>
|
|
{
|
|
taskCounting.Wait();
|
|
var state = GetCDMState();
|
|
if (state.IsError > 0)
|
|
{
|
|
string str = "ĐÃ XẢY RA LỖI TRONG QUÁ TRÌNH NỘP TIỀN";
|
|
Log.Information(str);
|
|
AppData.DeviceStatus.Description = "COUNT_ERROR:"+state.GetFullStatus();
|
|
APIModels.SendEvent(AppData.DeviceStatus);
|
|
DoCheck();
|
|
EndSession(COUNTINGSTATE.FULLIFSTORE, str);
|
|
}
|
|
else if (state.IsStackerFull>0) {
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
btnCheck.IsEnabled = true;
|
|
btnStoreStart.IsEnabled = true;
|
|
ResetTimers();
|
|
Log.Information("2. Count completed");
|
|
});
|
|
}
|
|
else
|
|
{
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
btnCountStart.IsEnabled = true;
|
|
btnCheck.IsEnabled = true;
|
|
btnStoreStart.IsEnabled = true;
|
|
ResetTimers();
|
|
Log.Information("2. Count completed");
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
|
|
}
|
|
else if(btn==btnCheck)
|
|
{
|
|
Log.Information($"3. Check starting");
|
|
ResetButtons();
|
|
bResult = DoCheck();
|
|
btnCountStart.IsEnabled= true;
|
|
ResetTimers();
|
|
if (bResult)
|
|
Log.Information($"3. Check completed");
|
|
else
|
|
Log.Information($"3. Check failed");
|
|
}
|
|
else if (btn == btnStoreStart)
|
|
{
|
|
//TransitionToState("Store");
|
|
Log.Information("4. Store starting");
|
|
ResetButtons();
|
|
bResult = DoStoreStart();
|
|
btnEnd.IsEnabled= true;
|
|
btnCountStart.IsEnabled = true;
|
|
ResetTimers();
|
|
if(bResult)
|
|
Log.Information("4. Store completed");
|
|
else
|
|
Log.Information("4. Store failed");
|
|
}
|
|
else if (btn == btnEnd)
|
|
{
|
|
// TransitionToState("End");
|
|
Log.Information("5. End starting");
|
|
ResetButtons();
|
|
bResult = DoEnd();
|
|
//btnStart.IsEnabled = true;
|
|
//btnLogout.IsEnabled = true;
|
|
//ResetTimers();
|
|
if (bResult)
|
|
Log.Information("5. End Completed");
|
|
else
|
|
Log.Information("5. End failed");
|
|
}
|
|
else if (btn == btnLogout)
|
|
{
|
|
Log.Information("6. Exit starting");
|
|
bResult = DoLogout();
|
|
if (bResult)
|
|
Log.Information("6. Exit Completed");
|
|
else
|
|
Log.Information("6. Exit failed");
|
|
AppData.IsInTransaction = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|