using System; using System.Collections.Generic; using System.Linq; using Dfs.WayneChina.HengshanFPos.FPosDbManager.Model; namespace Dfs.WayneChina.HengshanFPos.FPosDbManager { /// /// Sequence number manager /// public class FPosDbManager { //private FPosDbContext _context; //private object syncObj = new object(); NLog.Logger logger = NLog.LogManager.LoadConfiguration("NLog.config").GetLogger("HengshanPos"); public FPosDbManager(FPosDbContext context) { //_context = context; } public bool ReserveTransaction(ushort fPosSqNo, int fcSqNo) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions.FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { if (trx.Reserved) { logger.Info($"Current transaction FPosSqNo: {trx.FPosSqNo}, FcSqNo: {trx.FcSqNo} is already reserved by another entity."); return false; } try { trx.Reserved = true; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.Reserved).IsModified = true; _context.SaveChanges(); logger.Info($"FPos SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, Reserved set to: true"); return true; } catch (Exception ex) { logger.Info($"Exception in ReserveTransaction: {ex}"); return false; } } else { logger.Info($"ReserveTransaction, FPos SqNo {fPosSqNo}, FC SqNo {fcSqNo}, the trx record not found!"); } return false; } } public bool UnreserveTransaction(ushort fPosSqNo, int fcSqNo) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions.FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { try { trx.Reserved = false; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.Reserved).IsModified = true; _context.SaveChanges(); logger.Info($"FPos SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, Reserved set to: false"); return true; } catch (Exception ex) { logger.Info($"Exception in ReserveTransaction: {ex}"); return false; } } else { logger.Info($"UnreserveTransaction, FPos SqNo {fPosSqNo}, FC SqNo {fcSqNo}, the trx record not found!"); } return false; } } public void AddMapping(ushort epsSqNo, int fcSqNo, int pumpId, int nozzleId, int token, decimal fillingAmount) { using (var _context = new FPosDbContext()) { var mapper = new FPosTransaction { Reserved = false, PumpId = pumpId, NozzleId = nozzleId, FPosSqNo = epsSqNo, FcSqNo = fcSqNo, ReleaseToken = token, FillingAmount = fillingAmount, PosItemId = Guid.Empty, CloudTrxId = Guid.Empty, Submitted = false }; logger.Info($"Adding mapping, FPos SqNo={epsSqNo}, FC SqNo={fcSqNo}, PumpId={pumpId}, NozzleId={nozzleId}"); try { _context.FPosTransactions.Add(mapper); _context.SaveChanges(); } catch (Exception ex) { logger.Info($"Exception in inserting a new mapper: {ex.Message}"); } } } #region Un-used /// /// Returns the sequence number of the current fueling or a new one for a new fueling. /// /// Pump id (fueling point id). /// Nozzle id of the current pump. /// Sequence number. public ushort GetSqNo(int pumpId, int nozzleId) { using (var _context = new FPosDbContext()) { try { logger.Info($"Checking pumpId = {pumpId} and nozzleId = {nozzleId}"); var sqNoList = _context.SequenceNumbers .OrderByDescending(s => s.TimeStamp) .ToList(); var sqNo = sqNoList .Where(s => s.Ongoing && s.PumpId == pumpId && s.NozzleId == nozzleId) .FirstOrDefault(); if (sqNo != null) { return sqNo.SqNo; } logger.Info($"No running transaction for current pumpId: {pumpId} and nozzleId: {nozzleId}, will add a new one."); var newSqNo = new SequenceNumber { PumpId = pumpId, NozzleId = nozzleId, Ongoing = true, //Field value in DB: 1 TimeStamp = DateTime.Now }; _context.SequenceNumbers.Add(newSqNo); _context.SaveChanges(); logger.Info($"The newly-added SqNo is: {newSqNo.SqNo}"); return newSqNo.SqNo; } catch (Exception ex) { logger.Info($"Exception in getting new Sequence number: {ex.Message}"); return 0; } } } #endregion public ushort GetNewSqNo(int pumpId, int nozzleId) { using (var _context = new FPosDbContext()) { try { var newSqNo = new SequenceNumber { PumpId = pumpId, NozzleId = nozzleId, Ongoing = true, //Field value in DB: 1 TimeStamp = DateTime.Now }; _context.SequenceNumbers.Add(newSqNo); _context.SaveChanges(); logger.Info($"Got new SqNo: {newSqNo.SqNo}"); return newSqNo.SqNo; } catch (Exception ex) { logger.Info($"Exception in creating new SqNo: {ex.Message}"); return 0; } } } public ushort GetCurrentSqNo(int pumpId, int nozzleId) { logger.Info($"Retrieving current SqNo for pumpId = {pumpId} and nozzleId = {nozzleId}"); using (var _context = new FPosDbContext()) { var sqNoList = _context.SequenceNumbers .OrderByDescending(s => s.TimeStamp) .ToList(); var sqNo = sqNoList .Where(s => s.Ongoing && s.PumpId == pumpId && s.NozzleId == nozzleId) .FirstOrDefault(); if (sqNo != null) { logger.Info($"SqNo for current fueling: {sqNo.SqNo}"); return sqNo.SqNo; } return 0; } } public ushort SetFillingDone(int pumpId, int nozzleId) { using (var _context = new FPosDbContext()) { try { var sqNo = _context.SequenceNumbers .Where(s => s.Ongoing && s.PumpId == pumpId && s.NozzleId == nozzleId) .OrderByDescending(n => n.SqNo) .FirstOrDefault(); if (sqNo == null) { logger.Info($"could not get a SqNo for pump id: {pumpId}, nozzle id: {nozzleId} "); } sqNo.Ongoing = false; _context.SequenceNumbers.Attach(sqNo); var entry = _context.Entry(sqNo); entry.Property(p => p.Ongoing).IsModified = true; _context.SaveChanges(); logger.Info($"Pump id: {pumpId}, nozzle id: {nozzleId}, filling done, ongoing set to false"); return sqNo.SqNo; } catch (Exception ex) { logger.Info($"Exception in setting filling to be done: {ex.Message}"); return 0; } } } public bool SetCardType(ushort fPosSqNo, int fcSqNo, int cardType) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions .FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { try { trx.CardType = cardType; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.CardType).IsModified = true; _context.SaveChanges(); logger.Info($"pump id:{trx.PumpId}, nozzle id:{trx.NozzleId}, FPOS SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, CardType set to {cardType}"); return true; } catch (Exception ex) { logger.Info($"Exception in setting card type: {ex}"); return false; } } else { logger.Info($"Set card type, Could not find the match in FPos database with FPos SqNo:{fPosSqNo} and FC SqNo:{fcSqNo}"); return false; } } } public bool SetActualPayAmount(ushort fPosSqNo, int fcSqNo, decimal amount) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions .FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { try { trx.ActualPayAmount = amount; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.ActualPayAmount).IsModified = true; _context.SaveChanges(); logger.Info($"Entry pump id:{trx.PumpId}, nozzle id:{trx.NozzleId}, FPOS SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, ActualPayAmount=>{amount}"); return true; } catch (Exception ex) { logger.Info($"Exception in setting actual payment amount: {ex}"); return false; } } else { logger.Info($"Could not find the match in FPos database with FPos SqNo:{fPosSqNo} and FC SqNo:{fcSqNo}"); return false; } } } public FPosTransaction GetCurrentTrx(ushort currentFPosSqNo, int currentFdcSqNo) { using (var _context = new FPosDbContext()) { return _context.FPosTransactions .FirstOrDefault(t => t.Reserved && t.FPosSqNo == currentFPosSqNo && t.FcSqNo == currentFdcSqNo); } } public bool SetPosItemId(ushort fPosSqNo, int fcSqNo, Guid itemId) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions .FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { try { trx.PosItemId = itemId; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.PosItemId).IsModified = true; _context.SaveChanges(); logger.Info($"FPos SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, PosItemId set to {itemId}"); return true; } catch (Exception ex) { logger.Info($"Exception in setting PosItemId: {ex}"); return false; } } else { logger.Info($"Set PosItemId, FPos SqNo {fPosSqNo}, FC SqNo {fcSqNo}, the trx record not found!"); } return false; } } public bool SetTransactionId(ushort fPosSqNo, int fcSqNo, Guid trxId) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions .FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { try { trx.CloudTrxId = trxId; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.CloudTrxId).IsModified = true; _context.SaveChanges(); logger.Info($"FPos SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, CloudTrxId set to {trxId}"); return true; } catch (Exception ex) { logger.Info($"Exception in setting CloudTrxId: {ex}"); return false; } } else { logger.Info($"Set CloudTrxId, FPos SqNo {fPosSqNo}, FC SqNo {fcSqNo}, the trx record not found!"); } return false; } } public bool SetTransactionSubmitted(ushort fPosSqNo, int fcSqNo, bool submitted) { using (var _context = new FPosDbContext()) { var trx = _context.FPosTransactions .FirstOrDefault(t => t.FPosSqNo == fPosSqNo && t.FcSqNo == fcSqNo); if (trx != null) { try { trx.Submitted = submitted; _context.FPosTransactions.Attach(trx); var entry = _context.Entry(trx); entry.Property(p => p.Submitted).IsModified = true; _context.SaveChanges(); logger.Info($"FPos SqNo:{fPosSqNo}, FC SqNo:{fcSqNo}, Submitted set to {submitted}"); return true; } catch (Exception ex) { logger.Info($"Exception in setting Submitted: {ex}"); return false; } } else { logger.Info($"Set Submitted, FPos SqNo {fPosSqNo}, FC SqNo {fcSqNo}, the trx record not found!"); } return false; } } public void CleanSqNo() { using (var _context = new FPosDbContext()) { try { var oldSqNos = _context .SequenceNumbers .Where(sq => sq.TimeStamp < DateTime.Now.Subtract(new TimeSpan(0, 1, 0))); var mappers = new List(); foreach (var sqNo in oldSqNos.ToList()) { var mapper = _context.FPosTransactions .FirstOrDefault(m => m.FPosSqNo == sqNo.SqNo && m.Submitted); if (mapper != null) mappers.Add(mapper); } _context.SequenceNumbers.RemoveRange(oldSqNos.ToArray()); _context.FPosTransactions.RemoveRange(mappers.ToArray()); _context.SaveChanges(); } catch (Exception ex) { logger.Info($"Exception in deleting submitted trx sequence no: {ex.Message}"); } } } /// /// Get the POS sequence number. /// /// pump id. /// nozzle id. /// FDC transaction sequence number. /// public int GetSqNoByMapping(int pumpId, int nozzleId, int fcSqNo) { using (var _context = new FPosDbContext()) { try { var mapper = _context.FPosTransactions .OrderBy(s => s.Id) .FirstOrDefault(s => s.PumpId == pumpId && s.NozzleId == nozzleId && s.FcSqNo == fcSqNo); if (mapper != null) { return mapper.FPosSqNo; } else { logger.Info($"Could not find the POS SqNo by pumpId={pumpId} and nozzleId={nozzleId} for FcSqNo={fcSqNo}"); return 0; } } catch (Exception ex) { logger.Info($"Exception in get SqNo by FcSqNo={fcSqNo} from mapping table: {ex.Message}"); return 0; } } } } }