123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- using Applications.FDC;
- using Edge.Core.Database;
- using Edge.Core.Processor;
- using Edge.Core.IndustryStandardInterface.Pump;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Logging.Abstractions;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Common;
- using System.Linq;
- using System.Text;
- using Wayne.FDCPOSLibrary;
- using Edge.Core.Configuration;
- namespace Applications.PumpInfoToSinoChemPosSqlServerOrMySql
- {
- public abstract class AppBase
- {
- protected ILogger logger = NullLogger.Instance;
- protected FdcServerHostApp fdcServerHostApp;// = Configurator.Default.NozzleProductConfiguration.Mapping;
- protected AppConfigV1 appConfig;
- #region App config
- public class AppConfigV1
- {
- public string DatabaseConnStr { get; set; }
- public string JiaYouJiPeiZhi_TableName { get; set; }
- public List<YouJiConfigV1> YouJiConfigs { get; set; }
- }
- /// <summary>
- /// 对应一台物理油机
- /// </summary>
- public class YouJiConfigV1
- {
- /// <summary>
- /// 油机编号,由1开始编号
- /// 假设某个油站有四台油机, 则此号码分别为1、2、3、4
- /// </summary>
- public byte JiHao { get; set; }
- public List<YouMianConfigV1> YouMianConfigs { get; set; }
- }
- /// <summary>
- /// 每台物理油机有两个油面(A面或B面)
- /// </summary>
- public class YouMianConfigV1
- {
- /// <summary>
- /// 0 or 1, 0=A面 1=B面
- /// </summary>
- public int YouMianBianHao { get; set; }
- public List<YouQiangConfigV1> YouQiangConfigs { get; set; }
- }
- public class YouQiangConfigV1
- {
- /// <summary>
- /// 每台油面下的枪号,由1开始编号,作用范围是一个面,即换面则重置,重新从1开始。
- /// 如某个面上有2把枪,则此编号为1、2,另外一个面上有3把枪,则此编号为1、2、3.
- /// </summary>
- public int QiangHao { get; set; }
- /// <summary>
- /// 枪号,对应"加油流水表"和"油枪状态表"的枪号(jihao),整个油站的所有枪号由1开始编号
- ///
- /// 应该与FDC SERVER中的site level nozzle id相匹配对应。
- /// </summary>
- public int LuoJiQiangHao { get; set; }
- }
- #endregion
- protected AppBase(AppConfigV1 appConfig, IServiceProvider services)
- {
- this.appConfig = appConfig;
- var loggerFactory = services.GetRequiredService<ILoggerFactory>();
- this.logger = loggerFactory.CreateLogger("Application");
- }
- /// <summary>
- /// Truncate table jyjpz and jy_info, and then re-insert site nozzles info to them.
- /// </summary>
- /// <param name="dbConnCreator"></param>
- /// <param name="dbCommandCreator"></param>
- /// <returns></returns>
- protected bool ReCreatePumpLayoutToDatabase(Func<DbConnection> dbConnCreator,
- Func<DbCommand> dbCommandCreator)
- {
- try
- {
- #region truncate table [jyjpz] and [jy_info], and then insert data into table [jyjpz]
- // for now, always overwrite the whole table in POS database without further check for rows or columns level.
- using (var posConn = dbConnCreator())
- {
- /* configInFcDb structure like below */
- //" JiHao: " + oneRow["jiHao"] + ", sideId: " + oneRow["sideId"] +
- //", nozzleLogicalId: " + oneRow["HoseLogicalId"] +
- //", siteLevelNozzleId: " + oneRow["siteLevelNozzleId"]
- string bulkInsertCmd = "";
- const string sqlConcateAppendix = "Union all ";
- foreach (var youJiConfig in this.appConfig.YouJiConfigs)
- {
- foreach (var youMianConfig in youJiConfig.YouMianConfigs)
- {
- foreach (var youQiangConfig in youMianConfig.YouQiangConfigs)
- {
- bulkInsertCmd +=
- $"Select {youJiConfig.JiHao}, '{youMianConfig.YouMianBianHao}', {youQiangConfig.QiangHao}, {youQiangConfig.LuoJiQiangHao} {sqlConcateAppendix}";
- }
- }
- }
- var truncateAndInsertCmd = dbCommandCreator();
- truncateAndInsertCmd.Connection = posConn;
- truncateAndInsertCmd.CommandText =
- "TRUNCATE table " + this.appConfig.JiaYouJiPeiZhi_TableName + "; TRUNCATE table jy_info; INSERT " + this.appConfig.JiaYouJiPeiZhi_TableName + " (jihao, abtype, qianghao, luojiqh) " + bulkInsertCmd.Substring(0, bulkInsertCmd.Length - sqlConcateAppendix.Length);
- logger.LogInformation("truncateAndInsertSiteConfigCmd: " + truncateAndInsertCmd.CommandText);
- posConn.Open();
- truncateAndInsertCmd.ExecuteNonQuery();
- //return true;
- };
- #endregion
- #region insert data into table [jy_info]
- //foreach (var nozzle in sortedSiteNozzlesDataRows)//.Select(n => n["siteLevelNozzleId"]))
- //{
- //var siteLevelNozzleId = nozzle["siteLevelNozzleId"];
- foreach (var nozzle in fdcServerHostApp.FdcPumpControllers.SelectMany(c => c.Nozzles))
- {
- //var pumpId = int.Parse(nozzle["pumpid"].ToString());
- //var pump = fdcServerHostApp.FdcPumpControllers.First(f => f.PumpId == pumpId);
- //var nozzleLogicalId = int.Parse(nozzle["HoseLogicalId"].ToString());
- using (var posSqlConnection = dbConnCreator())
- {
- var bindingNozzleExtraInfo = this.fdcServerHostApp.GetNozzleExtraInfos()?.FirstOrDefault(f => f.PumpId == nozzle.PumpId
- && f.NozzleLogicalId == nozzle.LogicalId);
- try
- {
- //var gradeFriendlyName = rawProductNameToPosProductNameMapping[productNo];// Translator.GetFriendlyGradeName(SiteConfigUtility.Default.GetGradeName(siteLevelNozzleId));
- //SqliteDbContext dbContext = new SqliteDbContext();
- //var lastTrx = dbContext.PumpTransactionModels.OrderByDescending(f => f.SaleEndTime)
- // .FirstOrDefault(f => f.PumpId == pumpId && f.LogicalNozzleId == nozzleLogicalId);
- var lastTrx = fdcServerHostApp.GetAvailableFuelSaleTrxsWithDetailsAsync(nozzle.PumpId, nozzle.LogicalId, 1).Result.FirstOrDefault();
- var totalizer = fdcServerHostApp.GetFuelPointTotalsAsync(nozzle.PumpId, nozzle.LogicalId).Result;
- //new Tuple<float, float>((float)((lastTrx?.VolumeTotalizer / Math.Pow(10, pump.VolumeDecimalDigits) ?? 0)),
- // (float)((lastTrx?.AmountTotalizer / Math.Pow(10, pump.AmountDecimalDigits) ?? 0) * Math.Pow(10, 2)));
- var setPumpOnStartingCommand = dbCommandCreator();
- setPumpOnStartingCommand.Connection = posSqlConnection;
- setPumpOnStartingCommand.CommandText = this.InitTable_jy_info_SqlCommand(
- (bindingNozzleExtraInfo?.SiteLevelNozzleId ?? -1).ToString(),
- (bindingNozzleExtraInfo?.ProductName ?? "undefined"),
- totalizer.Item2, totalizer.Item1);
- logger.LogDebug("initTable_jy_info_Command: " + setPumpOnStartingCommand.CommandText);
- posSqlConnection.Open();
- setPumpOnStartingCommand.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- logger.LogError("executing initTable_jy_info_Command failed for siteLevelNozzleId: " + (bindingNozzleExtraInfo?.SiteLevelNozzleId ?? -1) + ", exception detail: " + ex);
- throw;
- }
- }
- }
- #endregion
- }
- catch (Exception ex)
- {
- logger.LogError("PerformCompareAndUpdate exceptioned, detail: " + ex);
- return false;
- }
- return true;
- }
- protected virtual string InitTable_jy_info_SqlCommand(string siteLevelNozzleId, string gradeFriendlyName,
- double totalizerVol, double totalizerAmt)
- {
- return string.Format("if not exists(select * from jy_info where jihao={0})" +
- " BEGIN" +
- " insert jy_info (jihao, status, youpin, qty, amount, fzqty, fzamount) values({0}, '{1}', N'{2}', 0, 0, '{3}', {4})" +
- " END",
- siteLevelNozzleId,
- 'F',
- gradeFriendlyName,
- totalizerVol, totalizerAmt);
- }
- /// <summary>
- /// attach pump event for inserting correlated data to database tables.
- /// </summary>
- /// <param name="dbConnCreator"></param>
- /// <param name="dbCommandCreator"></param>
- /// <returns></returns>
- protected bool HandlePumpStateChangeToDatabase(Func<DbConnection> dbConnCreator,
- Func<DbCommand> dbCommandCreator)
- {
- var siteLevelNozzldIdsInAppConfig = this.appConfig.YouJiConfigs.SelectMany(youJiConfig => youJiConfig.YouMianConfigs.SelectMany(youMianConfig => youMianConfig.YouQiangConfigs))
- .Select(youQiangConfig => youQiangConfig.LuoJiQiangHao);
- var siteLevelNozzldIdsInFdcServerApp = this.fdcServerHostApp.GetNozzleExtraInfos().Where(ri => ri.SiteLevelNozzleId.HasValue).Select(ri => ri.SiteLevelNozzleId.Value);
- var missedInFdcServerApp = siteLevelNozzldIdsInAppConfig.Except(siteLevelNozzldIdsInFdcServerApp);
- var missedInAppConfig = siteLevelNozzldIdsInFdcServerApp.Except(siteLevelNozzldIdsInAppConfig);
- if (missedInFdcServerApp.Any())
- {
- throw new ArgumentException("油枪(以此App中 全站枪号 为标识): "
- + missedInFdcServerApp.Select(n => n.ToString()).Aggregate((acc, n) => acc + ", " + n) + " 未配置于FdcServerApp中, 请配置后再试");
- }
- if (missedInAppConfig.Any())
- {
- throw new ArgumentException("油枪(以 FdcServerApp中的全站枪号 为标识): "
- + missedInAppConfig.Select(n => n.ToString()).Aggregate((acc, n) => acc + ", " + n) + " 未配置于此App中, 请配置后再试");
- }
- fdcServerHostApp.OnStateChange += (s, a) =>
- {
- var pump = s as IFdcPumpController;
- try
- {
- if (a.NewPumpState == LogicalDeviceState.FDC_READY)
- {
- /* indicate for nozzle if replaced back */
- var sizeLevelNozzleIdsOnPump = this.fdcServerHostApp.GetNozzleExtraInfos().Where(ri => ri.PumpId == pump.PumpId && ri.SiteLevelNozzleId.HasValue).Select(ri => ri.SiteLevelNozzleId.Value);
- if (!sizeLevelNozzleIdsOnPump.Any())
- {
- logger.LogInformation("Could not found any site level nozzle id defined on pump: " + pump.PumpId);
- return;
- }
- using (var posSqlConnection = dbConnCreator())
- {
- try
- {
- /* idle would not carry nozzle id, so here reset all nozzles on target pump.*/
- var setPumpOnIdleCommand = dbCommandCreator();
- setPumpOnIdleCommand.Connection = posSqlConnection;
- setPumpOnIdleCommand.CommandText = sizeLevelNozzleIdsOnPump.Select(
- siteLevelNozzleId =>
- string.Format(
- "Update jy_info set status = '{1}', qty=0, amount=0 where jihao = {0};", siteLevelNozzleId, 'F')
- ).Aggregate((acc, n) => acc + " " + n);
- logger.LogDebug("setPumpOnIdleCommand(via Fdc): " + setPumpOnIdleCommand.CommandText);
- posSqlConnection.Open();
- setPumpOnIdleCommand.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- logger.LogError("executing setPumpOnIdleCommand(via Fdc) failed, exception detail: " + ex);
- }
- }
- }
- else if (a.NewPumpState == LogicalDeviceState.FDC_CALLING)
- {
- using (var posSqlConnection = dbConnCreator())
- {
- try
- {
- var operatingNozzleLogicalId = a?.StateChangedNozzles?.FirstOrDefault()?.LogicalId ?? (byte)0;
- var bindingNozzleExtraInfo = this.fdcServerHostApp.GetNozzleExtraInfos()?.FirstOrDefault(f => f.PumpId == pump.PumpId
- && f.NozzleLogicalId == operatingNozzleLogicalId);
- //var updatePumpOnFuelingCommand =
- // new SqlCommand(string.Format("Update jy_info set [status] = '{1}', youpin = N'{2}', qty= {3}, amount= {4} where jihao = '{0}'"
- // , SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId, a?.Transaction?.Nozzle?.LogicalId ?? 0),
- // 'B',
- // gradeFriendlyName,
- // a.Transaction.Volumn,
- // a.Transaction.Amount),
- // posSqlConnection);
- var updatePumpOnFuelingCommand = dbCommandCreator();
- updatePumpOnFuelingCommand.Connection = posSqlConnection;
- updatePumpOnFuelingCommand.CommandText =
- string.Format("Update jy_info set status = '{1}' where jihao = '{0}';"
- , (bindingNozzleExtraInfo?.SiteLevelNozzleId ?? -1),
- 'B',
- (bindingNozzleExtraInfo?.ProductName ?? "undefined"));
- logger.LogDebug("updatePumpOnFuelingCommand: " + updatePumpOnFuelingCommand.CommandText);
- posSqlConnection.Open();
- updatePumpOnFuelingCommand.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- logger.LogError("executing updatePumpOnFuelingCommand failed, exception detail: " + ex);
- }
- }
- }
- }
- catch (Exception exx) { }
- };
- fdcServerHostApp.OnCurrentFuellingStatusChange += async (s, a) =>
- {
- try
- {
- var pump = s as IFdcPumpController;
- if (!a.Transaction.Finished)
- {
- //add some random drops to reduce the operations in db, this is for performance improve.
- if (DateTime.Now.Millisecond % 2 == 0 || DateTime.Now.Millisecond % 3 == 0) return;
- using (var posSqlConnection = dbConnCreator())
- {
- try
- {
- var bindingNozzleExtraInfo = this.fdcServerHostApp.GetNozzleExtraInfos().FirstOrDefault(f => f.PumpId == pump.PumpId
- && f.NozzleLogicalId == a.Transaction.Nozzle.LogicalId);
- //var updatePumpOnFuelingCommand =
- // new SqlCommand(string.Format("Update jy_info set [status] = '{1}', youpin = N'{2}', qty= {3}, amount= {4} where jihao = '{0}'"
- // , SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId, a?.Transaction?.Nozzle?.LogicalId ?? 0),
- // 'B',
- // gradeFriendlyName,
- // a.Transaction.Volumn,
- // a.Transaction.Amount),
- // posSqlConnection);
- var updatePumpOnFuelingCommand = dbCommandCreator();
- updatePumpOnFuelingCommand.Connection = posSqlConnection;
- updatePumpOnFuelingCommand.CommandText =
- string.Format("Update jy_info set youpin = N'{2}', qty= {3}, amount= {4} where jihao = '{0}';"
- , (bindingNozzleExtraInfo?.SiteLevelNozzleId ?? -1),
- "",
- (bindingNozzleExtraInfo?.ProductName ?? "undefined"),
- a.Transaction.Volumn / Math.Pow(10, pump.VolumeDecimalDigits),
- a.Transaction.Amount / Math.Pow(10, pump.AmountDecimalDigits));
- logger.LogDebug("updatePumpOnFuelingCommand: " + updatePumpOnFuelingCommand.CommandText);
- posSqlConnection.Open();
- updatePumpOnFuelingCommand.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- logger.LogError("executing updatePumpOnFuelingCommand failed, exception detail: " + ex);
- }
- }
- }
- else
- {
- #region totalizer value reading
- double volumeTotalizerValue = 0, amountTotalizerValue = 0;
- if (a.Transaction.VolumeTotalizer.HasValue)
- {
- /*indicates this kind of device will carry totalizer with trx, use it directly*/
- volumeTotalizerValue = a.Transaction.VolumeTotalizer.Value / Math.Pow(10, pump.VolumeDecimalDigits);
- amountTotalizerValue = a.Transaction.AmountTotalizer ?? -1;
- }
- else
- {
- /*indicates this kind of device will NOT carry totalizer with trx,
- * have to query it*/
- var queried = await fdcServerHostApp.GetFuelPointTotalsAsync(pump.PumpId, a.Transaction.Nozzle.LogicalId);
- volumeTotalizerValue = queried.Item2;
- amountTotalizerValue = queried.Item1;
- }
- #endregion
- var bindingNozzleExtraInfo = this.fdcServerHostApp.GetNozzleExtraInfos()?.FirstOrDefault(f => f.PumpId == pump.PumpId
- && f.NozzleLogicalId == a.Transaction.Nozzle.LogicalId);
- var posSqlConnection = dbConnCreator();
- using (posSqlConnection)
- {
- try
- {
- //var rawProductNo = nozzleProductConfig.FirstOrDefault(f => f.PumpId == pump.PumpId
- // && f.NozzleLogicalId == a.Transaction.Nozzle.LogicalId)?.ProductBarcode;
- //var totalizer = SiteConfigUtility.Default.GetTotalizer(e.Fuelling.Pump.Id, e.Fuelling.Nozzle.Id);
- var updateFuelingTrxDoneCommand = dbCommandCreator();
- updateFuelingTrxDoneCommand.Connection = posSqlConnection;
- updateFuelingTrxDoneCommand.CommandText =
- string.Format(
- "insert xiaofei2 (jihao, youpin, qty, danjia, amount, xf_date, xf_time, liushuino, fzqty, fzamount)" +
- " values({0}, N'{1}', {2}, {3}, {4}, '{5}', '{6}', {7}, {8}, {9})",
- (bindingNozzleExtraInfo?.SiteLevelNozzleId ?? -1),
- (bindingNozzleExtraInfo?.ProductName ?? "undefined"),
- a.Transaction.Volumn / Math.Pow(10, pump.VolumeDecimalDigits),
- a.Transaction.Price / Math.Pow(10, pump.PriceDecimalDigits),
- a.Transaction.Amount / Math.Pow(10, pump.AmountDecimalDigits),
- DateTime.Now.Date.ToString("yyyy-MM-dd"),
- DateTime.Now.ToString("HH:mm:ss"),
- a.Transaction.SequenceNumberGeneratedOnPhysicalPump,
- volumeTotalizerValue,
- amountTotalizerValue);
- logger.LogInformation("updateFuelingTrxDoneCommand: " + updateFuelingTrxDoneCommand.CommandText);
- posSqlConnection.Open();
- updateFuelingTrxDoneCommand.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- logger.LogError("executing updateFuelingTrxDoneCommand failed, exception detail: " + ex);
- }
- }
- using (var sqlConnection = dbConnCreator())
- {
- try
- {
- //var rawProductNo = nozzleProductConfig.First(f => f.PumpId == pump.PumpId
- // && f.NozzleLogicalId == operatingNozzleLogicalId).ProductBarcode;
- //var gradeFriendlyName = rawProductNameToPosProductNameMapping[rawProductNo.ToString()];
- //var updatePumpOnFuelingCommand =
- // new SqlCommand(string.Format("Update jy_info set [status] = '{1}', youpin = N'{2}', qty= {3}, amount= {4} where jihao = '{0}'"
- // , SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId, a?.Transaction?.Nozzle?.LogicalId ?? 0),
- // 'B',
- // gradeFriendlyName,
- // a.Transaction.Volumn,
- // a.Transaction.Amount),
- // posSqlConnection);
- var updatePumpOnFuelingCommand = dbCommandCreator();
- updatePumpOnFuelingCommand.Connection = sqlConnection;
- updatePumpOnFuelingCommand.CommandText =
- string.Format("Update jy_info set fzqty = '{1}', fzamount={2} where jihao = '{0}'",
- (bindingNozzleExtraInfo?.SiteLevelNozzleId ?? -1),
- volumeTotalizerValue,
- amountTotalizerValue);
- logger.LogDebug("updatePumpOnFuelingCommand: " + updatePumpOnFuelingCommand.CommandText);
- sqlConnection.Open();
- updatePumpOnFuelingCommand.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- logger.LogError("executing updatePumpOnFuelingCommand failed, exception detail: " + ex);
- }
- }
- }
- }
- catch (Exception exxx) { }
- };
- return true;
- }
- }
- }
|