Mango.Nop.Plugins/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs

257 lines
12 KiB
C#

using AyCode.Core.Extensions;
using AyCode.Utils.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
{
//- Dollár currency
//- Pipa, ha tied a licit
//- Pause, Lezárás, Revert,
//- 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!
//- 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!
public class SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext<AuctionHub> hubContext, IWorkContext workContext)
{
private readonly Mutex _handleMessageMutex = new();
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;
}
using (_handleMessageMutex.UseWaitOne())
{
try
{
switch (message.MessageType)
{
case "BidRequestMessage":
await HandleBidRequest(message.SenderId, message.Data.JsonTo<AuctionBidRequest>());
break;
case "AuctionProductStatusRequest":
await HandleProductToAuctionStatusChangedRequest(message.SenderId, message.Data.JsonTo<AuctionProductStatusRequest>());
break;
// Add other message types here
default:
await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {message.MessageType}");
break;
}
}
catch (Exception ex)
{
logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {message.MessageType}; ex: {ex}");
}
}
}
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.
//productBidBoxViewModel.IsAdmin = await _customerService.IsAdminAsync(customer);
//productBidBoxViewModel.IsGuest = await _customerService.IsGuestAsync(customer);
//TODO: if nincs aktív item.. - J.
var auction = await auctionService.GetAuctionDtoByProductToAuctionIdAsync(auctionProductStatusRequest.ProductToAuctionId, false);
if (auction == null || auction.Closed)
{
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}");
return;
}
var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId);
if (productToAuction == null)
{
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)");
return;
}
//TODO: mi van ha már lezárt a productToAuction? - J.
if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None)
{
//TODO: a ProductPrice-t ne változtassuk, mert emiatt nem jó a reset! - J.
productToAuction.AuctionStatus = AuctionStatus.None;
await auctionService.DeactivateProductToAuctionAsync(productToAuction); //TODO: Reset legyen és ne deactivate! - J.
}
else
{
switch (auctionProductStatusRequest.AuctionStatus)
{
case AuctionStatus.Pause:
//TODO: Pause - J.
break;
case AuctionStatus.Sold:
var lastAuctionBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
if (lastAuctionBid == null)
{
productToAuction.AuctionStatus = AuctionStatus.NotSold;
break;
}
productToAuction.AuctionStatus = AuctionStatus.Sold;
productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId;
break;
case AuctionStatus.NotSold:
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auctionProductStatusRequest.AuctionStatus == AuctionStatus.NotSold)");
break;
case AuctionStatus.FirstWarning:
case AuctionStatus.SecondWarning:
case AuctionStatus.Active:
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 = "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() //TODO: IsGuestAsync??? - J.
var customer = await workContext.GetCurrentCustomerAsync();
if (customer == null || bidRequestMessage.CustomerId != customer.Id) //|| !customer.Active)
{
logger.Error($"SignalRMessageHandler.HandleBidRequest(); (customer == null || bidRequestMessage.CustomerId != customer.Id)");
return;
}
var auction = await auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId, false, false);
if (auction == null || auction.Closed)
{
logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}");
return;
}
var activeProductAuction = (await auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault();
if (activeProductAuction is not { IsActiveItem: true } || activeProductAuction.WinnerCustomerId == customer.Id)
{
logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}");
return; //TODO: - J.
}
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 auctionBid = bidRequestMessage.CreateMainEntity();
auctionBid.ProductAuctionMappingId = activeProductAuction.Id;
//TODO: validate the bidprice amount
if (product.Price >= auctionBid.BidPrice || activeProductAuction.CurrentPrice >= auctionBid.BidPrice)
{
logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (product.Price >= bidRequestMessage.BidPrice || activeProductAuction.CurrentPrice >= auctionBid.BidPrice); productPrice: {product.Price}; bidRequestPrice: {auctionBid.BidPrice}; activeProductAuctionPrice: {activeProductAuction.CurrentPrice}");
return;
}
//save bid
await auctionService.InsertBidAsync(auctionBid);
//set new price
product.Price = bidRequestMessage.BidPrice;
await productService.UpdateProductAsync(product);
activeProductAuction.StartingPrice = product.OldPrice;
activeProductAuction.CurrentPrice = product.Price;
activeProductAuction.AuctionStatus = AuctionStatus.Active;
await auctionService.UpdateProductToAuctionMappingAsync(activeProductAuction);
var stepAmount = AuctionService.GetStepAmount(auctionBid.BidPrice);
var nextBidPrice = auctionBid.BidPrice + stepAmount;
var bid = new MessageWrapper
{
MessageType = "bidNotification",
SenderId = senderId,
Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(activeProductAuction.Id, true))
{
ProductName = product.Name,
CurrentPrice = auctionBid.BidPrice,
NextStepAmount = stepAmount,
NextBidPrice = nextBidPrice,
ToasterMessage = "EMPTY", //TODO: - J.
}.ToJson()
};
await hubContext.Clients.All.SendAsync("send", bid.ToJson());
}
catch (Exception ex)
{
logger.Error($"SignalRMessageHandler.HandleBidRequest(); MessageHandling error: {ex}");
}
}
}
}