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

278 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<AuctionHub> _hubContext;
private readonly IWorkContext _workContext;
public SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext<AuctionHub> 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;
}
if (message.SenderId <= 0 || message.SenderId != (await _workContext.GetCurrentCustomerAsync()).Id)
{
_logger.Error($"SignalRMessageHandler.HandleMessage(); message.SenderId <= 0 || message.SenderId != (await _workContext.GetCurrentCustomerAsync()).Id");
return;
}
//TODO: lock-olni! - J.
switch (message.MessageType)
{
case "BidRequestMessage":
await HandleBidRequest(message.SenderId, message.Data.JsonTo<AuctionBidRequest>());
break;
case "OpenItemRequestMessage":
await HandleProductToAuctionStatusChangedRequest(message.SenderId, message.Data.JsonTo<AuctionProductStatusRequest>());
break;
// Add other message types here
default:
await _logger.ErrorAsync("SignalRMessageHandler.HandleMessage(); Unknown message type");
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:
auctionProductStatusRequest.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 = 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}");
}
}
private static decimal GetStepAmount(decimal currentPrice)
{
return currentPrice switch
{
>= 0 and < 100000 => 1000, //Ezt csak hasraütésszerűen adtam meg!!! - J.
//100 000 - 1 000 000
>= 100000 and < 200000 => 10000,
>= 200000 and < 500000 => 20000,
>= 500000 and < 1000000 => 50000,
//1 000 000 - 10 000 000
>= 1000000 and < 2000000 => 100000,
>= 2000000 and < 5000000 => 200000,
>= 5000000 and < 10000000 => 500000,
//10 000 000 - 100 000 000
>= 10000000 and < 20000000 => 1000000,
>= 20000000 and < 50000000 => 2000000,
>= 50000000 and < 100000000 => 5000000,
//100 000 000 - ~
>= 100000000 and < 200000000 => 10000000,
_ => 20000000
};
//100 000 Ft 200 000 Ft között 10 000 Ft-tal
//200 000 Ft 500 000 Ft között 20 000 Ft-tal
//500 000 Ft 1 000 000 Ft között 50 000 Ft-tal
//1 000 000 Ft 2 000 000 Ft között 100 000 Ft-tal
//2 000 000 Ft 5 000 000 Ft között 200 000 Ft-tal
//5 000 000 Ft 10 000 000 Ft között 500 000 Ft-tal
//10 000 000 Ft 20 000 000 Ft között 1 000 000 Ft-tal
//20 000 000 Ft 50 000 000 Ft között 2 000 000 Ft-tal
//50 000 000 Ft 100 000 000 Ft között 5 000 000 Ft-tal
//100 000 000 Ft 200 000 000 Ft között 10 000 000 Ft-tal
//200 000 000 Ft fölött 20 000 000 Ft-tal
}
}
}