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
});
}
}
});
}
}
}