using Edge.Core.Processor;using Edge.Core.IndustryStandardInterface.Pump;using Edge.Core.IndustryStandardInterface.Pump; using Dfs.WayneChina.HengshanFPos.FPosDbManager; using Dfs.WayneChina.SpsDbModels.Models; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Dfs.WayneChina.CardTrxManager.TrxScanner { /// /// Scans the IC card trx within Hengshan MySQL Sps_db (table TrdInfo) /// public class TrxScanner { private FPosDbManager fPosDbManager; public event EventHandler OnMatchingTrxFound; public event EventHandler OnNoMatchFound; private static NLog.Logger scannerLogger = NLog.LogManager.LoadConfiguration("Nlog.config").GetLogger("TrxScanner"); private readonly int retryLimit = 30; public TrxScanner(FPosDbManager fPosDbManager) { this.fPosDbManager = fPosDbManager; } public void StartScanAsync(int fdcPumpId, int epsSqNo, int fdcSeqNo, int releaseToken, FdcTransaction fdcTrx) { bool matchFound = false; int retries = retryLimit; //default set to Cash, which should be handled by indoor POS. var paymentMethod = "CASH"; Task.Run(async () => { using (var db = new SpsDbContext()) { TTrdinfo matchingRecord = null; while (retries-- >= 0) { try { scannerLogger.Debug($"Starting to find a matching record with Fdc Pump Id: {fdcPumpId}, EpsSeqNo: {epsSqNo}"); // //PaymodeId = 100, customer card payment //PaymodeId = 103, operator card payment // matchingRecord = db.TTrdinfo .OrderByDescending(t => t.TtctimeEnd) .FirstOrDefault(t => t.PumpNo == (byte)(fdcPumpId) && t.PaymodeId.HasValue && (t.PaymodeId.Value == 100 || t.PaymodeId.Value == 103) && t.SeqNo.HasValue && t.SeqNo == epsSqNo && t.Mon.Value != 0 && (t.TrdType == 0x00 || t.TrdType == 0x01) // 0x00 = Normal trx; 0x01 = Gray card trx. && (DateTime.Now - t.Ttctime).TotalMinutes < TimeSpan.FromDays(1).TotalMinutes); if (matchingRecord != null) { scannerLogger.Info("Found the matching record in MySql"); // only Customer IC Card paid trx treated as 'IC' paymentMethod = (matchingRecord.CardType.HasValue && (matchingRecord.CardType == (byte)ICCardType.Customer)) ? "IC" : "CASH"; if (matchingRecord.CardType.HasValue && (matchingRecord.CardType == (byte)ICCardType.Customer)) { fPosDbManager.SetCardType((ushort)matchingRecord.SeqNo, fdcSeqNo, (int)ICCardType.Customer); scannerLogger.Info($"match found, set card type to {ICCardType.Customer}"); } scannerLogger.Debug($" The matching trx is paid with MOP: {paymentMethod}"); matchFound = true; } else { scannerLogger.Info("No matching trx found in MySql at this round"); } } catch (Exception e) { scannerLogger.Info("Exception in finding the matching transaction: " + e); } if (matchFound || retries == 0) break; int round = retryLimit - retries; if (round <= 5) { scannerLogger.Info($"Scan count: {round}"); } else if (round > 5 && round <= 10) { scannerLogger.Info($"# Scan count: {round}"); } else if (round > 10 && round <= 20) { scannerLogger.Info($"## Scan count: {round}"); } else { scannerLogger.Info($"### Scan count: {round}"); } await Task.Delay(1000); } if (matchFound) { scannerLogger.Info($"CardNo: {matchingRecord.CardNo}, RealMon: {matchingRecord.RealMon}"); fPosDbManager.SetActualPayAmount((ushort)epsSqNo, fdcSeqNo, (decimal)matchingRecord.RealMon / 100); scannerLogger.Info($"Set ActualPayAmount { (decimal)matchingRecord.RealMon / 100} to FPOS trx SqNo: {epsSqNo}"); OnMatchingTrxFound?.Invoke(this, new MatchingTrxFoundEventArgs { MOP = paymentMethod, QRCode = matchingRecord.CardNo, FdcSqNo = fdcSeqNo, ReleaseToken = releaseToken, TrdInfo = matchingRecord, FdcTrx = fdcTrx }); } else { scannerLogger.Info("Could not find a match, giving up..."); OnNoMatchFound?.Invoke(this, new NoMatchFoundEventArgs { FdcSqNo = fdcSeqNo, ReleaseToken = releaseToken, FdcTrx = fdcTrx }); } } }); } } }