123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667 |
- using Edge.Core.Configuration;
- using Edge.Core.Database;
- using Edge.Core.Database.Models;
- using Edge.Core.IndustryStandardInterface.ATG;
- using Edge.Core.IndustryStandardInterface.Pump;
- using Edge.Core.Processor;
- using Edge.Core.Processor.Dispatcher.Attributes;
- using Edge.Core.UniversalApi;
- using FdcServerHost;
- using Microsoft.EntityFrameworkCore;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text.Json;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using Wayne.FDCPOSInterface;
- using Wayne.FDCPOSLibrary;
- namespace Applications.FDC
- {
- [UniversalApi(Name = "OnFdcControllerStateChange", EventDataType = typeof(FdcPumpControllerOnStateChangeEventArg), Description = "When pump state changed, the event will fired")]
- [UniversalApi(Name = "OnError", EventDataType = typeof(string))]
- [UniversalApi(Name = "OnCurrentFuellingStatusChange", EventDataType = typeof(FdcServerTransactionDoneEventArg), Description = "When pump in fueling state, the fueling progress will be reported via this event")]
- [UniversalApi(Name = "OnFdcFuelSaleTransactinStateChange", EventDataType = typeof(FdcFuelSaleTransactinStateChangeEventArg), Description = "When pump transaction state changed, the event will fired")]
- [MetaPartsDescriptor(
- "lang-zh-cn:Fdc 服务器 Applang-en-us:Fdc Server App",
- "lang-zh-cn:用于管理已经配置和连接在此FCC中的所有加油机,并提供基于 IFSF-POS-FDC 协议定义的各类接口" +
- "lang-en-us:Used for manage all pumps configed and connected in this FCC, and providing varies of APIs based on IFSF-FDC-POS protocol",
- new[] { "lang-zh-cn:加油机lang-en-us:Pump", "lang-zh-cn:IfsfFdcServerlang-en-us:IfsfFdcServer" })]
- public class FdcServerHostApp : IAppProcessor
- {
- [UniversalApi(Description = "Get the overall pumps, nozzles info.")]
- public async Task<IEnumerable<object>> GetPumpsLayout(ApiData input)
- {
-
-
-
-
-
- return this.fdcPumpControllers.Select(p => new
- {
- p.Name,
- p.PumpId,
- Nozzles = p.Nozzles.Select(n => new
- {
- n.LogicalId,
- n.RealPriceOnPhysicalPump,
- SiteLevelNozzleId = this.nozzleExtraInfos.FirstOrDefault(c =>
- c.PumpId == n.PumpId && c.NozzleLogicalId == n.LogicalId)?.SiteLevelNozzleId,
- ProductBarcode = this.nozzleExtraInfos.FirstOrDefault(c =>
- c.PumpId == n.PumpId && c.NozzleLogicalId == n.LogicalId)?.ProductBarcode,
- ProductName = this.nozzleExtraInfos.FirstOrDefault(c =>
- c.PumpId == n.PumpId && c.NozzleLogicalId == n.LogicalId)?.ProductName,
- }),
- p.AmountDecimalDigits,
- p.VolumeDecimalDigits,
- p.PriceDecimalDigits,
- p.VolumeTotalizerDecimalDigits
- });
- }
- [UniversalApi(Description = "Get FuelSaleTrx Details info by searching conditions. </br>" +
- "Searching condition 1: by providing para.Name=='ReleaseToken' will ignore other conditions.</br>" +
- "Searching condition 2: para.Name=='PumpId' and para.Name=='LogicalNozzleId' must be provided, and para.Name=='TransactionNumber' is optional.")]
- public async Task<IEnumerable<object>> GetFuelSaleTrxDetailsAsync(ApiData input)
- {
- if (input == null || input.Parameters == null || !input.Parameters.Any()) throw new ArgumentException(nameof(input));
- List<FuelSaleTransaction> transactions;
- if (int.TryParse(input.Parameters.FirstOrDefault(p => p.Name.ToLower() == "releasetoken")?.Value, out int targetReleaseToken))
- {
- SqliteDbContext dbContext = new SqliteDbContext();
- transactions = await dbContext.PumpTransactionModels.Where(t => t.ReleaseToken == targetReleaseToken).ToListAsync();
- }
- else
- {
- if (!int.TryParse(input.Parameters.FirstOrDefault(p => p.Name.ToLower() == "pumpid")?.Value, out int targetPumpId)
- || !int.TryParse(input.Parameters.FirstOrDefault(p => p.Name.ToLower() == "logicalnozzleid")?.Value, out int targetLogicalNozzleId))
- throw new ArgumentException("Must provide valid parameter value for PumpId and LogicalNozzleId");
- var targetTransactionNumber = input.Parameters.FirstOrDefault(p => p.Name.ToLower() == "transactionnumber")?.Value;
- SqliteDbContext dbContext = new SqliteDbContext();
- int maxReturnDataCount = 50;
- if (string.IsNullOrEmpty(targetTransactionNumber))
- transactions = await dbContext.PumpTransactionModels.Where(t =>
- t.PumpId == targetPumpId && t.LogicalNozzleId == targetLogicalNozzleId).OrderByDescending(t => t.SaleStartTime).Take(maxReturnDataCount).ToListAsync();
- else
- transactions = await dbContext.PumpTransactionModels.Where(t =>
- t.PumpId == targetPumpId && t.LogicalNozzleId == targetLogicalNozzleId
- && t.TransactionSeqNumberFromPhysicalPump == targetTransactionNumber).OrderByDescending(t => t.SaleStartTime).Take(maxReturnDataCount).ToListAsync();
- }
- return transactions.Select(trx =>
- {
-
-
- var pumpHandler = this.fdcPumpControllers.FirstOrDefault(fpc => fpc.PumpId == trx.PumpId);
- return new
- {
- trx.ReleaseToken,
- trx.PumpId,
- trx.LogicalNozzleId,
- SiteLevelNozzleId = this.nozzleExtraInfos.FirstOrDefault(c =>
- c.PumpId == trx.PumpId && c.NozzleLogicalId == trx.LogicalNozzleId)?.SiteLevelNozzleId,
- trx.TransactionSeqNumberFromPhysicalPump,
- trx.ProductBarcode,
- ProductName = this.nozzleExtraInfos.FirstOrDefault(c =>
- c.PumpId == trx.PumpId && c.NozzleLogicalId == trx.LogicalNozzleId)?.ProductName,
- RawAmount = trx.Amount,
- Amount = pumpHandler == null ? (double?)null : (trx.Amount / Math.Pow(10, pumpHandler.AmountDecimalDigits)),
- RawVolume = trx.Volumn,
- Volume = pumpHandler == null ? (double?)null : trx.Volumn / Math.Pow(10, pumpHandler.VolumeDecimalDigits),
- RawPrice = trx.UnitPrice,
- Price = pumpHandler == null ? (double?)null : trx.UnitPrice / Math.Pow(10, pumpHandler.PriceDecimalDigits),
- RawAmountTotalizer = trx.AmountTotalizer,
- AmountTotalizer = pumpHandler == null ? (double?)null : trx.AmountTotalizer / Math.Pow(10, pumpHandler.AmountDecimalDigits),
- RawVolumeTotalizer = trx.VolumeTotalizer,
- VolumeTotalizer = pumpHandler == null ? (double?)null : trx.VolumeTotalizer / Math.Pow(10, pumpHandler.VolumeDecimalDigits),
- trx.State,
- trx.SaleStartTime,
- trx.SaleEndTime,
- };
- });
- }
- [UniversalApi]
- public int PumpCount => this.fdcPumpControllers?.Count ?? 0;
- [UniversalApi]
- public async Task<IEnumerable<object>> GetDeviceState(ApiData input)
- {
- List<object> resultList = new List<object>();
- foreach (var controller in this.FdcPumpControllers)
- {
- var state = await controller.QueryStatusAsync();
-
-
-
-
-
-
-
- List<object> nozzles = new List<object>();
- foreach (var n in controller.Nozzles)
- {
- if (n.VolumeTotalizer == null)
- {
- var result = await GetFuelPointTotalsAsync(controller.PumpId, n.LogicalId);
- n.VolumeTotalizer = (int?)(result.Item2 * Math.Pow(10, controller.VolumeDecimalDigits));
- }
- var Amount = GetLatestTransactionAmount(controller.PumpId, n.LogicalId);
- nozzles.Add(new { n.LogicalId, n.VolumeTotalizer, Amount });
- }
- resultList.Add(new { controller.PumpId, DeviceState = state, Nozzles = nozzles });
- }
- return resultList;
- }
- private int GetLatestTransactionAmount(int pumpId, int nozzleId)
- {
- var dueDate = DateTime.Now.Subtract(new TimeSpan(30, 0, 0, 0));
- SqliteDbContext dbContext = new SqliteDbContext();
- var trans = dbContext.PumpTransactionModels.Where(t => t.State != FuelSaleTransactionState.Cleared
- && t.PumpId == pumpId && t.LogicalNozzleId == nozzleId
- && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime).Take(1);
- return trans.Any() ? trans.FirstOrDefault().Amount : 0;
- }
- [UniversalApi(Description = "Get lastest 1000 count of Payable or Locked state fuel trx for nozzles." +
- "</br>input parameters are explained as below, " +
- "</br>para.Name==\"nozzleid\" nozzle logical id" +
- "</br>\"pumpid\" the target pump id" +
- "</br>Leave input as Null to get for all nozzles in all pumps")]
- public async Task<object> GetLastAvailableTransaction(ApiData input)
- {
- var nozzleId = -1;
- var pumpId = -1;
- if (input != null && !input.IsEmpty())
- {
- var temp = "";
- foreach (var p in input.Parameters)
- {
- temp += p.Name + " " + p.Value + " ";
- }
-
- nozzleId = input.Get("nozzleid", -1);
- pumpId = input.Get("pumpid", -1);
- }
- fdcLogger.LogDebug("GetAvailableTransactions for nozzle:{0},pump:{1}", nozzleId, pumpId);
- List<object> resultList = new List<object>();
- var result = await GetAvailableFuelSaleTrxsWithDetailsAsync(pumpId, nozzleId, 1000);
- if (result != null && result.Any())
- {
- var all = result.GroupBy(r => new { r.PumpId, r.LogicalNozzleId });
- foreach (var a in all)
- {
- var trans = a.Where(_ =>
- _.State == FuelSaleTransactionState.Payable || _.State == FuelSaleTransactionState.Locked);
- resultList.Add(new { a.Key.PumpId, a.Key.LogicalNozzleId, hasPayableTransactions = trans.Any(), trans.FirstOrDefault().VolumeTotalizer, trans.FirstOrDefault().Amount });
- }
- return resultList;
- }
- resultList.Add(new { LogicalNozzleId = nozzleId, PumpId = pumpId, hasPayableTransactions = false });
- return resultList;
- }
- private bool config_AutoAuthCallingPumps;
- private int config_MaxStackUnpaidTrxPerPump;
- private int config_ListeningPort;
- private FDCPOSInterfaceServer fdcServer;
- public string MetaConfigName { get; set; }
- private IEnumerable<NozzleExtraInfo> nozzleExtraInfos;
- private List<IFdcPumpController> fdcPumpControllers;
- private List<IFdcCommunicableController> fdcCommunicableControllers;
- private List<IAutoTankGaugeController> autoTankGaugeControllers = new List<IAutoTankGaugeController>();
- private IServiceProvider services;
- private Configurator configurator;
- private EventHandler onConfiguratorConfigFileChangedEventHandler;
- private System.Timers.Timer purgeDatabaseTimer;
- static ILogger fdcLogger;
- static ILogger cloudLogger;
- private object syncObject = new object();
- enum FDCLogicalState
- {
- FDC_LOGICAL_ST_UNLOCKED = 0,
- FDC_LOGICAL_ST_LOCKED = 1,
- };
- #region App configs
-
-
-
-
-
- public class AppConfigV1
- {
- public bool AutoAuthCallingPumps { get; set; }
- public int MaxStackUnpaidTrxPerPump { get; set; }
- public int FdcServerListeningPort { get; set; }
- public int? PurgePayableTrxOlderThanByMin { get; set; }
- public int? PurgeClearedTrxOlderThanByDay { get; set; }
- public List<AppProductConfigV1> ProductConfigs { get; set; }
- public List<AppPumpConfigV1> PumpConfigs { get; set; }
- }
- public class AppPumpConfigV1
- {
- public int PumpId { get; set; }
- public List<AppNozzleConfigV1> NozzleConfigs { get; set; }
- }
- public class AppProductConfigV1
- {
- public int ProductCode { get; set; }
- public string ProductName { get; set; }
- }
- public class AppNozzleConfigV1
- {
- public int NozzleLogicalId { get; set; }
- public int? SiteLevelNozzleId { get; set; }
- public int ProductCode { get; set; }
-
-
-
- public int? TankNumber { get; set; }
- public string Description { get; set; }
- }
- #endregion
-
-
-
-
-
-
-
-
- private static List<object> ResolveCtorMetaPartsConfigCompatibility(string incompatibleCtorParamsJsonStr)
- {
- var jsonParams = JsonDocument.Parse(incompatibleCtorParamsJsonStr).RootElement.EnumerateArray().ToArray();
-
- string uiTemplateVersionRegex = @"(?<=""UITemplateVersion""\:\"").+?(?="")";
- var match = Regex.Match(jsonParams.First().GetRawText(), uiTemplateVersionRegex, RegexOptions.IgnoreCase | RegexOptions.Multiline);
- if (match.Success)
- {
-
- var curVersion = match.Value;
- if (curVersion == "1.0")
- {
- var existsAppConfigV1 = JsonSerializer.Deserialize(jsonParams.First().GetRawText(), typeof(AppConfigV1));
-
-
-
-
-
- }
-
-
-
-
-
-
-
-
-
- }
- else
- {
-
-
- return new List<object>() {
- new AppConfigV1() {
- AutoAuthCallingPumps = false,
- FdcServerListeningPort = 4711,
- MaxStackUnpaidTrxPerPump = 3 } };
- }
- return new List<object>() {
- new AppConfigV1() {
- AutoAuthCallingPumps = false,
- FdcServerListeningPort = 4711,
- MaxStackUnpaidTrxPerPump = 3 } };
- }
- public Task Test(params object[] parameters)
- {
- if ((!this.fdcServer?.IsStarted) ?? false)
- throw new InvalidOperationException("Fdc server failed to start on a port");
- return Task.CompletedTask;
- }
- [ParamsJsonSchemas("appCtorParamsJsonSchema")]
- public FdcServerHostApp(AppConfigV1 appConfig, IServiceProvider services)
- {
- this.config_AutoAuthCallingPumps = appConfig.AutoAuthCallingPumps;
- this.config_MaxStackUnpaidTrxPerPump = appConfig.MaxStackUnpaidTrxPerPump;
- this.config_ListeningPort = appConfig.FdcServerListeningPort;
- if (appConfig.PurgeClearedTrxOlderThanByDay.HasValue || appConfig.PurgePayableTrxOlderThanByMin.HasValue)
- {
- this.purgeDatabaseTimer = new System.Timers.Timer();
- this.purgeDatabaseTimer.Interval = 1000 * 60;
- this.purgeDatabaseTimer.Elapsed += (s, a) =>
- {
- if (appConfig.PurgeClearedTrxOlderThanByDay.HasValue)
- {
- try
- {
- using (var dbContext = new SqliteDbContext())
- {
- var due = DateTime.Now.Subtract(new TimeSpan(appConfig.PurgeClearedTrxOlderThanByDay.Value, 0, 0, 0));
- var deleting = dbContext.PumpTransactionModels.Where(t => t.State == FuelSaleTransactionState.Cleared && t.PaidTime.HasValue && t.PaidTime <= due);
- dbContext.RemoveRange(deleting);
- var deletedRowCount = dbContext.SaveChanges();
- if (deletedRowCount > 0)
- fdcLogger.LogDebug($"PurgeClearedTrxOlderThanByDay purged: {deletedRowCount} rows");
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("PurgeClearedTrxOlderThanByDay exceptioned: " + exxx.ToString());
- }
- try
- {
- if (appConfig.PurgePayableTrxOlderThanByMin.HasValue)
- {
- using (var dbContext = new SqliteDbContext())
- {
- var due = DateTime.Now.Subtract(new TimeSpan(0, appConfig.PurgePayableTrxOlderThanByMin.Value, 0));
- var deleting = dbContext.PumpTransactionModels.Where(t => t.State == FuelSaleTransactionState.Payable && t.SaleStartTime.HasValue && t.SaleStartTime <= due);
- dbContext.RemoveRange(deleting);
- var deletedRowCount = dbContext.SaveChanges();
- if (deletedRowCount > 0)
- fdcLogger.LogDebug($"PurgePayableTrxOlderThanByMin purged: {deletedRowCount} rows");
- }
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("PurgePayableTrxOlderThanByMin exceptioned: " + exxx.ToString());
- }
- }
- };
- this.purgeDatabaseTimer.Start();
- }
- this.services = services;
- var loggerFactory = services.GetRequiredService<ILoggerFactory>();
- fdcLogger = loggerFactory.CreateLogger("DynamicPrivate_FdcServer");
- cloudLogger = loggerFactory.CreateLogger("CloudRestClient");
-
- this.nozzleExtraInfos = appConfig.PumpConfigs
- ?.SelectMany(p => p.NozzleConfigs,
- (p, ns) =>
- new NozzleExtraInfo()
- {
- PumpId = p.PumpId,
- NozzleLogicalId = ns.NozzleLogicalId,
- SiteLevelNozzleId = ns.SiteLevelNozzleId,
- ProductBarcode = ns.ProductCode,
- ProductName = appConfig.ProductConfigs?.FirstOrDefault(p => p.ProductCode == ns.ProductCode)?.ProductName,
- TankNumber = ns.TankNumber,
- Description = ns.Description,
- });
- FdcResourceArbitrator.fdcLogger = fdcLogger;
- this.fdcServer = new FDCPOSInterfaceServer(services);
- }
- public FdcServerHostApp(string autoAuthCallingPumps, int maxStackUnpaidTrxPerPump, int listeningPort
- , IServiceProvider services)
- {
-
- this.config_AutoAuthCallingPumps = autoAuthCallingPumps.ToLower() == "true" ? true : false;
- this.config_MaxStackUnpaidTrxPerPump = maxStackUnpaidTrxPerPump;
- this.config_ListeningPort = listeningPort;
- this.services = services;
- var loggerFactory = services.GetRequiredService<ILoggerFactory>();
- fdcLogger = loggerFactory.CreateLogger("DynamicPrivate_FdcServer");
- cloudLogger = loggerFactory.CreateLogger("CloudRestClient");
- this.configurator = services.GetService<Configurator>();
- this.nozzleExtraInfos = Configurator.Default.NozzleExtraInfoConfiguration.Mapping;
- FdcResourceArbitrator.fdcLogger = fdcLogger;
- this.fdcServer = new FDCPOSInterfaceServer(services);
- this.onConfiguratorConfigFileChangedEventHandler = (_, __) =>
- {
- try
- {
- var c = Configurator.Default.DeviceProcessorConfiguration.Processor
- .FirstOrDefault(p => p.Name == this.MetaConfigName);
- if (c == null) return;
- var newAutoAuthCallingPumps = c.Parameter.First(p => p.Name == "AutoAuthCallingPumps").Value.ToLower() == "true" ? true : false;
- var newMaxStackUnpaidTrxPerPump = int.Parse(c.Parameter.First(p => p.Name == "MaxStackUnpaidTrxPerPump").Value);
- if (this.config_AutoAuthCallingPumps != newAutoAuthCallingPumps)
- {
- fdcLogger.LogInformation("Configuration change detected on parameter: autoAuthCallingPumps, " +
- "will update its value from: " + this.config_AutoAuthCallingPumps + " to: " + newAutoAuthCallingPumps);
- this.config_AutoAuthCallingPumps = newAutoAuthCallingPumps;
- }
- if (this.config_MaxStackUnpaidTrxPerPump != newMaxStackUnpaidTrxPerPump)
- {
- fdcLogger.LogInformation("Configuration change detected on parameter: maxStackUnpaidTrxPerPump, " +
- "will update its value from: " + this.config_MaxStackUnpaidTrxPerPump + " to: " + newMaxStackUnpaidTrxPerPump);
- this.config_MaxStackUnpaidTrxPerPump = newMaxStackUnpaidTrxPerPump;
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("Configuration auto reload exceptioned: " + exxx);
- }
- };
- this.configurator.OnConfigFileChanged += this.onConfiguratorConfigFileChangedEventHandler;
- }
- public void Init(IEnumerable<IProcessor> processors)
- {
- this.fdcPumpControllers = new List<IFdcPumpController>();
- this.fdcPumpControllers.AddRange(
- processors.WithHandlerOrApp<IFdcPumpController>().SelectHandlerOrAppThenCast<IFdcPumpController>());
- foreach (var p in processors)
- {
- if (p.IsWithHandlerOrApp<IEnumerable<IFdcPumpController>>())
- {
- var pumpGroupHandler = p.SelectHandlerOrAppThenCast<IEnumerable<IFdcPumpController>>();
- this.fdcPumpControllers.AddRange(pumpGroupHandler);
-
- if (pumpGroupHandler.GetType().GetMethod("OnFdcServerInit")?.GetParameters()
- ?.FirstOrDefault()?.ParameterType?.IsAssignableFrom(typeof(Dictionary<string, object>)) ?? false)
- {
- pumpGroupHandler.GetType().GetMethod("OnFdcServerInit")?.Invoke(
- pumpGroupHandler,
- new[]{
- new Dictionary<string, object>() {
- { "NozzleProductMapping", this.nozzleExtraInfos }
- }
- });
- }
- }
- }
- if (this.fdcPumpControllers.GroupBy(p => p.PumpId).Any(g => g.Count() > 1))
- throw new ArgumentException("Duplicate PumpId in Fdc Pump Controllers, PumpId must be unique");
- this.fdcCommunicableControllers = new List<IFdcCommunicableController>();
- this.fdcCommunicableControllers.AddRange(processors.WithHandlerOrApp<IFdcCommunicableController>().SelectHandlerOrAppThenCast<IFdcCommunicableController>());
- this.autoTankGaugeControllers = new List<IAutoTankGaugeController>();
- this.autoTankGaugeControllers.AddRange(processors.WithHandlerOrApp<IAutoTankGaugeController>().SelectHandlerOrAppThenCast<IAutoTankGaugeController>());
- }
- public class Grouping<TKey, TElement> : List<TElement>, IGrouping<TKey, TElement>
- {
- public Grouping(TKey key) : base() => Key = key;
- public Grouping(TKey key, int capacity) : base(capacity) => Key = key;
- public Grouping(TKey key, IEnumerable<TElement> collection)
- : base(collection) => Key = key;
- public TKey Key { get; private set; }
- }
- public Task<bool> Start()
- {
-
- #region OnGetCountrySettings, OnLogOnReq and OnLogOffReq
- fdcServer.OnGetCountrySettingsReq += (string workstationID, string applicationSender, int requestID) =>
- {
- fdcLogger.LogDebug("OnGetCountrySettingsReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestID + ")");
- fdcServer.GetCountrySettings(workstationID, applicationSender, requestID, "Litre", "CNY", "Litre", "C", "3", ".", "CHN", "zh-cn", (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- };
- fdcServer.OnStartForecourtReq += (string workstationID, string applicationSender, int requestID) =>
- {
- fdcLogger.LogDebug("OnStartForecourtReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestID + ")");
- fdcServer.StartForecourt(workstationID, applicationSender, requestID, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- };
- fdcServer.OnLogOnReq += (string workstationID, string applicationSender, int requestId, int responsePort, int unsolicitedPort, int version) =>
- {
- fdcLogger.LogInformation("OnLogOnReq(wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", ver: " + version + ")");
- fdcServer.LogOn(workstationID, applicationSender, requestId, responsePort, unsolicitedPort, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- };
- fdcServer.OnLogOffReq += (string workstationID, string applicationSender, int requestId) =>
- {
- fdcLogger.LogInformation("OnLogOffReq(wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ")");
- fdcServer.LogOff(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- };
- #endregion
- #region reserve related
- fdcServer.OnLockNozzleReq += async (string workstationID, string applicationSender, int requestId, int deviceId, int NozzleNo) =>
- {
- try
- {
- fdcLogger.LogDebug("OnLockNozzleReq (wid: " + workstationID + ", appSender: "
- + applicationSender + ", requestId: " + requestId
- + ", deviceId: " + deviceId + ", NozzleNo: " + NozzleNo);
- var result = await this.LockNozzleAndNotifyAllFdcClientsAsync(int.Parse(workstationID), applicationSender, requestId, deviceId, NozzleNo);
- if (!result)
- fdcLogger.LogInformation(" LockNozzle failed");
- fdcLogger.LogDebug(" OnLockNozzleReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnLockNozzleReq exceptioned: " + exxx.ToString());
- }
- };
- fdcServer.OnUnlockNozzleReq += async (string workstationID, string applicationSender, int requestId, int deviceId, int NozzleNo) =>
- {
- try
- {
- fdcLogger.LogDebug("OnUnlockNozzleReq (wid: " + workstationID + ", appSender: "
- + applicationSender + ", requestId: " + requestId
- + ", deviceId: " + deviceId + ", NozzleNo: " + NozzleNo);
- var result = await this.UnlockNozzleAndNotifyAllFdcClientsAsync(int.Parse(workstationID), applicationSender, requestId, deviceId, NozzleNo);
-
-
-
-
- fdcLogger.LogDebug(" OnUnlockNozzleReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnUnlockNozzleReq exceptioned: " + exxx.ToString());
- }
- };
- fdcServer.OnReserveFuelPointReq += async (string workstationID, string applicationSender, int requestId, int deviceId) =>
- {
- try
- {
- fdcLogger.LogDebug("OnReserveFuelPointReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", deviceId: " + deviceId);
- var result = await FdcResourceArbitrator.Default.TryReserveFuelPointAsync(int.Parse(workstationID), deviceId);
- if (result)
- fdcServer.ReserveFuelPoint(workstationID, applicationSender, requestId, deviceId, deviceId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- else
- {
- fdcLogger.LogInformation(" ReserveFuelPoint failed");
- fdcServer.ReserveFuelPoint(workstationID, applicationSender, requestId, deviceId, deviceId, (int)ErrorCode.ERRCD_FPLOCK, OverallResult.Failure.ToString());
- }
- fdcLogger.LogDebug(" OnReserveFuelPointReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnReserveFuelPointReq exceptioned: " + exxx.ToString());
- fdcServer.ReserveFuelPoint(workstationID, applicationSender, requestId, deviceId, deviceId, (int)ErrorCode.ERRCD_OK, OverallResult.Failure.ToString());
- }
- };
- fdcServer.OnFreeFuelPointReq += async (string workstationID, string applicationSender, int requestId, int deviceId) =>
- {
- try
- {
- fdcLogger.LogDebug("OnFreeFuelPointReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", deviceId: " + deviceId);
- var result = await FdcResourceArbitrator.Default.TryUnreserveFuelPointAsync(int.Parse(workstationID), deviceId);
- if (result)
- fdcServer.FreeFuelPoint(workstationID, applicationSender, requestId, deviceId, deviceId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- else
- fdcServer.FreeFuelPoint(workstationID, applicationSender, requestId, deviceId, deviceId, (int)ErrorCode.ERRCD_OK, OverallResult.Failure.ToString());
- fdcLogger.LogDebug(" OnFreeFuelPointReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnFreeFuelPointReq exceptioned: " + exxx.ToString());
- fdcServer.FreeFuelPoint(workstationID, applicationSender, requestId, deviceId, deviceId, (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.Failure.ToString());
- }
- };
- fdcServer.OnLockFuelSaleTrxReq += async (string workstationID, string applicationSender, int requestId, int deviceId,
- int transactionNo, string releaseToken) =>
- {
- try
- {
- fdcLogger.LogDebug("OnLockFuelSaleTrxReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: "
- + requestId + ", deviceId: " + deviceId + ", transactionNo: " + transactionNo + ", releaseToken: " + releaseToken + ")");
- var result = await this.LockFuelSaleTrxAndNotifyAllFdcClientsAsync(int.Parse(workstationID), applicationSender, requestId, deviceId, transactionNo, int.Parse(releaseToken));
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (result == null)
- fdcLogger.LogDebug($" OnLockFuelSaleTrxReq(releaseToken: {releaseToken}) failed");
- fdcLogger.LogDebug($" OnLockFuelSaleTrxReq(releaseToken: {releaseToken}) done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnLockFuelSaleTrxReq exceptioned: " + exxx.ToString());
- try
- {
- fdcServer.LockFuelSaleTrx(workstationID, applicationSender, requestId, deviceId,
- transactionNo, releaseToken, (int)ErrorCode.ERRCD_TRANSLOCKED, 1, OverallResult.Failure.ToString());
- }
- catch (Exception eeee)
- {
- fdcLogger.LogError("Fdc server is trying to respond a failed LocFuelSaleTrx response to a fdcclient that issue current LockFuleSaleTrx request, but still failed with reason: " + eeee);
- }
- }
- };
- fdcServer.OnUnlockFuelSaleTrxReq += async (string workstationID, string applicationSender, int requestId, int deviceId,
- int transactionNo, string releaseToken) =>
- {
- try
- {
- fdcLogger.LogDebug("OnUnlockFuelSaleTrxReq (wid: " + workstationID + ", appSender: " + applicationSender
- + ", requestId: " + requestId + ", deviceId: " + deviceId + ", transactionNo: " + transactionNo
- + ", releaseToken: " + releaseToken);
- var result = await this.UnlockFuelSaleTrxAndNotifyAllFdcClientsAsync(int.Parse(workstationID), applicationSender, requestId, deviceId, transactionNo, int.Parse(releaseToken));
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (result == null)
- fdcLogger.LogDebug(" OnUnlockFuelSaleTrxReq failed");
- fdcLogger.LogDebug(" OnUnlockFuelSaleTrxReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnUnlockFuelSaleTrxReq exceptioned: " + exxx.ToString() + Environment.NewLine);
- try
- {
- fdcServer.UnlockFuelSaleTrx(workstationID, applicationSender, requestId, deviceId,
- transactionNo, releaseToken, (int)ErrorCode.ERRCD_TRANSLOCKED, 1, OverallResult.Failure.ToString());
- }
- catch (Exception eeee)
- {
- fdcLogger.LogError("Fdc server is trying to respond a failed UnlocFuelSaleTrx response to a fdcclient that issue current UnlockFuleSaleTrx request, but still failed with reason: " + eeee);
- }
- }
- };
- #endregion
- fdcServer.OnGetTankDataReq += async (string workstationID, string applicationSender, int requestID, int deviceId, int tankNo) =>
- {
- try
- {
- fdcLogger.LogDebug("OnGetTankDataReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestID + ", deviceId: " + deviceId + ", tankNo: " + tankNo + ")");
- if (this.autoTankGaugeControllers == null || !this.autoTankGaugeControllers.Any())
- {
- fdcLogger.LogDebug($" failed for OnGetTankDataReq since there's an empty AutoTankGaugeControllers list.");
- fdcServer.GetTankDataSend(workstationID, applicationSender, requestID,
- (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.DeviceUnavailable.ToString());
- return;
- }
- var atgController = this.autoTankGaugeControllers.FirstOrDefault();
- if (!atgController.Tanks.Any())
- {
- fdcLogger.LogDebug($" failed for OnGetTankDataReq since there's no Tanks at all in AutoTankGaugeController.");
- fdcServer.GetTankDataSend(workstationID, applicationSender, requestID,
- (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.DeviceUnavailable.ToString());
- return;
- }
- if (deviceId != -1
- && !atgController.Tanks.Any(t => t.TankNumber == deviceId))
- {
- fdcLogger.LogDebug($" failed for OnGetTankDataReq since there's no Tank with number: {deviceId} in AutoTankGaugeController.");
- fdcServer.GetTankDataSend(workstationID, applicationSender, requestID,
- (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.DeviceUnavailable.ToString());
- return;
- }
-
- if (deviceId == -1)
- {
- foreach (var tank in atgController.Tanks)
- {
- try
- {
- var tankReading = await atgController.GetTankReadingAsync(tank.TankNumber);
- fdcLogger.LogDebug($" GetTankReadingAsync for tankNumber: {tank.TankNumber} succeed, data-> { tankReading.ToString()}");
- fdcServer.GetTankDataAdd(workstationID, applicationSender, requestID,
- tank.TankNumber,
- tank.TankNumber, 0, 0,
- tankReading.Height ?? 0,
- tankReading.Volume ?? 0,
- tankReading.TcVolume ?? 0,
- tankReading.Temperature ?? 0,
- tankReading.Water ?? 0,
- 0,
- (int)ErrorCode.ERRCD_OK, (int)LogicalDeviceState.FDC_READY);
- }
- catch (Exception exx)
- {
- fdcLogger.LogInformation($" failed for GetTankReadingAsync for tankNumber: {tank.TankNumber} by exception: {exx}" +
- $"{Environment.NewLine} will skip this tank and continue on next tank...");
- continue;
- }
- }
- }
- else
- {
- var tankReading = await atgController.GetTankReadingAsync(deviceId);
- fdcLogger.LogDebug($" GetTankReadingAsync for tankNumber: " + deviceId + " succeed " +
- Environment.NewLine + tankReading.ToString());
- fdcServer.GetTankDataAdd(workstationID, applicationSender, requestID,
- deviceId,
- deviceId, 0, 0,
- tankReading.Height ?? 0,
- tankReading.Volume ?? 0,
- tankReading.TcVolume ?? 0,
- tankReading.Temperature ?? 0,
- tankReading.Water ?? 0,
- 0,
- (int)ErrorCode.ERRCD_OK, (int)LogicalDeviceState.FDC_READY);
- }
- fdcServer.GetTankDataSend(workstationID, applicationSender, requestID, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnGetTankDataReq exceptioned: " + exxx.ToString());
- fdcServer.GetTankDataSend(workstationID, applicationSender, requestID,
- (int)ErrorCode.ERRCD_BADVAL, OverallResult.Failure.ToString());
- }
- };
- fdcServer.OnGetProductTableReq += (string workstationID, string applicationSender, int requestID) =>
- {
- fdcLogger.LogDebug("OnGetProductTableReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestID + ")");
- var allProductBarcodes = nozzleExtraInfos.GroupBy(p => p.ProductBarcode);
- foreach (var b in allProductBarcodes)
- fdcServer.GetProductTableAdd(workstationID, applicationSender, requestID, b.Key, (b.FirstOrDefault()?.ProductName ?? ("refer cloud for name of " + b.Key)));
- fdcServer.GetProductTableSend(workstationID, applicationSender, requestID, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- };
- fdcServer.OnGetConfigurationReq += (string workstationID, string applicationSender, int requestId, string deviceType) =>
- {
- lock (this.syncObject)
- {
- try
- {
- fdcLogger.LogDebug("OnGetConfigurationReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", deviceType: " + deviceType);
- if (deviceType == "TLG")
- {
-
- var tankGroups = this.nozzleExtraInfos.Where(np => np.TankNumber.HasValue)
- .GroupBy(np => np.TankNumber)
- .Select(tg =>
- {
-
- var tank = this.autoTankGaugeControllers?.SelectMany(c => c.Tanks ?? new Tank[] { })?.FirstOrDefault(t => t.TankNumber == tg.Key)
- ?? new Tank()
- {
- TankNumber = (byte)tg.Key.Value,
- Label = "Logical tank",
- Product = new Product()
- {
- ProductCode = tg.First().ProductBarcode.ToString(),
- ProductLabel = tg.First().Description
- }
- };
- var pumpGroups = tg.GroupBy(np => np.PumpId).Select(pg => new Grouping<int, byte>(pg.Key, pg.Select(x => (byte)x.NozzleLogicalId)));
- return new Grouping<Tank, Grouping<int, byte>>(tank, pumpGroups);
- });
- if (!tankGroups.Any())
- {
- fdcServer.GetConfigurationSend(workstationID, applicationSender, requestId,
- deviceType, OverallResult.WrongConfiguration.ToString());
- fdcLogger.LogDebug(" OnGetConfigurationReq with TLG done with WrongConfiguration as no tanks info generated.");
- return;
- }
- fdcLogger.LogDebug(" OnGetConfigurationReq with TLG done with success, returned data-> " +
- tankGroups.Select(tg => $"Tank with number: {tg.Key.TankNumber}, " +
- $"label: {tg.Key.Label ?? ""}, productCode: {tg.Key.Product?.ProductCode ?? ""} linked to PumpIds: " +
- $"{tg.Select(p => $"{p.Key}(nzlLogiIds: {p.Select(n => n.ToString()).Aggregate("", (acc, n) => acc + ", " + n)})").Aggregate("", (acc, n) => acc + ", " + n)}")
- .Aggregate((acc, n) => acc + "; " + n));
- fdcServer.GetConfigurationAddTLG(workstationID, applicationSender, requestId, tankGroups);
- }
- else
- {
- foreach (var fdcPumpController in fdcPumpControllers)
- {
- foreach (var nozzle in fdcPumpController.Nozzles)
- {
- var bindProduct = nozzleExtraInfos.FirstOrDefault(n =>
- n.PumpId == fdcPumpController.PumpId
- && n.NozzleLogicalId == nozzle.LogicalId);
- var fuelPrice = nozzle.RealPriceOnPhysicalPump == null ? 0 :
- (nozzle.RealPriceOnPhysicalPump.Value / Math.Pow(10, fdcPumpController.PriceDecimalDigits));
- if (string.IsNullOrEmpty(deviceType) || deviceType == "DSP")
- {
- int bindProductNo = (bindProduct == null ? 0 : bindProduct.ProductBarcode);
- if (bindProduct == null)
- fdcLogger.LogInformation("Could not find bind product for pumpId: " + fdcPumpController.PumpId + ", nozzleId: " + nozzle.LogicalId + ", will use 0 instead");
- fdcLogger.LogDebug(" OnGetConfigurationReq pumpId: "
- + fdcPumpController.PumpId
- + ", nozzle logicalId: " + nozzle.LogicalId + ", nozzle phyId: " + nozzle.PhysicalId + ", productNo: " + bindProductNo
- + ", price: " + fuelPrice);
- fdcServer.GetConfigurationAddDSP(workstationID, applicationSender, requestId,
- fdcPumpController.PumpId,
- bindProductNo,
- bindProduct?.ProductName ?? ("refer cloud for name of " + bindProductNo),
- 1,
- fuelPrice);
- fdcServer.GetConfigurationAddFP(workstationID, applicationSender, requestId,
- fdcPumpController.PumpId,
- fdcPumpController.PumpId, nozzle.LogicalId, (bindProduct == null ? 0 : bindProduct.ProductBarcode), 0, 100, 0);
- }
-
-
- }
- }
- }
- fdcServer.GetConfigurationSend(workstationID, applicationSender, requestId,
- deviceType, OverallResult.Success.ToString());
- fdcLogger.LogDebug(" OnGetConfigurationReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnGetConfigurationReq exceptioned: " + exxx.ToString());
- fdcServer.GetConfigurationSend(workstationID, applicationSender, requestId, deviceType, OverallResult.Failure.ToString());
- }
- }
- };
- fdcServer.OnGetDeviceStateReq += async (string workstationID, string applicationSender, int requestId, string deviceType, int deviceId) =>
- {
- try
- {
- fdcLogger.LogDebug("OnGetDeviceStateReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", deviceId: " + deviceId + ")");
-
- if (deviceId == -1)
- {
- var controllers = fdcPumpControllers;
- foreach (var c in controllers)
- {
- var s = await c.QueryStatusAsync();
- fdcLogger.LogDebug(" Pump with pumpId: " + c.PumpId + " is in state: " + s.ToString()
- + ", nozzles states are(LogicalId-State): "
- + (c.Nozzles != null ?
- (c.Nozzles.Any() ?
- c.Nozzles.Select(n =>
- n.LogicalId.ToString() + "-" + (n.LogicalState?.ToString() ?? ""))
- .Aggregate((n, acc) => n + ", " + acc) : "") : ""));
- byte nozzleLockedOrUnlockedBitMap = 0;
- foreach (var nozzle in c.Nozzles)
- {
- if (nozzle.LogicalState.HasValue && nozzle.LogicalState == LogicalDeviceState.FDC_LOCKED)
- nozzleLockedOrUnlockedBitMap = SetBit(nozzleLockedOrUnlockedBitMap, nozzle.LogicalId - 1, nozzle.LogicalId, 1);
- else
- nozzleLockedOrUnlockedBitMap = SetBit(nozzleLockedOrUnlockedBitMap, nozzle.LogicalId - 1, nozzle.LogicalId, 0);
- }
- fdcServer.GetDeviceStateAdd(workstationID, applicationSender, requestId, deviceType, c.PumpId, (int)s,
- -1, "", "", (int)FDCLogicalState.FDC_LOGICAL_ST_UNLOCKED, "",
- c.Nozzles.Count(), 0, nozzleLockedOrUnlockedBitMap, 0);
- }
- }
- else
- {
- var targetController = fdcPumpControllers.First(c => c.PumpId == deviceId) as IFdcPumpController;
- byte nozzleLockedOrUnlockedBitMap = 0;
- foreach (var nozzle in targetController.Nozzles)
- {
- if (nozzle.LogicalState.HasValue && nozzle.LogicalState == LogicalDeviceState.FDC_LOCKED)
- nozzleLockedOrUnlockedBitMap = SetBit(nozzleLockedOrUnlockedBitMap, nozzle.LogicalId - 1, nozzle.LogicalId, 1);
- else
- nozzleLockedOrUnlockedBitMap = SetBit(nozzleLockedOrUnlockedBitMap, nozzle.LogicalId - 1, nozzle.LogicalId, 0);
- }
- fdcServer.GetDeviceStateAdd(workstationID, applicationSender, requestId, deviceType, deviceId,
- (int)targetController.QueryStatusAsync().Result,
- -1, "", "", (int)FDCLogicalState.FDC_LOGICAL_ST_UNLOCKED, "",
- targetController.Nozzles.Count(),
- 0, nozzleLockedOrUnlockedBitMap, 0);
- }
- fdcServer.GetDeviceStateSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- fdcLogger.LogDebug(" OnGetDeviceStateReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnGetDeviceStateReq exceptioned: " + exxx.ToString());
- fdcServer.GetDeviceStateSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_BADCONF, OverallResult.Failure.ToString());
- }
- };
- fdcServer.OnAuthoriseFuelPointReq += async
- (string workstationID, string applicationSender, int requestId, string releaseToken, int fuellingType,
- int deviceId, int reservingDeviceId, double maxTrxAmount, double maxTrxVolume,
- string products, int mode, bool lockFuelSaleTrx, string payType) =>
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- try
- {
- fdcLogger.LogDebug("OnAuthoriseFuelPointReq(wid: " + workstationID + ", appSender: " + applicationSender
- + ", requestId: " + requestId + ", releaseToken: " + releaseToken
- + ", deviceId: " + deviceId + ", reservingDeviceId: " + reservingDeviceId + ", maxTrxAmount: "
- + maxTrxAmount + ", maxTrxVolume: " + maxTrxVolume + ", products: " + products
- + ", lockFuelSaleTrx: " + lockFuelSaleTrx + ", payType: " + payType + ")");
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var succeed = await this.AuthorizePumpAsync(deviceId, maxTrxAmount, maxTrxVolume);
- if (succeed)
- fdcServer.AuthoriseFuelPoint(workstationID, applicationSender, requestId, -99, releaseToken, deviceId,
- (int)LogicalDeviceState.FDC_READY, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- else
- {
- fdcLogger.LogError("Authorising FP(requestId: " + requestId + ", releaseToken: " + releaseToken + ", deviceId: " + deviceId
- + ", reservingDeviceId: " + reservingDeviceId + ", maxTrxAmount: " + maxTrxAmount + ", maxTrxVolume: " + maxTrxVolume
- + ", products: " + products + ", lockFuelSaleTrx: " + lockFuelSaleTrx + ", payType: " + payType + ") failed");
- fdcServer.AuthoriseFuelPoint(workstationID, applicationSender, requestId, -99, releaseToken, deviceId,
- (int)LogicalDeviceState.FDC_READY, (int)ErrorCode.ERRCD_NOPERM, OverallResult.Failure.ToString());
- }
- fdcLogger.LogDebug(" Authorising FP done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnAuthoriseFuelPointReq exceptioned: " + exxx.ToString());
- fdcServer.AuthoriseFuelPoint(workstationID, applicationSender, requestId, -99, releaseToken, deviceId,
- (int)LogicalDeviceState.FDC_READY, (int)ErrorCode.ERRCD_NOPERM, OverallResult.Failure.ToString());
- }
- };
- fdcServer.OnTerminateFuellingReq += async (string workstationID, string applicationSender, int requestId, int deviceId) =>
- {
- fdcLogger.LogInformation("OnTerminateFuellingReq(wid: " + workstationID + ", appSender: " + applicationSender
- + ", requestId: " + requestId + ", deviceId: " + deviceId + ")");
- var targetController = fdcPumpControllers.FirstOrDefault(c => c.PumpId == deviceId);
- if (targetController == null)
- {
- fdcServer.TerminateFuellingSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_BADDEVID, OverallResult.WrongDeviceNo.ToString());
- return;
- }
- try
- {
-
- fdcLogger.LogInformation(" OnTerminateFuellingReq will be interpreted as UnAuthorize to pump handler.");
- var result = await targetController.UnAuthorizeAsync(1);
- if (result)
- fdcServer.TerminateFuellingSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- else
- fdcServer.TerminateFuellingSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_INOP, OverallResult.Failure.ToString());
- }
- catch (Exception exx)
- {
- fdcLogger.LogError("OnTerminateFuellingReq exceptioned: " + exx);
- fdcServer.TerminateFuellingSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.Failure.ToString());
- }
- };
- fdcServer.OnGetAvailableFuelSaleTrxsReq += (string workstationID, string applicationSender, int requestId, int deviceId) =>
- {
-
- int maxReturnDays = 365;
-
- int maxReturnDataCount = 1000;
- lock (this.syncObject)
- {
- try
- {
- fdcLogger.LogDebug("OnGetAvailableFuelSaleTrxsReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", deviceId: " + deviceId);
- var dueDate = DateTime.Now.Subtract(new TimeSpan(maxReturnDays, 0, 0, 0));
- int totalReturnTrxCount = 0;
- SqliteDbContext dbContext = new SqliteDbContext();
- if (deviceId == -1)
- {
- var all = dbContext.PumpTransactionModels.Where(t => t.State != FuelSaleTransactionState.Paid
- && t.State != FuelSaleTransactionState.Cleared
- && t.SaleStartTime >= dueDate)
- .Select(t => new { t.PumpId, t.TransactionSeqNumberFromPhysicalPump, t.State, t.SaleStartTime, t.ReleaseToken })
- .OrderByDescending(r => r.SaleStartTime).Take(maxReturnDataCount);
- foreach (var unpaidTrx in all)
- {
-
- if (!fdcPumpControllers.Select(p => p.PumpId).Any(p => p == unpaidTrx.PumpId))
- continue;
- totalReturnTrxCount++;
- fdcServer.GetAvailableFuelSaleTrxsAdd(workstationID, applicationSender, requestId,
- unpaidTrx.PumpId,
- int.Parse(unpaidTrx.TransactionSeqNumberFromPhysicalPump),
- unpaidTrx.ReleaseToken.ToString(),
- (int)unpaidTrx.State);
- }
- }
- else
- {
- var all = dbContext.PumpTransactionModels.Where(t => t.PumpId == deviceId
- && t.State != FuelSaleTransactionState.Paid
- && t.State != FuelSaleTransactionState.Cleared
- && t.SaleStartTime >= dueDate)
- .Select(t => new { t.PumpId, t.TransactionSeqNumberFromPhysicalPump, t.State, t.SaleStartTime, t.ReleaseToken })
- .OrderByDescending(r => r.SaleStartTime).Take(maxReturnDataCount);
- foreach (var unpaidTrx in all)
- {
-
- if (!fdcPumpControllers.Select(p => p.PumpId).Any(p => p == unpaidTrx.PumpId))
- continue;
- totalReturnTrxCount++;
- fdcServer.GetAvailableFuelSaleTrxsAdd(workstationID, applicationSender, requestId,
- unpaidTrx.PumpId,
- int.Parse(unpaidTrx.TransactionSeqNumberFromPhysicalPump),
- unpaidTrx.ReleaseToken.ToString(),
- (int)unpaidTrx.State);
- }
- }
- fdcServer.GetAvailableFuelSaleTrxsSend(workstationID, applicationSender, requestId,
- (int)ErrorCode.ERRCD_OK, (totalReturnTrxCount > 0 ? OverallResult.Success.ToString() : OverallResult.NoData.ToString()));
- fdcLogger.LogDebug(" OnGetAvailableFuelSaleTrxsReq done (total count: " + totalReturnTrxCount + ")");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnGetAvailableFuelSaleTrxsReq exceptioned: " + exxx.ToString());
- fdcServer.GetAvailableFuelSaleTrxsSend(workstationID, applicationSender, requestId,
- (int)ErrorCode.ERRCD_BADCONF, OverallResult.Failure.ToString());
- }
- }
- };
- fdcServer.OnGetFuelSaleTrxDetailsReq += (string workstationID, string applicationSender, int requestId, int deviceId, int transactionNo, string releaseToken) =>
- {
- lock (this.syncObject)
- {
- try
- {
-
- fdcLogger.LogDebug("OnGetFuelSaleTrxDetailsReq (wid: " + workstationID
- + ", appSender: " + applicationSender + ", requestId: " + requestId
- + ", deviceId: " + deviceId + ", transactionNo: " + transactionNo + ", releaseToken: " + releaseToken);
- int databaseId = int.Parse(releaseToken);
- SqliteDbContext dbContext = new SqliteDbContext();
- List<Edge.Core.Database.Models.FuelSaleTransaction> target;
- if (transactionNo == -1)
- target = dbContext.PumpTransactionModels.Where(t => t.PumpId == deviceId).ToList();
- else
- target = dbContext.PumpTransactionModels.Where(t =>
- t.ReleaseToken == databaseId
- && t.PumpId == deviceId
- && t.TransactionSeqNumberFromPhysicalPump == transactionNo.ToString()).ToList();
- if (target.Any())
- {
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == deviceId) as IFdcPumpController;
- foreach (var trx in target)
- {
- var reservedBy = string.IsNullOrEmpty(trx.LockedByFdcClientId) ?
- -1 : int.Parse(trx.LockedByFdcClientId);
- fdcServer.GetFuelSaleTrxDetailsAdd(workstationID, applicationSender, requestId,
- deviceId,
- trx.Volumn / Math.Pow(10, targetController.VolumeDecimalDigits),
- trx.Amount / Math.Pow(10, targetController.AmountDecimalDigits),
- trx.UnitPrice / Math.Pow(10, targetController.PriceDecimalDigits),
- trx.LogicalNozzleId,
- int.Parse(trx.ProductBarcode),
- "", "", 1,
- int.Parse(trx.TransactionSeqNumberFromPhysicalPump), releaseToken,
- (int)trx.State,
- trx.SaleStartTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- trx.SaleEndTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- trx.LockedByFdcClientId,
- "9999",
- reservedBy, 1);
- }
- fdcServer.GetFuelSaleTrxDetailsSend(workstationID, applicationSender, requestId,
- (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- }
- else
- {
- fdcLogger.LogInformation(" Trx with releaseToken: " + releaseToken + " is not found");
- fdcServer.GetFuelSaleTrxDetailsSend(workstationID, applicationSender, requestId,
- (int)ErrorCode.ERRCD_OK, OverallResult.NoData.ToString());
- }
- fdcLogger.LogDebug(" OnGetFuelSaleTrxDetailsReq done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnGetFuelSaleTrxDetailsReq exceptioned: " + exxx.ToString());
- fdcServer.GetFuelSaleTrxDetailsSend(workstationID, applicationSender, requestId,
- (int)ErrorCode.ERRCD_BADVAL, OverallResult.Failure.ToString());
- }
- }
- };
- fdcServer.OnClearFuelSaleTrxReq += async (string workstationID, string applicationSender, int requestId, int deviceId, int transactionNo, string releaseToken) =>
- {
- try
- {
- fdcLogger.LogDebug("OnClearFuelSaleTrxReq (wid: " + workstationID + ", appSender: " + applicationSender
- + ", requestId: " + requestId + ", deviceId: " + deviceId
- + ", transactionNo: " + transactionNo + ", releaseToken: " + releaseToken + ")");
- var target = await this.ClearFuelSaleTrxAndNotifyAllFdcClientsAsync(deviceId, transactionNo.ToString(), int.Parse(releaseToken), workstationID, applicationSender, requestId);
- if (target == null)
- fdcLogger.LogError("OnClearFuelSaleTrxReq failed(wid: " + workstationID + ", appSender: " + applicationSender
- + ", requestId: " + requestId + ", deviceId: " + deviceId
- + ", transactionNo: " + transactionNo + ", releaseToken: " + releaseToken + ")");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnClearFuelSaleTrxReq exceptioned: " + exxx.ToString());
- try
- {
- fdcServer.ClearFuelSaleTrx(workstationID, applicationSender, requestId, deviceId, transactionNo, releaseToken,
- (int)ErrorCode.ERRCD_BADVAL, 1, OverallResult.Failure.ToString());
- }
- catch (Exception eeee)
- {
- fdcLogger.LogError("Fdc server is trying to respond a failed ClearFuelSaleTrx response to a fdcclient that issue current ClearFuelSaleTrx request, but still failed with reason: " + eeee);
- }
- }
- };
-
- fdcServer.OnChangeFuelPriceInStringReq += (string workstationID,
- string applicationSender, int requestId, string formattedValues) =>
- {
- try
- {
- fdcLogger.LogInformation("OnChangeFuelPriceInStringReq (requestId:" +
- requestId + ") with data-> (barcode; PriceNew; ModeNo; PriceOld; EffectiveDatetime;!): " + formattedValues);
-
-
- var targetProductBarcode = int.Parse(formattedValues.Split(';')[0]);
-
-
- var rawNewPriceWithHumanReadableFormat = double.Parse(formattedValues.Split(';')[1]);
- var succeedNozzles = this.ChangeFuelPriceAsync(targetProductBarcode, rawNewPriceWithHumanReadableFormat).Result;
- fdcLogger.LogInformation(" OnChangeFuelPriceInStringReq (requestId:" + requestId + ") is done");
-
- if (succeedNozzles != null && succeedNozzles.Any())
- {
-
- fdcServer.FuelPriceChange(targetProductBarcode, 1,
- rawNewPriceWithHumanReadableFormat,
- 0,
-
- DateTime.Now.Subtract(new TimeSpan(0, 5, 0)).ToString("yyyy-MM-dd HH:mm:ss"));
- return targetProductBarcode.ToString() + ";" + rawNewPriceWithHumanReadableFormat.ToString() + ";1;" + 0 + ";!";
- }
- else return null;
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnChangeFuelPriceInStringReq exceptioned: " + exxx);
- return null;
- }
- };
-
-
-
-
-
-
-
-
-
- fdcServer.OnGetCurrentFuellingStatusReq += (string workstationID, string applicationSender,
- int requestId, int deviceId) =>
- {
-
- var targetController = fdcPumpControllers.First(c => c.PumpId == deviceId) as IFdcPumpController;
-
-
-
-
- };
- fdcServer.OnGetFuelPointTotalsReq += async (string workstationID, string applicationSender, int requestId, int deviceId, int nozzleId) =>
- {
- try
- {
- fdcLogger.LogDebug("OnGetFuelPointTotalsReq (wid: " + workstationID + ", appSender: " + applicationSender + ", requestId: " + requestId + ", deviceId: " + deviceId
- + ", nozzleId: " + nozzleId);
- if (deviceId == -1)
- {
-
- var everReadSuccessfully = false;
- foreach (var pumpController in fdcPumpControllers)
- {
- var pumpState = await pumpController.QueryStatusAsync();
- if (pumpState != LogicalDeviceState.FDC_READY)
- {
- fdcLogger.LogDebug($" OnGetFuelPointTotalsReq, pump: {pumpController.PumpId} is in state: {pumpState}, will skip to query its totalizer.");
- continue;
- }
- foreach (var nozzle in pumpController.Nozzles)
- {
- var result = await this.GetFuelPointTotalsAsync(pumpController.PumpId, (byte)nozzle.LogicalId);
- everReadSuccessfully = true;
- fdcLogger.LogInformation(" OnGetFuelPointTotalsReq for pump: " + pumpController.PumpId
- + ", nozzle: " + nozzle.LogicalId + " result(with decimal points) is: " + result.Item1 + " <-> " + result.Item2);
- fdcServer.GetFuelPointTotalsAdd(workstationID, applicationSender, requestId, pumpController.PumpId, nozzle.LogicalId,
- nozzleExtraInfos.FirstOrDefault(n => n.PumpId == pumpController.PumpId && n.NozzleLogicalId == nozzle.LogicalId).ProductBarcode,
- result.Item2,
- result.Item1,
- (pumpController.Nozzles.FirstOrDefault(n => n.LogicalId == nozzleId)?.RealPriceOnPhysicalPump ?? 0) / Math.Pow(10, pumpController.PriceDecimalDigits));
- }
- }
- if (everReadSuccessfully)
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- else
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_NOTALLOWED, OverallResult.DeviceUnavailable.ToString());
- }
- else if (nozzleId == -1)
- {
-
- var pumpController = fdcPumpControllers
- .First(c => c.PumpId == deviceId) as IFdcPumpController;
- var pumpState = await pumpController.QueryStatusAsync();
- if (pumpState != LogicalDeviceState.FDC_READY)
- {
- fdcLogger.LogDebug($" OnGetFuelPointTotalsReq, pump: {pumpController.PumpId} is in state: {pumpState}, will skip to query its totalizer.");
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_NOTALLOWED, OverallResult.DeviceUnavailable.ToString());
- }
- else
- {
- foreach (var nozzle in pumpController.Nozzles)
- {
- var result = await this.GetFuelPointTotalsAsync(pumpController.PumpId, (byte)nozzle.LogicalId);
- fdcLogger.LogInformation(" OnGetFuelPointTotalsReq for pump: " + pumpController.PumpId + ", nozzle: " + nozzle.LogicalId + " result(with decimal points) is: " + result.Item1 + " <-> " + result.Item2);
- fdcServer.GetFuelPointTotalsAdd(workstationID, applicationSender, requestId, pumpController.PumpId, nozzle.LogicalId,
- nozzleExtraInfos.FirstOrDefault(n => n.PumpId == pumpController.PumpId && n.NozzleLogicalId == nozzle.LogicalId).ProductBarcode,
- result.Item2,
- result.Item1,
- (pumpController.Nozzles.FirstOrDefault(n => n.LogicalId == nozzleId)?.RealPriceOnPhysicalPump ?? 0) / Math.Pow(10, pumpController.PriceDecimalDigits));
- }
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- }
- }
- else
- {
-
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == deviceId) as IFdcPumpController;
- var pumpState = await targetController.QueryStatusAsync();
- if (pumpState != LogicalDeviceState.FDC_READY)
- {
- fdcLogger.LogDebug($" OnGetFuelPointTotalsReq, pump: {targetController.PumpId} is in state: {pumpState}, will skip to query its totalizer.");
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_NOTALLOWED, OverallResult.DeviceUnavailable.ToString());
- }
- else
- {
- var result = await this.GetFuelPointTotalsAsync(targetController.PumpId, (byte)nozzleId);
- fdcLogger.LogInformation(" OnGetFuelPointTotalsReq for pump: " + targetController.PumpId + ", nozzle: " + nozzleId + " result(with decimal points) is: " + result.Item1 + " <-> " + result.Item2);
- fdcServer.GetFuelPointTotalsAdd(workstationID, applicationSender, requestId, deviceId, nozzleId,
- nozzleExtraInfos.FirstOrDefault(n => n.PumpId == targetController.PumpId && n.NozzleLogicalId == nozzleId).ProductBarcode,
- result.Item2,
- result.Item1,
- (targetController.Nozzles.FirstOrDefault(n => n.LogicalId == nozzleId)?.RealPriceOnPhysicalPump ?? 0) / Math.Pow(10, targetController.PriceDecimalDigits));
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId, (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- }
- }
- fdcLogger.LogDebug(" OnGetFuelPointTotals done");
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("OnGetFuelPointTotalsReq exceptioned: " + exxx.ToString());
- fdcServer.GetFuelPointTotalsSend(workstationID, applicationSender, requestId,
- (int)ErrorCode.ERRCD_BADCONF, OverallResult.Failure.ToString());
- }
- };
- #region setup Fdc unsolicited event
- foreach (var fdcPumpController in this.fdcPumpControllers)
- {
- fdcPumpController.OnStateChange += async (s, stateChangeArg) =>
- {
- var pump = s as IFdcPumpController;
- try
- {
- fdcLogger.LogDebug("Pump " + pump.PumpId
- + " StateChanged to: " + stateChangeArg.NewPumpState.ToString() + ", nozzles states are(LogicalId-State): "
- + (pump.Nozzles != null ?
- (pump.Nozzles.Any() ?
- pump.Nozzles.Select(n =>
- n.LogicalId.ToString() + "-" + (n.LogicalState?.ToString() ?? ""))
- .Aggregate((n, acc) => n + ", " + acc) : "") : "")
- + ", StateChangedNozzles are: "
- + (stateChangeArg.StateChangedNozzles != null ?
- (stateChangeArg.StateChangedNozzles.Any() ?
- stateChangeArg.StateChangedNozzles.Select(n => n.LogicalId.ToString())
- .Aggregate((n, acc) => n + ", " + acc) : "") : ""));
- this.OnStateChange?.Invoke(s, stateChangeArg);
- var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
- await universalApiHub.FireEvent(this, "OnFdcControllerStateChange",
- new
- {
- pump.PumpId,
- logicalId = (stateChangeArg.StateChangedNozzles != null && stateChangeArg.StateChangedNozzles.Any()) ?
- stateChangeArg.StateChangedNozzles.FirstOrDefault().LogicalId.ToString() : "",
- logicalState = stateChangeArg.NewPumpState
- });
- fdcLogger.LogTrace("Pump " + pump.PumpId + " StateChanged event fired and back");
-
- byte nozzleUpOrDownBitMap = 0;
- if (stateChangeArg.StateChangedNozzles != null)
- foreach (var upNozzle in stateChangeArg.StateChangedNozzles)
- {
- nozzleUpOrDownBitMap = SetBit(nozzleUpOrDownBitMap, upNozzle.LogicalId - 1, upNozzle.LogicalId, 1);
- }
- byte nozzleLockedOrUnlockedBitMap = 0;
- foreach (var nozzle in pump.Nozzles)
- {
- if (nozzle.LogicalState.HasValue && nozzle.LogicalState == LogicalDeviceState.FDC_LOCKED)
- nozzleLockedOrUnlockedBitMap = SetBit(nozzleLockedOrUnlockedBitMap, nozzle.LogicalId - 1, nozzle.LogicalId, 1);
- else
- nozzleLockedOrUnlockedBitMap = SetBit(nozzleLockedOrUnlockedBitMap, nozzle.LogicalId - 1, nozzle.LogicalId, 0);
- }
- fdcServer.DeviceStateChange(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, pump.PumpId,
- (int)(stateChangeArg.NewPumpState), (int)LogicalDeviceState.FDC_UNDEFINED, "", "", "",
- pump.Nozzles.Count(), nozzleUpOrDownBitMap, nozzleLockedOrUnlockedBitMap, 0);
- fdcLogger.LogTrace($"Pump {pump.PumpId } Fdc DeviceStateChange event fired and back");
- if (stateChangeArg.NewPumpState == LogicalDeviceState.FDC_CALLING)
- {
- if (this.config_AutoAuthCallingPumps)
- {
- if (this.config_MaxStackUnpaidTrxPerPump > 0)
- {
- SqliteDbContext dbContext = new SqliteDbContext();
- var unpaidTrxCount = dbContext.PumpTransactionModels.Count(t => t.PumpId == pump.PumpId && t.State == FuelSaleTransactionState.Payable);
- if (unpaidTrxCount >= this.config_MaxStackUnpaidTrxPerPump)
- {
- fdcLogger.LogInformation(" Auto authorizing is not permit since pump " + pump.PumpId + " has: " + unpaidTrxCount + " unpaid trx");
- return;
- }
- }
- fdcLogger.LogDebug("Auto authorizing Pump: " + pump.PumpId);
- int autoAuthDefaultAmount = 9999;
- var result = await pump.AuthorizeWithAmountAsync((int)(autoAuthDefaultAmount * Math.Pow(10, pump.AmountDecimalDigits)), 1);
- if (!result)
- fdcLogger.LogError("Auto auth Pump: " + pump.PumpId + " FAILED!");
- }
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError($"PumpId: {pump.PumpId}, fdcPumpController.OnStateChange exceptioned: {exxx}");
- }
- };
- fdcPumpController.OnCurrentFuellingStatusChange += async (s, a) =>
- {
- var pump = s as IFdcPumpController;
- try
- {
- fdcLogger.LogDebug($"Pump {pump.PumpId }, Nozzle: {a?.Transaction?.Nozzle?.LogicalId.ToString() ?? ""}, OnCurrentFuellingStatusChange");
- var product = nozzleExtraInfos.FirstOrDefault(c => c.PumpId == pump.PumpId && c.NozzleLogicalId == a.Transaction.Nozzle.LogicalId);
- if (product != null)
- a.Transaction.Barcode = product.ProductBarcode;
- else
- a.Transaction.Barcode = 1;
- if (a.Transaction.Finished)
- {
- fdcLogger.LogInformation("Pump " + pump.PumpId + ", transaction is finished, vol: " + a.Transaction.Volumn + ", amount: " + a.Transaction.Amount
- + ", price: " + a.Transaction.Price + ", nozzleNo: " + a.Transaction.Nozzle.LogicalId
- + ", volumeTotalizer: " + (a.Transaction.VolumeTotalizer ?? -1)
- + ", amountTotalizer: " + (a.Transaction.AmountTotalizer ?? -1)
- + ", seqNumber: " + a.Transaction.SequenceNumberGeneratedOnPhysicalPump
- + ", productBarcode: " + product?.ProductBarcode
- + ", productName: " + (product?.ProductName ?? ""));
-
-
-
-
-
-
-
-
-
- var duplicationDectectTimeRange = 3;
- var range = DateTime.Now.Subtract(new TimeSpan(duplicationDectectTimeRange, 0, 0, 0));
- SqliteDbContext dbContext = new SqliteDbContext();
- var existed = dbContext.PumpTransactionModels.Where(f =>
- f.PumpId == pump.PumpId
- && f.TransactionSeqNumberFromPhysicalPump == a.Transaction.SequenceNumberGeneratedOnPhysicalPump.ToString()
- && f.UnitPrice == a.Transaction.Price
- && f.Amount == a.Transaction.Amount
- && f.Volumn == a.Transaction.Volumn
- && f.SaleEndTime > range).ToList();
- if (existed.Any())
- {
- fdcLogger.LogWarning("A new trx duplicated with an existed trx in db which done in recent "
- + duplicationDectectTimeRange + " days, it was with " +
- "releaseToken:" + existed.First().ReleaseToken + ", pumpId: " + pump.PumpId + " and seqNo: "
- + a.Transaction.SequenceNumberGeneratedOnPhysicalPump.ToString()
- + ", will do nothing and NOT notify any POS, while the existed one in database detail is-> "
- + "Vol: " + existed.First().Volumn
- + ", Amount: " + existed.First().Amount
- + ", State: " + existed.First().State.ToString()
- + ", SaleStartTime: " + (existed.First().SaleStartTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "")
- + ", EndStartTime: " + (existed.First().SaleEndTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "")
- + ", ProductBarcode: " + existed.First().ProductBarcode.ToString()
- + "");
- }
- else
- {
- var trx = new Edge.Core.Database.Models.FuelSaleTransaction()
- {
- TransactionSeqNumberFromPhysicalPump = a.Transaction.SequenceNumberGeneratedOnPhysicalPump.ToString(),
- PumpId = pump.PumpId,
- LogicalNozzleId = a.Transaction.Nozzle.LogicalId,
- Amount = a.Transaction.Amount,
- Volumn = a.Transaction.Volumn,
- UnitPrice = a.Transaction.Price,
- VolumeTotalizer = a.Transaction.VolumeTotalizer ?? -1,
- AmountTotalizer = a.Transaction.AmountTotalizer ?? -1,
- ProductBarcode = product?.ProductBarcode.ToString() ?? "9999",
-
- State = FuelSaleTransactionState.Payable,
- LockedByFdcClientId = "",
-
- SaleStartTime = a.Transaction.SaleStartTime ?? ((a.Transaction.SaleEndTime ?? DateTime.Now).Subtract(new TimeSpan(0, 3, 0))),
- SaleEndTime = a.Transaction.SaleEndTime ?? DateTime.Now,
- };
- dbContext.PumpTransactionModels.Add(trx);
- dbContext.SaveChanges();
- fdcLogger.LogDebug(" ######transaction is done saving to db with ReleaseToken(Id): " + trx.ReleaseToken);
- var safe = this.OnFdcFuelSaleTransactinStateChange;
- safe?.Invoke(this, new FdcFuelSaleTransactinStateChangeEventArg(trx, FuelSaleTransactionState.Payable));
- var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
- await universalApiHub.FireEvent(this, "OnFdcFuelSaleTransactinStateChange", new FdcFuelSaleTransactinStateChangeEventArg(trx, FuelSaleTransactionState.Payable));
- var startingTime = DateTime.Now;
- fdcServer.FuelSaleTrx(pump.PumpId,
- trx.Volumn / Math.Pow(10, pump.VolumeDecimalDigits),
- trx.Amount / Math.Pow(10, pump.AmountDecimalDigits),
- trx.UnitPrice / Math.Pow(10, pump.PriceDecimalDigits),
- trx.LogicalNozzleId,
- product?.ProductBarcode ?? 0,
- product?.ProductName ?? ("refer cloud for name of " + (product?.ProductBarcode ?? -1)),
- "", 1,
- int.Parse(trx.TransactionSeqNumberFromPhysicalPump),
- (int)trx.State,
- 0, trx.ReleaseToken.ToString(),
- trx.SaleStartTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- trx.SaleEndTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- "", "", 0, 0);
- fdcLogger.LogDebug($" ######transaction(releaseToken: {trx.ReleaseToken}) is done broadcasting to POSes, used: {DateTime.Now.Subtract(startingTime).TotalMilliseconds}");
- this.OnCurrentFuellingStatusChange?.Invoke(s,
- new FdcServerTransactionDoneEventArg(a.Transaction)
- { ReleaseToken = trx.ReleaseToken });
- fdcLogger.LogTrace("Pump " + pump.PumpId + " OnCurrentFuellingStatusChange event fired and back");
- if (a.Transaction.VolumeTotalizer == null)
- {
- var result = await GetFuelPointTotalsAsync(pump.PumpId, a.Transaction.Nozzle.LogicalId);
- a.Transaction.AmountTotalizer = (int?)(result.Item1 * Math.Pow(10, pump.AmountDecimalDigits));
- a.Transaction.VolumeTotalizer = (int?)(result.Item2 * Math.Pow(10, pump.VolumeDecimalDigits));
- }
- var targetNozzle = pump.Nozzles.First(n => n.LogicalId == a.Transaction.Nozzle.LogicalId);
- if (targetNozzle != null) targetNozzle.VolumeTotalizer = a.Transaction.VolumeTotalizer;
- await universalApiHub.FireEvent(this, "OnCurrentFuellingStatusChange", new FdcServerTransactionDoneEventArg(a.Transaction) { FuelingEndTime = trx.SaleEndTime });
- }
- }
- else
- {
- fdcLogger.LogDebug(" transaction is ongoing, vol: " + a.Transaction.Volumn + ", amount: " + a.Transaction.Amount
- + ", price: " + a.Transaction.Price + ", nozzleNo: " + a.Transaction.Nozzle.LogicalId
- + ", seqNumber: " + a.Transaction.SequenceNumberGeneratedOnPhysicalPump ?? ""
- + ", productBarcode: " + product.ProductBarcode
- + ", productName: " + (product.ProductName ?? ""));
- fdcServer.CurrentFuellingStatus(pump.PumpId,
- a.Transaction.Volumn / Math.Pow(10, pump.VolumeDecimalDigits),
- a.Transaction.Amount / Math.Pow(10, pump.AmountDecimalDigits),
- a.Transaction.Price / Math.Pow(10, pump.PriceDecimalDigits),
- a.Transaction.Nozzle.LogicalId,
- a.Transaction.SequenceNumberGeneratedOnPhysicalPump, "9999", 1, a.Transaction.Nozzle.LogicalId);
- this.OnCurrentFuellingStatusChange?.Invoke(s, new FdcServerTransactionDoneEventArg(a.Transaction));
- fdcLogger.LogTrace("Pump " + pump.PumpId + " OnCurrentFuellingStatusChange event fired and back");
- var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
- await universalApiHub.FireEvent(this, "OnCurrentFuellingStatusChange", new FdcServerTransactionDoneEventArg(a.Transaction));
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError($"PumpId: { pump?.PumpId ?? -1}, fdcPumpController.OnCurrentFuellingStatusChange exceptioned: " + exxx);
- }
- };
- }
- #endregion
- #region handle BroadcastGenericTypelessMessage
- if (this.fdcCommunicableControllers != null)
- {
- this.fdcCommunicableControllers.ToList().ForEach(c =>
- {
- c.BroadcastMessageViaFdc += (msg) =>
- {
- fdcServer.SendGenericTypelessMessageToFdcClient(null, null, msg);
- return true;
- };
- });
- this.fdcCommunicableControllers.ToList().ForEach(c =>
- {
- c.SendMessageViaFdc += (workstationID, applicationSender, msg) =>
- {
- fdcServer.SendGenericTypelessMessageToFdcClient(workstationID, applicationSender, msg);
- return true;
- };
- });
- }
- fdcServer.OnGetGenericTypelessMessageReq += (string workstationID, string applicationSender, int requestId, string message) =>
- {
- this.fdcCommunicableControllers.ToList().ForEach(c =>
- {
- if (c.OnMessageReceivedViaFdc != null)
- {
- var returnResult = c.OnMessageReceivedViaFdc(message);
- fdcServer.GenericTypelessMessageSend(workstationID, applicationSender, requestId, returnResult.Item1, returnResult.Item2.ToString());
- }
- });
- };
- #endregion
- fdcLogger.LogDebug("Start all FdcPumpController initing...(total: "
- + (fdcPumpControllers?.Count() ?? -1)
- + ", pump Ids are: " + ((fdcPumpControllers?.Any() ?? false) ?
- (fdcPumpControllers.Select(c => c.PumpId.ToString()).Aggregate((acc, n) => acc + ", " + n) + ")") : ")"));
- foreach (var fdcPumpController in this.fdcPumpControllers)
- {
- var onFdcServerInitParams = new Dictionary<string, object>();
- try
- {
- #region LastPriceChange for each nozzles
-
- var innerParams0 = new Dictionary<byte, int>();
- foreach (var nozzle in fdcPumpController.Nozzles)
- {
- var dbContext = new SqliteDbContext();
- var lastPriceChange = dbContext.FuelPriceChanges
- .Where(t => t.PumpId == fdcPumpController.PumpId
- && t.LogicalNozzleId == nozzle.LogicalId)
- .OrderByDescending(b => b.Id).FirstOrDefault();
- if (lastPriceChange != null)
- innerParams0.Add(nozzle.LogicalId, lastPriceChange.NewPriceWithoutDecimal);
- }
- onFdcServerInitParams.Add("LastPriceChange", innerParams0);
- #endregion
- #region LastFuelSaleTrx for each nozzles
-
- var innerParams1 = new Dictionary<byte, FuelSaleTransaction>();
- foreach (var nozzle in fdcPumpController.Nozzles)
- {
- var dbContext = new SqliteDbContext();
- var lastPaidTrx = dbContext.PumpTransactionModels
- .Where(t => t.PumpId == fdcPumpController.PumpId
- && t.LogicalNozzleId == nozzle.LogicalId)
- .OrderByDescending(b => b.SaleStartTime).FirstOrDefault();
- if (lastPaidTrx != null)
- innerParams1.Add(nozzle.LogicalId, lastPaidTrx);
- }
- onFdcServerInitParams.Add("LastFuelSaleTrx", innerParams1);
- #endregion
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("Retrieve lastPriceChange for OnFdcServerInit from db for Pump with pumpid: "
- + fdcPumpController.PumpId + " exceptioned: " + exxx.ToString()
- + System.Environment.NewLine + "Will skip this pump and continue for next pump.");
- continue;
- }
- try
- {
- fdcPumpController.OnFdcServerInit(onFdcServerInitParams);
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("FdcPumpController with pumpid: "
- + fdcPumpController.PumpId + " exceptioned in OnFdcServerInit, detail: " + exxx.ToString()
- + System.Environment.NewLine + "Will skip and continue for next FdcPumpController.");
- continue;
- }
- }
- fdcLogger.LogDebug("Done all FdcPumpController init, start FdcServer tcp listening...");
- var _ = fdcServer.Start(this.config_ListeningPort, true, "WINCOR", 2, true, "NONE");
- fdcLogger.LogDebug("Done FdcServer tcp listening...");
- return Task.FromResult(_);
- }
- public Task<bool> Stop()
- {
- if (this.onConfiguratorConfigFileChangedEventHandler != null)
- this.configurator.OnConfigFileChanged -= this.onConfiguratorConfigFileChangedEventHandler;
- this.purgeDatabaseTimer?.Stop();
-
- this.fdcPumpControllers = new List<IFdcPumpController>();
- var stopFdcServerResult = fdcServer.Stop();
- return Task.FromResult(stopFdcServerResult);
- }
- private static byte SetBit(byte target, int bitStartIndex, int bitEndIndex, int replacedValue)
- {
- if (bitStartIndex < 0 || bitEndIndex > 7 || bitEndIndex < bitStartIndex)
- {
- throw new ArgumentException("bitStartIndex or bitEndIndex value is not valid");
- }
- byte mask = 0;
- for (int i = 0; i < bitEndIndex - bitStartIndex + 1; i++)
- {
- mask += (byte)Math.Pow(2, i);
- }
- if (replacedValue > mask)
- {
- throw new ArgumentOutOfRangeException("Replaced value: " + replacedValue + " cannot fit the bits range");
- }
- byte maskedValue = (byte)(target & (255 - (mask << bitStartIndex)));
- return (byte)(maskedValue + (replacedValue << bitStartIndex));
- }
- public void Dispose()
- {
- }
- #region pump control interface opened for local call, used in other fc app.
-
-
-
- public event EventHandler<FdcPumpControllerOnStateChangeEventArg> OnStateChange;
-
-
-
-
- public event EventHandler<FdcServerTransactionDoneEventArg> OnCurrentFuellingStatusChange;
-
-
-
-
- public event EventHandler<FdcFuelSaleTransactinStateChangeEventArg> OnFdcFuelSaleTransactinStateChange;
- public IEnumerable<IFdcPumpController> FdcPumpControllers => this.fdcPumpControllers;
-
-
-
-
-
-
-
- public async Task<bool> AuthorizePumpAsync(int pumpId, double maxTrxAmount, double maxTrxVolume)
- {
- fdcLogger.LogDebug("Authorizing Pump: " + pumpId + ", maxTrxAmount: " + maxTrxAmount + ", maxTrxVolume: " + maxTrxVolume);
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
- if (this.config_MaxStackUnpaidTrxPerPump > 0)
- {
- SqliteDbContext dbContext = new SqliteDbContext();
- var unpaidTrxCount = dbContext.PumpTransactionModels.Count(t => t.PumpId == targetController.PumpId
- && t.State == FuelSaleTransactionState.Payable);
- if (unpaidTrxCount >= this.config_MaxStackUnpaidTrxPerPump)
- {
- fdcLogger.LogInformation(" Authorizing from FdcClient is not permit since pump " + targetController.PumpId + " has: " + unpaidTrxCount + " unpaid trx");
-
-
- return false;
- }
- }
- bool succeed = false;
- if (maxTrxAmount == 0 && maxTrxVolume == 0)
-
- succeed = await targetController.AuthorizeAsync(1);
- else if (maxTrxAmount == 0 && maxTrxVolume != 0)
- succeed = await targetController.AuthorizeWithVolumeAsync((int)(maxTrxVolume * Math.Pow(10, targetController.VolumeDecimalDigits)), 1);
- else
- succeed = await targetController.AuthorizeWithAmountAsync((int)(maxTrxAmount * Math.Pow(10, targetController.AmountDecimalDigits)), 1);
- fdcLogger.LogDebug(" AuthorizePump: " + pumpId + " finished with: " + succeed.ToString());
- return succeed;
- }
-
-
-
-
-
-
-
-
-
-
-
- [UniversalApi(Description = "Clear an unpaid fuel sale trx from db and notify all tcp FdcClients.")]
- public async Task<FuelSaleTransaction> ClearFuelSaleTrxAndNotifyAllFdcClientsAsync(int pumpId, string transactionNo, int trxDbUniqueId, string lockingClientId)
- {
- return await this.ClearFuelSaleTrxAndNotifyAllFdcClientsAsync(pumpId, transactionNo, trxDbUniqueId, lockingClientId, null, -1);
- }
-
-
-
-
-
-
-
-
-
-
-
-
- public async Task<FuelSaleTransaction> ClearFuelSaleTrxAndNotifyAllFdcClientsAsync(int pumpId, string transactionNo,
- int trxDbUniqueId, string workstationID, string appSenderId, int fdcClientRequestId)
- {
- try
- {
- fdcLogger.LogDebug("ClearFuelSaleTrxAndNotifyAllFdcClients (wid: " + workstationID + ", appSenderId: " + (appSenderId ?? "") + ", pumpId: " + pumpId
- + ", transactionNo: " + transactionNo + ", releaseToken: " + trxDbUniqueId + ")");
- SqliteDbContext dbContext = new SqliteDbContext();
- int databaseId = trxDbUniqueId;
- var target = await dbContext.PumpTransactionModels.FirstOrDefaultAsync(t =>
- t.ReleaseToken == databaseId
- && t.PumpId == pumpId
- && t.TransactionSeqNumberFromPhysicalPump == transactionNo);
- if (target != null)
- {
- if (target.State == FuelSaleTransactionState.Paid)
- {
- fdcLogger.LogInformation("ClearFuelSaleTrx for workstationId: " + workstationID + " on pump with pumpId: " + pumpId + ", transactionNo: " + transactionNo
- + ", releaseToken: " + trxDbUniqueId
- + " failed due to target trx is already a Paid trx");
-
-
- if (!string.IsNullOrEmpty(appSenderId))
- {
- int.TryParse(transactionNo, out int p_trxNo);
- fdcServer.ClearFuelSaleTrx(workstationID, appSenderId, fdcClientRequestId, pumpId, p_trxNo, trxDbUniqueId.ToString(),
- (int)ErrorCode.ERRCD_NOTPOSSIBLE, 1, OverallResult.Failure.ToString());
- }
- return null;
- }
- else
- {
- target.State = FuelSaleTransactionState.Paid;
- target.PaidByFdcClientId = workstationID;
- target.PaidTime = DateTime.Now;
- await dbContext.SaveChangesAsync();
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
- int.TryParse(transactionNo, out int p_trxNo);
-
-
- if (!string.IsNullOrEmpty(appSenderId))
- fdcServer.ClearFuelSaleTrx(workstationID, appSenderId, fdcClientRequestId, pumpId, p_trxNo, trxDbUniqueId.ToString(),
- (int)ErrorCode.ERRCD_OK, 1, OverallResult.Success.ToString());
- var safe = this.OnFdcFuelSaleTransactinStateChange;
- safe?.Invoke(this,
- new FdcFuelSaleTransactinStateChangeEventArg(target, FuelSaleTransactionState.Paid));
- var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
- await universalApiHub.FireEvent(this, "OnFdcFuelSaleTransactinStateChange", new FdcFuelSaleTransactinStateChangeEventArg(target, FuelSaleTransactionState.Paid));
- fdcServer.FuelSaleTrx(target.PumpId,
- target.Volumn / Math.Pow(10, targetController.VolumeDecimalDigits),
- target.Amount / Math.Pow(10, targetController.AmountDecimalDigits),
- target.UnitPrice / Math.Pow(10, targetController.PriceDecimalDigits),
- target.LogicalNozzleId,
- int.Parse(target.ProductBarcode),
- "", "", 1,
- int.Parse(target.TransactionSeqNumberFromPhysicalPump),
-
- (int)FuelSaleTransactionState.Cleared,
- 0, trxDbUniqueId.ToString(),
- target.SaleStartTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- target.SaleEndTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- target.LockedByFdcClientId ?? "",
- "", -1, 0);
- return target;
- }
- }
- else
- {
- fdcLogger.LogInformation("ClearFuelSaleTrx for workstationId: " + workstationID + " on pump with pumpId: " + pumpId + ", transactionNo: " + transactionNo
- + ", releaseToken: " + trxDbUniqueId
- + " failed due to target trx could not found");
-
-
- if (!string.IsNullOrEmpty(appSenderId))
- {
- int.TryParse(transactionNo, out int p_trxNo);
- fdcServer.ClearFuelSaleTrx(workstationID, appSenderId, fdcClientRequestId, pumpId, p_trxNo, trxDbUniqueId.ToString(),
- (int)ErrorCode.ERRCD_BADVAL, 1, OverallResult.Failure.ToString());
- }
- return null;
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogInformation("ClearFuelSaleTrx for workstationId: " + workstationID + " on pump with pumpId: " + pumpId + ", transactionNo: " + transactionNo
- + ", releaseToken: " + trxDbUniqueId
- + " failed due to exception: " + exxx);
- return null;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
- [UniversalApi(Description = "Lock an unlocked state fuel sale trx from db and notify all tcp FdcClients.")]
- public async Task<FuelSaleTransaction> LockFuelSaleTrxAndNotifyAllFdcClientsAsync(int lockingClientId,
- int pumpId,
- int transactionNo, int trxDbUniqueId)
- {
- return await this.LockFuelSaleTrxAndNotifyAllFdcClientsAsync(lockingClientId, "", -1, pumpId, transactionNo, trxDbUniqueId);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- public async Task<FuelSaleTransaction> LockFuelSaleTrxAndNotifyAllFdcClientsAsync(int lockingClientId, string fdcClientAppSender, int fdcClientRequestId,
- int pumpId,
- int transactionNo, int trxDbUniqueId)
- {
- try
- {
- fdcLogger.LogDebug("LockFuelSaleTrxAndNotifyAllFdcClients from lockingClientId: " + lockingClientId
- + ", fdcClientAppSender: " + (fdcClientAppSender ?? "")
- + ", fdcClientRequestId: " + fdcClientRequestId
- + ", pumpId: " + pumpId + ", transactionNo: " + transactionNo + ", trxDbUniqueId: " + trxDbUniqueId);
- var result = await FdcResourceArbitrator.Default.TryLockFuelSaleTrxAsync(lockingClientId, pumpId, transactionNo, trxDbUniqueId);
- fdcLogger.LogDebug($" TryLockFuelSaleTrx(trxDbUniqueId: {trxDbUniqueId}) with result: {!(result == null)}");
-
- if (result != null)
- {
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.LockFuelSaleTrx(lockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId, pumpId,
- transactionNo, trxDbUniqueId.ToString(), (int)ErrorCode.ERRCD_OK, 1, OverallResult.Success.ToString());
- var safe = this.OnFdcFuelSaleTransactinStateChange;
- safe?.Invoke(this,
- new FdcFuelSaleTransactinStateChangeEventArg(result, FuelSaleTransactionState.Locked));
- var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
- await universalApiHub.FireEvent(this, "OnFdcFuelSaleTransactinStateChange", new FdcFuelSaleTransactinStateChangeEventArg(result, FuelSaleTransactionState.Locked));
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
- fdcServer.FuelSaleTrx(pumpId,
- result.Volumn / Math.Pow(10, targetController.VolumeDecimalDigits),
- result.Amount / Math.Pow(10, targetController.AmountDecimalDigits),
- result.UnitPrice / Math.Pow(10, targetController.PriceDecimalDigits),
- result.LogicalNozzleId,
- int.Parse(result.ProductBarcode),
- this.nozzleExtraInfos
- .FirstOrDefault(n => n.PumpId == pumpId && n.NozzleLogicalId == result.LogicalNozzleId)?.ProductName ??
- ("refer cloud for name of " + result.ProductBarcode), "", 1,
- int.Parse(result.TransactionSeqNumberFromPhysicalPump),
- (int)FuelSaleTransactionState.Locked,
- 0, trxDbUniqueId.ToString(),
- result.SaleStartTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- result.SaleEndTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- lockingClientId.ToString(), "", lockingClientId, 0);
- }
- else
- {
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.LockFuelSaleTrx(lockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId, pumpId,
- transactionNo, trxDbUniqueId.ToString(), (int)ErrorCode.ERRCD_TRANSLOCKED, 1, OverallResult.Failure.ToString());
- }
- fdcLogger.LogTrace($" LockFuelSaleTrxAndNotifyAllFdcClients(trxDbUniqueId: {trxDbUniqueId}) returned");
- return result;
- }
- catch (Exception exx)
- {
- fdcLogger.LogError("LockFuelSaleTrxAndNotifyAllFdcClients exceptioned for lockingClientId: "
- + lockingClientId + ", pumpId: " + pumpId + ", transactionNo: " + transactionNo + ", trxDbUniqueId: " + trxDbUniqueId + ", exception detail: " + exx);
- throw;
- }
- }
-
-
-
-
-
-
-
-
-
-
- [UniversalApi(Description = "Unlock a locked state fuel sale trx from db and notify all tcp FdcClients.")]
- public async Task<FuelSaleTransaction> UnlockFuelSaleTrxAndNotifyAllFdcClientsAsync(int lockingClientId,
- int pumpId,
- int transactionNo, int trxDbUniqueId)
- {
- return await this.UnlockFuelSaleTrxAndNotifyAllFdcClientsAsync(lockingClientId, "", -1, pumpId, transactionNo, trxDbUniqueId);
- }
- public IEnumerable<NozzleExtraInfo> GetNozzleExtraInfos()
- {
- return this.nozzleExtraInfos;
- }
-
-
-
-
-
-
-
-
-
-
-
-
- public async Task<FuelSaleTransaction> UnlockFuelSaleTrxAndNotifyAllFdcClientsAsync(int unlockingClientId, string fdcClientAppSender, int fdcClientRequestId, int pumpId,
- int transactionNo, int trxDbUniqueId)
- {
- try
- {
- fdcLogger.LogDebug("UnlockFuelSaleTrxAndNotifyAllFdcClients from lockingClientId: " + unlockingClientId
- + ", fdcClientAppSender: " + (fdcClientAppSender ?? "")
- + ", fdcClientRequestId: " + fdcClientRequestId
- + ", pumpId: " + pumpId + ", transactionNo: " + transactionNo + ", trxDbUniqueId: " + trxDbUniqueId);
- var result = await FdcResourceArbitrator.Default.TryUnlockFuelSaleTrxAsync(unlockingClientId, pumpId, transactionNo, trxDbUniqueId);
- if (result != null)
- {
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.UnlockFuelSaleTrx(unlockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId, pumpId,
- transactionNo, trxDbUniqueId.ToString(), (int)ErrorCode.ERRCD_OK, 1, OverallResult.Success.ToString());
- var safe = this.OnFdcFuelSaleTransactinStateChange;
- safe?.Invoke(this,
- new FdcFuelSaleTransactinStateChangeEventArg(result, FuelSaleTransactionState.Payable));
- var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
- await universalApiHub.FireEvent(this, "OnFdcFuelSaleTransactinStateChange", new FdcFuelSaleTransactinStateChangeEventArg(result, FuelSaleTransactionState.Payable));
- fdcServer.FuelSaleTrx(pumpId,
- result.Volumn / Math.Pow(10, targetController.VolumeDecimalDigits),
- result.Amount / Math.Pow(10, targetController.AmountDecimalDigits),
- result.UnitPrice / Math.Pow(10, targetController.PriceDecimalDigits),
- result.LogicalNozzleId,
- int.Parse(result.ProductBarcode),
- this.nozzleExtraInfos
- .FirstOrDefault(n => n.PumpId == pumpId && n.NozzleLogicalId == result.LogicalNozzleId)?.ProductName ??
- ("refer cloud for name of " + result.ProductBarcode), "", 1,
- int.Parse(result.TransactionSeqNumberFromPhysicalPump),
- (int)FuelSaleTransactionState.Payable,
- 0, trxDbUniqueId.ToString(),
- result.SaleStartTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- result.SaleEndTime?.ToString("yyyy-MM-dd HH:mm:ss"),
- "", "", unlockingClientId, 0);
- }
- else
- {
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.UnlockFuelSaleTrx(unlockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId, pumpId,
- transactionNo, trxDbUniqueId.ToString(), (int)ErrorCode.ERRCD_TRANSLOCKED, 1, OverallResult.Failure.ToString());
- }
- return result;
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("UnlockFuelSaleTrxAndNotifyAllFdcClients exceptioned for unlockingClientId: "
- + unlockingClientId + ", pumpId: " + pumpId + ", transactionNo: " + transactionNo + ", trxDbUniqueId: " + trxDbUniqueId + ", exception detail: " + exxx);
- throw;
- }
- }
-
-
-
-
-
-
-
-
-
-
- public async Task<bool> LockNozzleAndNotifyAllFdcClientsAsync(int lockingClientId,
- int pumpId,
- int logicalNozzleId)
- {
- return await this.LockNozzleAndNotifyAllFdcClientsAsync(lockingClientId, "", -1, pumpId, logicalNozzleId);
- }
-
-
-
-
-
-
-
-
-
-
-
-
- public async Task<bool> LockNozzleAndNotifyAllFdcClientsAsync(int lockingClientId, string fdcClientAppSender, int fdcClientRequestId,
- int pumpId,
- int logicalNozzleId)
- {
- try
- {
- fdcLogger.LogDebug("LockNozzleAndNotifyAllFdcClientsAsync from lockingClientId: " + lockingClientId
- + ", fdcClientAppSender: " + (fdcClientAppSender ?? "")
- + ", fdcClientRequestId: " + fdcClientRequestId
- + ", pumpId: " + pumpId + ", logicalNozzleId: " + logicalNozzleId);
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
- var result = await targetController.LockNozzleAsync((byte)logicalNozzleId);
- if (result)
- {
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.LockNozzle(lockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId,
- pumpId, pumpId, logicalNozzleId,
- (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- }
- else
- {
- fdcLogger.LogDebug("LockNozzleAndNotifyAllFdcClientsAsync failed");
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.LockNozzle(lockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId,
- pumpId, pumpId, logicalNozzleId,
- (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.Failure.ToString());
- }
- return result;
- }
- catch (Exception exx)
- {
- fdcLogger.LogError("LockNozzleAndNotifyAllFdcClientsAsync exceptioned for lockingClientId: "
- + lockingClientId + ", pumpId: " + pumpId + ", logicalNozzleId: " + logicalNozzleId + ", exception detail: " + exx);
- fdcServer.LockNozzle(lockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId,
- pumpId, pumpId, logicalNozzleId,
- (int)ErrorCode.ERRCD_NOTALLOWED, OverallResult.Failure.ToString());
- return false;
- }
- }
-
-
-
-
-
-
-
-
-
- public async Task<bool> UnlockNozzleAndNotifyAllFdcClientsAsync(int lockingClientId,
- int pumpId,
- int logicalNozzleId)
- {
- return await this.UnlockNozzleAndNotifyAllFdcClientsAsync(lockingClientId, "", -1, pumpId, logicalNozzleId);
- }
-
-
-
-
-
-
-
-
-
-
-
- public async Task<bool> UnlockNozzleAndNotifyAllFdcClientsAsync(int unlockingClientId, string fdcClientAppSender, int fdcClientRequestId, int pumpId,
- int logicalNozzleId)
- {
- try
- {
- fdcLogger.LogDebug("UnlockNozzleAndNotifyAllFdcClientsAsync from lockingClientId: " + unlockingClientId
- + ", fdcClientAppSender: " + (fdcClientAppSender ?? "")
- + ", fdcClientRequestId: " + fdcClientRequestId
- + ", pumpId: " + pumpId + ", logicalNozzleId: " + logicalNozzleId);
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
- var result = await targetController.UnlockNozzleAsync((byte)logicalNozzleId);
- if (result)
- {
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.UnlockNozzle(unlockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId,
- pumpId, pumpId,
- logicalNozzleId,
- (int)ErrorCode.ERRCD_OK, OverallResult.Success.ToString());
- }
- else
- {
- fdcLogger.LogDebug("UnlockNozzleAndNotifyAllFdcClientsAsync failed");
-
-
- if (!string.IsNullOrEmpty(fdcClientAppSender))
- fdcServer.UnlockNozzle(unlockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId,
- pumpId, pumpId,
- logicalNozzleId, (int)ErrorCode.ERRCD_NOTPOSSIBLE, OverallResult.Failure.ToString());
- }
- return result;
- }
- catch (Exception exx)
- {
- fdcLogger.LogError("UnlockNozzleAndNotifyAllFdcClientsAsync exceptioned for lockingClientId: "
- + unlockingClientId + ", pumpId: " + pumpId + ", logicalNozzleId: " + logicalNozzleId + ", exception detail: " + exx);
- fdcServer.UnlockNozzle(unlockingClientId.ToString(), fdcClientAppSender, fdcClientRequestId,
- pumpId, pumpId,
- logicalNozzleId, (int)ErrorCode.ERRCD_NOTALLOWED, OverallResult.Failure.ToString());
- return false;
- }
- }
-
-
-
-
-
-
- [UniversalApi(Description = "returned value are With decimal points value, format-> Money:Volume")]
- public async Task<Tuple<double, double>> GetFuelPointTotalsAsync(int pumpId, byte nozzleLogicalId)
- {
- try
- {
- if (fdcLogger.IsEnabled(LogLevel.Debug))
- fdcLogger.LogDebug("GetFuelPointTotals for pumpId: " + pumpId + ", nozzleLogicalId: " + nozzleLogicalId);
- var targetController = fdcPumpControllers.First(c => c.PumpId == pumpId) as IFdcPumpController;
- var totalizerResultTask = targetController.QueryTotalizerAsync(nozzleLogicalId);
- await Task.WhenAny(totalizerResultTask, Task.Delay(10000));
- if (totalizerResultTask.IsCompleted)
- {
- if (fdcLogger.IsEnabled(LogLevel.Debug))
- fdcLogger.LogDebug(" GetFuelPointTotals for pumpId: " + pumpId
- + ", nozzleLogicalId: " + nozzleLogicalId
- + ", no decimal point Money<->Volume pair is: " + totalizerResultTask.Result.Item1 + "<->" + totalizerResultTask.Result.Item2);
- return new Tuple<double, double>(
- totalizerResultTask.Result.Item1 / Math.Pow(10, targetController.AmountDecimalDigits),
- totalizerResultTask.Result.Item2 / Math.Pow(10, targetController.VolumeDecimalDigits));
- }
- else
- {
- fdcLogger.LogInformation(" GetFuelPointTotals for pumpId: " + pumpId
- + ", nozzleLogicalId: " + nozzleLogicalId + " timed out.");
- return new Tuple<double, double>(-1, -1);
- }
- }
- catch (Exception ex)
- {
- fdcLogger.LogError("GetFuelPointTotals for pumpId:" + pumpId +
- ", nozzleLogicalId: " + nozzleLogicalId + " exception:" + ex.Message);
- return new Tuple<double, double>(-1, -1);
- }
- }
-
-
-
-
-
- public IFdcPumpController GetFdcPumpController(int pumpId)
- {
- if (fdcLogger.IsEnabled(LogLevel.Debug))
- fdcLogger.LogDebug("GetFdcPumpController for pumpId: " + pumpId);
- var targetController = fdcPumpControllers
- .First(c => c.PumpId == pumpId) as IFdcPumpController;
- return targetController;
- }
-
-
-
-
-
-
-
- public async Task<IEnumerable<FuelSaleTransaction>> GetAvailableFuelSaleTrxsWithDetailsAsync(int pumpId)
- {
- return await this.GetAvailableFuelSaleTrxsWithDetailsAsync(pumpId, -1, 100);
- }
-
-
-
-
-
-
-
- [UniversalApi(Description = "get the latest fuel transactions with state Payable or Locked.")]
- public async Task<IEnumerable<FuelSaleTransaction>> GetAvailableFuelSaleTrxsWithDetailsAsync(int pumpId, int nozzleLogicalId, int rowCount)
- {
-
- int maxReturnDays = 365;
-
- int maxReturnDataCount = rowCount;
- try
- {
- var dueDate = DateTime.Now.Subtract(new TimeSpan(maxReturnDays, 0, 0, 0));
- SqliteDbContext dbContext = new SqliteDbContext();
- if (pumpId == -1)
- {
- if (nozzleLogicalId == -1)
- {
- var all = await dbContext.PumpTransactionModels.Where(t => t.State != FuelSaleTransactionState.Paid
- && t.State != FuelSaleTransactionState.Cleared
- && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime).Take(maxReturnDataCount).ToListAsync();
- return all;
- }
- else
- {
- var all = await dbContext.PumpTransactionModels.Where(t => t.LogicalNozzleId == nozzleLogicalId
- && t.State != FuelSaleTransactionState.Paid
- && t.State != FuelSaleTransactionState.Cleared
- && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime).Take(maxReturnDataCount).ToListAsync();
- return all;
- }
- }
- if (nozzleLogicalId == -1)
- {
- var some = await dbContext.PumpTransactionModels.Where(t => t.PumpId == pumpId
- && t.State != FuelSaleTransactionState.Paid
- && t.State != FuelSaleTransactionState.Cleared
- && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime).Take(maxReturnDataCount).ToListAsync();
- return some;
- }
- else
- {
- var some = await dbContext.PumpTransactionModels.Where(t => t.PumpId == pumpId
- && t.LogicalNozzleId == nozzleLogicalId
- && t.State != FuelSaleTransactionState.Paid
- && t.State != FuelSaleTransactionState.Cleared
- && t.SaleStartTime >= dueDate)
- .OrderByDescending(r => r.SaleStartTime).Take(maxReturnDataCount).ToListAsync();
- return some;
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("GetAvailableFuelSaleTrxsWithDetails for pumpId: " + pumpId
- + ", nozzleLogicalId: " + nozzleLogicalId
- + ", rowCount: " + rowCount + " exceptioned: "
- + exxx.ToString());
- return null;
- }
- }
-
-
-
-
-
-
-
-
-
- [UniversalApi(Description = "get the latest fuel transactions by conditions.</br>" +
- "<param name=\"pumpId\">the target pump id, or null for all pumps</param></br>" +
- "<param name=\"nozzleLogicalId\">further specify the nozzle logical id, or null for all nozzles in the pump.</param></br>" +
- "<param name=\"pageRowCount\">for paging the returned data, controls how many data rows in a single page</param></br>" +
- "<param name=\"pageIndex\">for paging the returned data, controls return which data page</param></br>" +
- "<param name=\"filterTimestamp\">controls trx that only with its SaleStartTime >= filterTimestamp will be returned, leave null to ignore this check, the results are ordered by SaleStartTime (with default ascending)</param>")]
- public async Task<IEnumerable<FuelSaleTransaction>> GetFuelSaleTrxsWithDetailsAsync(int? pumpId, int? nozzleLogicalId,
- FuelSaleTransactionState transactionState,
- int pageRowCount = 10, int pageIndex = 0, DateTime? filterTimestamp = null, bool isAscending = true)
- {
-
- int maxReturnDays = 60;
- try
- {
- var dueDate = DateTime.Now.Subtract(new TimeSpan(maxReturnDays, 0, 0, 0));
- if (filterTimestamp != null)
- dueDate = filterTimestamp.Value;
- SqliteDbContext dbContext = new SqliteDbContext();
- if (!pumpId.HasValue)
- {
- IOrderedQueryable<FuelSaleTransaction> orderedResults = null;
- if (isAscending)
- orderedResults = dbContext.PumpTransactionModels.Where(t => t.State == transactionState
- && t.SaleStartTime >= dueDate).OrderBy(r => r.SaleStartTime);
- else
- orderedResults = dbContext.PumpTransactionModels.Where(t => t.State == transactionState
- && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime);
- var all = await orderedResults.Skip(pageRowCount * pageIndex).Take(pageRowCount).ToListAsync();
- return all;
- }
- if (!nozzleLogicalId.HasValue)
- {
- IOrderedQueryable<FuelSaleTransaction> orderedResults = null;
- if (isAscending)
- orderedResults = dbContext.PumpTransactionModels.Where(t => t.PumpId == pumpId
- && t.State == transactionState && t.SaleStartTime >= dueDate).OrderBy(r => r.SaleStartTime);
- else
- orderedResults = dbContext.PumpTransactionModels.Where(t => t.PumpId == pumpId
- && t.State == transactionState && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime);
- var some = await orderedResults.Skip(pageRowCount * pageIndex).Take(pageRowCount).ToListAsync();
- return some;
- }
- else
- {
- IOrderedQueryable<FuelSaleTransaction> orderedResults = null;
- if (isAscending)
- orderedResults = dbContext.PumpTransactionModels.Where(t => t.PumpId == pumpId
- && t.LogicalNozzleId == nozzleLogicalId
- && t.State == transactionState && t.SaleStartTime >= dueDate).OrderBy(r => r.SaleStartTime);
- else
- orderedResults = dbContext.PumpTransactionModels.Where(t => t.PumpId == pumpId
- && t.LogicalNozzleId == nozzleLogicalId
- && t.State == transactionState && t.SaleStartTime >= dueDate).OrderByDescending(r => r.SaleStartTime);
- var some = await orderedResults.Skip(pageRowCount * pageIndex).Take(pageRowCount).ToListAsync();
- return some;
- }
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError($"GetFuelSaleTrxsWithDetailsAsync for pumpId: { pumpId }, nozzleLogicalId: { nozzleLogicalId }, " +
- $"pageRowCount: { pageRowCount }, pageIndex: {pageIndex}, filterTimestamp: {filterTimestamp ?? DateTime.MinValue}, isAscending: {isAscending}, exceptioned:{exxx}");
- return null;
- }
- }
-
-
-
-
-
-
- [UniversalApi]
- public async Task<IEnumerable<LogicalNozzle>> ChangeFuelPriceAsync(int barcode, double newPriceWithDecimalPoints)
- {
- try
- {
- fdcLogger.LogInformation("ChangeFuelPrice for product with barcode: " + barcode
- + " to new price(with decimal points): " + newPriceWithDecimalPoints);
- var targetNozzles = fdcPumpControllers.SelectMany(p => p.Nozzles).Join(
- nozzleExtraInfos.Where(c => c.ProductBarcode == barcode),
- n => n.PumpId + "," + n.LogicalId,
- c => c.PumpId + "," + c.NozzleLogicalId,
- (n, c) => n);
- if (!targetNozzles.Any())
- {
- fdcLogger.LogError("ChangeFuelPrice, have NOT seen product with barcode: " + barcode
- + " bound to any nozzles from all pumps, will quit.");
- return null;
- }
-
- var succeedNozzles = new List<LogicalNozzle>();
- foreach (var nozzle in targetNozzles)
- {
- bool succeed = false;
- var targetController = fdcPumpControllers.First(p => p.PumpId == nozzle.PumpId);
- var pumpRawFormatPrice = (int)(
- Math.Round(newPriceWithDecimalPoints * Math.Pow(10, targetController.PriceDecimalDigits),
- MidpointRounding.AwayFromZero));
- var previousPrice = targetController.Nozzles
- .First(n => n.LogicalId == nozzle.LogicalId)?.RealPriceOnPhysicalPump;
-
-
-
-
-
-
-
-
- FuelPriceChange dbFuelPriceChange = null;
- try
- {
- dbFuelPriceChange = new FuelPriceChange()
- {
- PumpId = nozzle.PumpId,
- LogicalNozzleId = nozzle.LogicalId,
- NewPriceWithoutDecimal = pumpRawFormatPrice,
- StartTime = DateTime.Now,
- FinishTime = null
- };
- var dbContext = new SqliteDbContext();
- dbContext.FuelPriceChanges.Add(dbFuelPriceChange);
- await dbContext.SaveChangesAsync();
-
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError(" ChangeFuelPrice, new price pre-save into database for pump: "
- + targetController.PumpId + ", logical Nozzle: " + nozzle.LogicalId
- + " exceptioned: " + exxx
- + Environment.NewLine
- + "Will ignore this nozzle and continue to next...");
- continue;
- }
- try
- {
- succeed = await targetController.ChangeFuelPriceAsync(pumpRawFormatPrice, nozzle.LogicalId);
- fdcLogger.LogInformation(" ChangeFuelPrice succeed in IFdcController side for pump with PumpId: " + targetController.PumpId
- + ", LogicalNozzleId: " + nozzle.LogicalId);
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError(" ChangeFuelPrice, pump " + targetController.PumpId
- + ", logical nozzle " + nozzle.LogicalId + " exceptioned in pump side: "
- + exxx
- + Environment.NewLine
- + "Will continue to next nozzle.");
- continue;
- }
- if (succeed)
- {
- succeedNozzles.Add(nozzle);
-
-
- try
- {
- dbFuelPriceChange.FinishTime = DateTime.Now;
- var dbContext = new SqliteDbContext();
- await dbContext.SaveChangesAsync();
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError(" ChangeFuelPrice, new price post-save into database for pump: "
- + targetController.PumpId
- + ", logicalNozzle: " + nozzle.LogicalId + " exceptioned: "
- + exxx
- + Environment.NewLine
- + "Will ignore and continue to next nozzle");
- }
- }
- else
- {
- fdcLogger.LogError(" ChangeFuelPrice, Pump " + targetController.PumpId
- + ", NozzleLogicalId " + nozzle.LogicalId + " apply new price failed on pump side");
- }
- }
- return succeedNozzles;
- }
- catch (Exception exxx)
- {
- fdcLogger.LogError("ChangeFuelPrice, generic exception: " + exxx);
- return null;
- }
- }
- #endregion
- }
- }
|