using System.Globalization; using AyCode.Core.Extensions; using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Plugin.Misc.AuctionPlugin.Models; using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Services.Catalog; using Nop.Services.Logging; using Microsoft.AspNetCore.SignalR; using Nop.Core; using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; namespace Nop.Plugin.Misc.AuctionPlugin.Hubs { //- FirstWarning, SecondWarning, //- ProductToAuctionDto ne lista legyen //- GetFullAuctionDto //- SortIndex //- Rátettem egy unique-ot az AuctionId és a ProductId-ra!!! //- Új field-ek a db-be! pl.: WinnerCustomerId, stb... //- IsActiveItem //- Product onupdate //- lock //- ha saját licit a legjobb vagy lezárt, ne lehessen bid-elni //- az előző esetben a kliensen a gombot is tiltani, már a.cshtml-ben ellenőrizni! //- ha nincs login elszállhat a kliens //- csak a watch-olt item-eknél legyen announcment //- ha bid-elt 1x is, kerüljön a watch-ba //- DbTransaction-t vhogy megcsinánli! //- NextStepAmount public class SignalRMessageHandler { private readonly ILogger _logger; private readonly IProductService _productService; private readonly AuctionService _auctionService; private readonly IHubContext _hubContext; private readonly IWorkContext _workContext; public SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext hubContext, IWorkContext workContext) { _logger = logger; _productService = productService; _auctionService = auctionService; _hubContext = hubContext; _workContext = workContext; } public async Task HandleMessage(MessageWrapper message) { if (message?.Data == null) { _logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null"); return; } await _logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); jsonData: {message.Data}"); if (message.SenderId <= 0 || message.SenderId != (await _workContext.GetCurrentCustomerAsync()).Id) { _logger.Error($"SignalRMessageHandler.HandleMessage(); message.SenderId <= 0 || message.SenderId != (await _workContext.GetCurrentCustomerAsync()).Id; SenderId: {message.SenderId}"); return; } //TODO: lock-olni! - J. switch (message.MessageType) { case "BidRequestMessage": await HandleBidRequest(message.SenderId, message.Data.JsonTo()); break; case "AuctionProductStatusRequest": await HandleProductToAuctionStatusChangedRequest(message.SenderId, message.Data.JsonTo()); break; // Add other message types here default: await _logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {message.MessageType}"); break; } } private async Task HandleProductToAuctionStatusChangedRequest(int senderId, AuctionProductStatusRequest auctionProductStatusRequest) { if (auctionProductStatusRequest == null) { _logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null"); return; } try { await _logger.InformationAsync($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})"); //TODO: if IsAdmin.. - J. //TODO: if nincs aktív item.. - J. var auction = await _auctionService.GetAuctionDtoByProductToAuctionIdAsync(auctionProductStatusRequest.ProductToAuctionId); if (auction == null || auction.Closed) { _logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auction == null || auction.Closed;"); return; } var productToAuction = await _auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId); if (productToAuction == null) { _logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); productToAuction == null"); return; } switch (auctionProductStatusRequest.AuctionStatus) { case AuctionStatus.FirstWarning: productToAuction.AuctionStatus = AuctionStatus.FirstWarning; //AuctionStatus.Active | AuctionStatus.FirstWarning; break; case AuctionStatus.SecondWarning: productToAuction.AuctionStatus = AuctionStatus.SecondWarning; //AuctionStatus.Active | AuctionStatus.SecondWarning; break; case AuctionStatus.None: case AuctionStatus.Active: case AuctionStatus.SoldOut: case AuctionStatus.NotSold: default: productToAuction.AuctionStatus = auctionProductStatusRequest.AuctionStatus; break; } await _auctionService.UpdateProductToAuctionMappingAsync(productToAuction); var productToauctionChangedNotification = new MessageWrapper { MessageType = nameof(ProductToAuctionStatusNotification), SenderId = senderId, Data = new ProductToAuctionStatusNotification(await _auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true)) { ToasterMessage = "string.Empty", //TODO: - J. }.ToJson() }; await _hubContext.Clients.All.SendAsync("send", productToauctionChangedNotification.ToJson()); } catch (Exception ex) { _logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); Error {ex.Message}"); } } private async Task HandleBidRequest(int senderId, AuctionBidRequest bidRequestMessage) { if (bidRequestMessage == null) { _logger.Error($"SignalRMessageHandler.HandleBidRequest(); bidRequestMessage == null"); return; } try { await _logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received; Auction: {bidRequestMessage.AuctionId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}"); //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(); customer == null || bidRequestMessage.CustomerId != customer.Id"); return; } var auction = await _auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId); if (auction.Closed) { _logger.Warning($"SignalRMessageHandler.HandleBidRequest(); auction.Closed"); return; } var product = await _productService.GetProductByIdAsync(bidRequestMessage.ProductId); if (product == null) { _logger.Error($"SignalRMessageHandler.HandleBidRequest(); product == null"); return; //ha nincs product vagy exception van, akkor ne broadcast-eljük ki az invalid Bid-et! - J. } var activeProductAuction = (await _auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault(); if (activeProductAuction == null) //|| productAuction.WinnerCustomerId == customer.Id) { _logger.Warning($"SignalRMessageHandler.HandleBidRequest(); activeProductAuction == null"); return; //TODO: - J. } var auctionBid = bidRequestMessage.CreateMainEntity(); auctionBid.ProductAuctionMappingId = activeProductAuction.Id; //TODO: validate the bidprice amount if (product.Price >= auctionBid.BidPrice) { _logger.Warning($"SignalRMessageHandler.HandleBidRequest(); product.Price >= bidRequestMessage.BidPrice; productPrice: {product.Price}; bidRequestPrice: {auctionBid.BidPrice}"); return; } //save bid await _auctionService.InsertBidAsync(auctionBid); //set new price product.Price = bidRequestMessage.BidPrice; await _productService.UpdateProductAsync(product); activeProductAuction.StartingPrice = product.OldPrice; activeProductAuction.BidPrice = product.Price; await _auctionService.UpdateProductToAuctionMappingAsync(activeProductAuction); var stepAmount = AuctionService.GetStepAmount(auctionBid.BidPrice); var nextBidPrice = auctionBid.BidPrice + stepAmount; //stepAmount = GetStepAmount(nextBidPrice); //Direkt van 2x, különben a sávváltásoknál lehet gond! - J. var bid = new MessageWrapper { MessageType = "bidNotification", SenderId = senderId, Data = new BidNotificationMessage(await _auctionService.GetAuctionDtoByProductToAuctionIdAsync(activeProductAuction.Id, true)) { ProductName = auctionBid.ProductId.ToString(), BidPrice = auctionBid.BidPrice, NextStepAmount = stepAmount, NextBidPrice = nextBidPrice, ToasterMessage = string.Empty, //TODO: - J. }.ToJson() }; await _hubContext.Clients.All.SendAsync("send", bid.ToJson()); } catch (Exception ex) { _logger.Error($"SignalRMessageHandler.HandleBidRequest(); MessageHandling error: {ex}"); } } } }