From cb83fbe077f7af4ec57457c7ea2690e89531e0a9 Mon Sep 17 00:00:00 2001 From: Loretta Date: Wed, 20 Nov 2024 14:53:00 +0100 Subject: [PATCH] improvements, fixes, etc... --- .../Controllers/AnnouncementController.cs | 1 + .../Hubs/Messages/AuctionNotificationBase.cs | 8 +++++ .../AuctionProductStatusNotification.cs | 6 ++++ .../Messages/AuctionStatusNotification.cs | 6 ++++ .../Hubs/Messages/BidNotificationMessage.cs | 11 +++++- .../Hubs/SignalRMessageHandler.cs | 34 ++++++++++++++----- .../Services/AuctionService.cs | 23 ++++++++++--- 7 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionNotificationBase.cs create mode 100644 Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionProductStatusNotification.cs create mode 100644 Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionStatusNotification.cs diff --git a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs index 0baf97b..308a04c 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs @@ -118,6 +118,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Controllers MessageType = "bidNotification", Data = new BidNotificationMessage { + //AuctionDto = TODO: ??? - J. ProductName = viewModel.ProductName, BidPrice = viewModel.BidPrice.ToString(), NextStepAmount = viewModel.NextStepAmount.ToString() diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionNotificationBase.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionNotificationBase.cs new file mode 100644 index 0000000..c505ca3 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionNotificationBase.cs @@ -0,0 +1,8 @@ +using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; + +namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; + +public abstract class AuctionNotificationBase +{ + public AuctionDto AuctionDto { get; set; } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionProductStatusNotification.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionProductStatusNotification.cs new file mode 100644 index 0000000..4b1ccc2 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionProductStatusNotification.cs @@ -0,0 +1,6 @@ +namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; + +public class AuctionProductStatusNotification : AuctionNotificationBase +{ + +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionStatusNotification.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionStatusNotification.cs new file mode 100644 index 0000000..c538cdc --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionStatusNotification.cs @@ -0,0 +1,6 @@ +namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; + +public class AuctionStatusNotification : AuctionNotificationBase +{ + +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs index 34d05f1..d7beff2 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages { @@ -11,10 +12,18 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages /// this message sends update to the clients. so it sends current (the already winner) price, /// sends the ACTUAL bidstep, so the new price, and next bid can be calculated on the client side /// - public class BidNotificationMessage + public class BidNotificationMessage : AuctionNotificationBase { public string ProductName { get; set; } public string BidPrice { get; set; } public string NextStepAmount { get; set; } + + public BidNotificationMessage() { } + + public BidNotificationMessage(AuctionDto auctionDto) + { + AuctionDto = auctionDto; + } } + } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs index 3504dcf..7445cf9 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs @@ -11,6 +11,8 @@ using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Newtonsoft.Json.Serialization; using Microsoft.AspNetCore.SignalR; using Nop.Core; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; +using Nop.Services.Customers; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { @@ -46,6 +48,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs // return; //} + //TODO: lock-olni! - J. switch (message.MessageType) { case "BidRequestMessage": @@ -69,11 +72,20 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs try { - await _logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received: - Auction: {bidRequestMessage.AuctionId} Product: {bidRequestMessage.ProductId} - Bid: {bidRequestMessage.BidPrice} - Customer: {bidRequestMessage.CustomerId}"); + await _logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received; Auction: {bidRequestMessage.AuctionId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}"); - if (bidRequestMessage.CustomerId != (await _workContext.GetCurrentCustomerAsync()).Id) + //CustomerService a = new CustomerService()a.IsGuestAsync() + var customer = await _workContext.GetCurrentCustomerAsync(); + if (customer == null || bidRequestMessage.CustomerId != customer.Id) //|| !customer.Active) //TODO: ??? - J. { - _logger.Error($"SignalRMessageHandler.HandleBidRequest(); bidRequestMessage.CustomerId != (await _workContext.GetCurrentCustomerAsync()).Id"); + _logger.Error($"SignalRMessageHandler.HandleBidRequest(); customer == null || bidRequestMessage.CustomerId != customer.Id"); + return; + } + + var auction = await _auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId); + if (auction.Closed) + { + _logger.Warning($"SignalRMessageHandler.HandleBidRequest(); auction.Closed"); return; } @@ -84,15 +96,15 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs return; //ha nincs product vagy exception van, akkor ne broadcast-eljük ki az invalid Bid-et! - J. } - var mapping = await _auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId); - if (mapping == null || mapping.Count == 0) + var activeProductAuction = (await _auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault(); + if (activeProductAuction == null) //|| productAuction.WinnerCustomerId == customer.Id) { - _logger.Error($"SignalRMessageHandler.HandleBidRequest(); mapping == null || mapping.Count == 0"); - return; //ha nincs ProductToAuction, akkor ne broadcast-eljük ki az invalid Bid-et! - J. + _logger.Warning($"SignalRMessageHandler.HandleBidRequest(); activeProductAuction == null"); + return; //TODO: - J. } var auctionBid = bidRequestMessage.CreateMainEntity(); - auctionBid.ProductAuctionMappingId = mapping.FirstOrDefault()!.Id; + auctionBid.ProductAuctionMappingId = activeProductAuction.Id; //TODO: validate the bidprice amount if (product.Price >= auctionBid.BidPrice) @@ -108,11 +120,15 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs product.Price = bidRequestMessage.BidPrice; await _productService.UpdateProductAsync(product); + activeProductAuction.StartingPrice = product.OldPrice; + activeProductAuction.BidPrice = product.Price; + await _auctionService.UpdateProductToAuctionMappingAsync(activeProductAuction); + // Optionally broadcast to all clients var bid = new MessageWrapper { MessageType = "bidNotification", - Data = new BidNotificationMessage + Data = new BidNotificationMessage(await _auctionService.GetAuctionDtoWithProductByIdAsync(auction.Id, activeProductAuction.ProductId, true)) { ProductName = auctionBid.ProductId.ToString(), BidPrice = auctionBid.BidPrice.ToString(CultureInfo.InvariantCulture), diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs index c8b4d23..c7eec9d 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs @@ -7,6 +7,7 @@ using Nop.Plugin.Misc.AuctionPlugin.Domains; using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Services.Logging; namespace Nop.Plugin.Misc.AuctionPlugin.Services; @@ -146,6 +147,12 @@ public class AuctionService : IAuctionService await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } + public virtual async Task UpdateAuctionAsync(Auction auction) + { + await _ctx.Auctions.UpdateAsync(auction); + await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); + } + public async Task> GetAllAuctionsAsync() { return await _ctx.Auctions.GetAllAuctionsAsync(); @@ -166,13 +173,13 @@ public class AuctionService : IAuctionService return auction == null ? null : new AuctionDto(auction); } - public async Task GetAuctionDtoWithProductByIdAsync(int auctionId, int productId) + public async Task GetAuctionDtoWithProductByIdAsync(int auctionId, int productId, bool activeProductOnly = false) { var auction = await _ctx.Auctions.GetByIdAsync(auctionId); if (auction == null) return null; var auctionDto = new AuctionDto(auction); - auctionDto.ProductToAuctionDtos.AddRange(await _ctx.ProductToAuctions.GetByAuctionAndProductId(auctionId, productId).Select(x => new ProductToAuctionDto(x)).ToListAsync()); + auctionDto.ProductToAuctionDtos.AddRange((await GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, activeProductOnly)).Select(x => new ProductToAuctionDto(x))); return auctionDto; } @@ -206,9 +213,11 @@ public class AuctionService : IAuctionService return new List(await _ctx.ProductToAuctions.GetByProductId(productId).ToListAsync()); } - public async Task> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId) + public async Task> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeOnly = false) { - return new List(await _ctx.ProductToAuctions.GetByAuctionAndProductId(auctionId, productId).ToListAsync()); + return new List(await _ctx.ProductToAuctions.GetByAuctionAndProductId(auctionId, productId) + .Where(x => !activeOnly || (x.AuctionStatus == AuctionStatus.Active || x.AuctionStatus == AuctionStatus.FirstWarning || x.AuctionStatus == AuctionStatus.SecondWarning)) + .ToListAsync()); } public async Task AssignProductToAuctionAsync(int productId, decimal startingPrice, decimal bidPrice, int auctionId) @@ -242,5 +251,11 @@ public class AuctionService : IAuctionService return mapping; } + public virtual async Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping) + { + await _ctx.ProductToAuctions.UpdateAsync(productToAuctionMapping); + await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); + } + #endregion Dtos } \ No newline at end of file