From 583ed975399b4fa9cdef75b412326ebfd2bb36f0 Mon Sep 17 00:00:00 2001 From: Loretta Date: Mon, 16 Dec 2024 08:47:15 +0100 Subject: [PATCH] AuctionHub refactoring in progress... --- .../LiveAnnouncementViewComponent.cs | 74 ++++---- .../Hubs/AuctionHub.cs | 170 ++++++++++-------- .../Services/AuctionBackgroundService.cs | 48 ++++- 3 files changed, 171 insertions(+), 121 deletions(-) diff --git a/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs b/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs index db7d881..9d88dc6 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs @@ -24,54 +24,54 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Components { var customer = await workContext.GetCurrentCustomerAsync(); - await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Before lock; widgetZone: {widgetZone}", null, customer); + //await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Before lock; widgetZone: {widgetZone}", null, customer); - using (await lockService.SemaphoreSlim.UseWaitAsync()) - { - await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Enter lock; widgetZone: {widgetZone}", null, customer); + //using (await lockService.SemaphoreSlim.UseWaitAsync()) + //{ + // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Enter lock; widgetZone: {widgetZone}", null, customer); - await Task.Delay(1000); + // await Task.Delay(1000); - var auctions = await auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); - if (auctions.Count > 0) - { - await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}"); + // var auctions = await auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); + // if (auctions.Count > 0) + // { + // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}"); - var statusChangedMessageWrapper = new MessageWrapper - { - MessageType = nameof(ProductToAuctionStatusNotification), - SenderId = 0, - ResponseType = ResponseType.ToAllClients - }; + // var statusChangedMessageWrapper = new MessageWrapper + // { + // MessageType = nameof(ProductToAuctionStatusNotification), + // SenderId = 0, + // ResponseType = ResponseType.ToAllClients + // }; - foreach (var auction in auctions) - { - auction.Closed = false; - await auctionService.UpdateAuctionAsync(auction); + // foreach (var auction in auctions) + // { + // auction.Closed = false; + // await auctionService.UpdateAuctionAsync(auction); - var auctionDto = new AuctionDto(auction); - var productToAuctions = (await auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList(); + // var auctionDto = new AuctionDto(auction); + // var productToAuctions = (await auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList(); - foreach (var productToAuction in productToAuctions) - { - productToAuction.AuctionStatus = AuctionStatus.Active; - auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); + // foreach (var productToAuction in productToAuctions) + // { + // productToAuction.AuctionStatus = AuctionStatus.Active; + // auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); - ////TEMPOPRARY - J. - //statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); - //await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); - ////TEMPOPRARY - J. - } + // ////TEMPOPRARY - J. + // //statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); + // //await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); + // ////TEMPOPRARY - J. + // } - await auctionService.UpdateProductToAuctionMappingAsync(productToAuctions); + // await auctionService.UpdateProductToAuctionMappingAsync(productToAuctions); - statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); - await auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); - } - } + // statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); + // await auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); + // } + // } - await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Exit lock; widgetZone: {widgetZone}", null, customer); - } + // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Exit lock; widgetZone: {widgetZone}", null, customer); + //} await logger.InformationAsync($"SignalR Widget called customer: {customer.Email}"); diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs index 51ef2fc..7215542 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -101,21 +101,20 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer); //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J. - //using (await _handleMessageMutex.WaitOne()) using (await lockService.SemaphoreSlim.UseWaitAsync()) { try { await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); - await Task.Delay(3000); + //await Task.Delay(3000); //TODO: ez csak a teszt időszakig van itt!!! - J. if (messageWrapper.MessageType == "BidRequestMessage") return await HandleBidRequestAsync(customer, messageWrapper); else { - if (!await customerService.IsAdminAsync(customer)) + if (!customer.IsSystemAccount && !await customerService.IsAdminAsync(customer)) { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); + logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (!customer.IsSystemAccount && !await customerService.IsAdminAsync(customer)); connectionId: {connectionId}", null, customer); return ResponseType.Error; } @@ -281,7 +280,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (auctionProductStatusRequest == null) { logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); - return ResponseType.Error; + return ResponseType.None; } try @@ -289,78 +288,10 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs //var responseType = ResponseType.ToAllClients; await logger.InformationAsync($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer); - var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId); - if (productToAuction == null) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer); - return ResponseType.Error; - } + var (auction, productToAuction, responseType) = await GetAndUpdateProductToAuctionStatusIfValidAsync(auctionProductStatusRequest.ProductToAuctionId, auctionProductStatusRequest.AuctionStatus, customer); + if (auction == null || productToAuction == null || responseType == ResponseType.None) return ResponseType.None; - var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); - if (auction == null || auction.Closed) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); - return ResponseType.Error; - } - - if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus)) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); RequestAuctionStatusIsValid() == false; newStatus: {auctionProductStatusRequest.AuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer); - - await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToCaller); - return ResponseType.Error; - } - - if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId); - else - { - switch (auctionProductStatusRequest.AuctionStatus) - { - case AuctionStatus.Active: - productToAuction.AuctionStatus = AuctionStatus.Active; - await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true); - break; - - case AuctionStatus.FirstWarning: - case AuctionStatus.SecondWarning: - productToAuction.AuctionStatus = auctionProductStatusRequest.AuctionStatus; - break; - - case AuctionStatus.Sold: - var lastAuctionBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id); - if (lastAuctionBid == null) productToAuction.AuctionStatus = AuctionStatus.NotSold; - else - { - productToAuction.AuctionStatus = AuctionStatus.Sold; - productToAuction.CurrentPrice = lastAuctionBid.BidPrice; - productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId; - - var placeOrderResult = await auctionService.CreateOrderForWinnerAsync(productToAuction); - if (placeOrderResult == null || placeOrderResult.Id == 0) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (placeOrderResult == null || placeOrderResult.Id == 0)", null, customer); - //return; //TODO: EGYELŐRE HAGYJUK LEZÁRNI AKKOR IS, HA NEM SIKERÜLT AZ ORDERPLACE()! - J. - } - } - - await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, false); - break; - - case AuctionStatus.Pause: - productToAuction.AuctionStatus = AuctionStatus.Pause; - break; - - default: - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer); - - await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToCaller); - return ResponseType.Error; - } - - await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); - } - - await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToAllClients); + await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, responseType); //TODO: gond van ha az Admin valamit módosít és újrazár egy régi ProductToAuction-t!!!! AuctionRequestMode.Normal...- J. if ( /*AuctionRequestMode.Normal &&*/ auction.AuctionType == AuctionType.AutomaticNext && productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold) @@ -376,6 +307,86 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs return ResponseType.Error; } + private async Task UpdateProductToAuctionStatusIfValidAsync(AuctionStatus newProductToAuctionStatus, Auction auction, ProductToAuctionMapping productToAuction, Customer customer) + { + if (!IsValidRequestAuctionStatus(newProductToAuctionStatus, productToAuction.AuctionStatus)) + { + logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); RequestAuctionStatusIsValid() == false; newStatus: {newProductToAuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer); + + return ResponseType.ToCaller; + } + + if (newProductToAuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId); + else + { + switch (newProductToAuctionStatus) + { + case AuctionStatus.Active: + productToAuction.AuctionStatus = AuctionStatus.Active; + await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true); + break; + + case AuctionStatus.FirstWarning: + case AuctionStatus.SecondWarning: + productToAuction.AuctionStatus = newProductToAuctionStatus; + break; + + case AuctionStatus.Sold: + var lastAuctionBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id); + if (lastAuctionBid == null) productToAuction.AuctionStatus = AuctionStatus.NotSold; + else + { + productToAuction.AuctionStatus = AuctionStatus.Sold; + productToAuction.CurrentPrice = lastAuctionBid.BidPrice; + productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId; + + var placeOrderResult = await auctionService.CreateOrderForWinnerAsync(productToAuction); + if (placeOrderResult == null || placeOrderResult.Id == 0) + { + logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); (placeOrderResult == null || placeOrderResult.Id == 0)", null, customer); + //return; //TODO: EGYELŐRE HAGYJUK LEZÁRNI AKKOR IS, HA NEM SIKERÜLT AZ ORDERPLACE()! - J. + } + } + + await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, false); + break; + + case AuctionStatus.Pause: + productToAuction.AuctionStatus = AuctionStatus.Pause; + break; + + default: + logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); AuctionStatus not found; (newStatus == {newProductToAuctionStatus})", null, customer); + + return ResponseType.ToCaller; + } + + await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); + } + + return ResponseType.ToAllClients; + } + + private async Task<(Auction auction, ProductToAuctionMapping productToAuction, ResponseType responseType)> GetAndUpdateProductToAuctionStatusIfValidAsync(int productToAuctionId, AuctionStatus newProductToAuctionStatus, Customer customer) + { + var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(productToAuctionId); + if (productToAuction == null) + { + logger.Error($"AuctionHub.GetAndUpdateProductToAuctionStatusIfValidAsync(); (productToAuction == null)", null, customer); + return (null, null, ResponseType.None); + } + + var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); + if (auction == null || auction.Closed) + { + logger.Error($"AuctionHub.GetAndUpdateProductToAuctionStatusIfValidAsync(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); + return (null, null, ResponseType.None); + } + + var responseType = await UpdateProductToAuctionStatusIfValidAsync(newProductToAuctionStatus, auction, productToAuction, customer); + return (auction, productToAuction, responseType); + } + private async Task SendStatusChangedNotificationAsync(Customer customer, MessageWrapper statusChangedMessageWrapper, ProductToAuctionMapping productToAuction, ResponseType responseType) { await UpdateStatusChangedNotificationMessageWrapperAsync(statusChangedMessageWrapper, customer, productToAuction, responseType); @@ -558,6 +569,9 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs break; case ResponseType.Error: + messageWrapper.HideToaster = false; + await Clients.Caller.send(messageWrapper.ToJson()); + break; default: throw new ArgumentOutOfRangeException(); @@ -596,9 +610,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs sessionItem = null; var httpContext = Context.GetHttpContext(); - if (httpContext == null) return false; - - return !sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem); + return httpContext != null && sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem); } } } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs index 92478bd..420db33 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs @@ -1,9 +1,13 @@ -using AyCode.Utils.Extensions; +using AyCode.Core.Extensions; +using AyCode.Utils.Extensions; using Mango.Nop.Services; using Microsoft.AspNetCore.SignalR; using Nop.Core; using Nop.Core.Domain.Customers; using Nop.Data; +using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Plugin.Misc.AuctionPlugin.Hubs; using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Services.Customers; @@ -17,13 +21,16 @@ public class AuctionBackgroundService : MgBackgroundServiceBase private readonly IHubContext _auctionHubContext; private readonly ILockService _lockService; + private readonly AuctionService _auctionService; private readonly Customer _auctionSystemCustomer; public AuctionBackgroundService(ILogger logger, IServiceProvider service, IHubContext auctionHubContext, AuctionService auctionService, ILockService lockService, IRepository customerService) : base(logger, service) { _logger = logger; _auctionHubContext = auctionHubContext; + _lockService = lockService; + _auctionService = auctionService; _auctionSystemCustomer = customerService.Table.FirstOrDefault(x => x.Email == "builtin@background_task_auction.com"); @@ -37,16 +44,47 @@ public class AuctionBackgroundService : MgBackgroundServiceBase if (_auctionSystemCustomer == null) return; - //await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Before lock; ", null, _auctionSystemCustomer); + await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Before lock; ", null, _auctionSystemCustomer); using (await _lockService.SemaphoreSlim.UseWaitAsync()) { + await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Enter lock;", null, _auctionSystemCustomer); - //var auctionDto = auctionService.GetProductToAuctionDtosByAuctionId() - //await auctionHubContext.Clients.All.SendAsync("send", new MessageWrapper()); + var auctions = await _auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); + if (auctions.Count > 0) + { + await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}", null, _auctionSystemCustomer); - await _auctionHubContext.Clients.All.SendAsync("OnDateTimeReceive", DateTime.Now.ToString("G")); + var statusChangedMessageWrapper = new MessageWrapper + { + MessageType = nameof(ProductToAuctionStatusNotification), + SenderId = _auctionSystemCustomer.Id, + ResponseType = ResponseType.ToAllClients + }; + foreach (var auction in auctions) + { + auction.Closed = false; + await _auctionService.UpdateAuctionAsync(auction); + + var auctionDto = new AuctionDto(auction); + var productToAuctions = (await _auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList(); + + foreach (var productToAuction in productToAuctions) + { + productToAuction.AuctionStatus = AuctionStatus.Active; + auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); + } + + await _auctionService.UpdateProductToAuctionMappingAsync(productToAuctions); + + statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); + await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); + } + } + + await _auctionHubContext.Clients.All.SendAsync("OnDateTimeReceive", DateTime.Now.ToString("G")); //TODO: ez csak a teszt időszakig van itt!!! - J. + await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Exit lock;", null, _auctionSystemCustomer); } } } \ No newline at end of file