278 lines
12 KiB
C#
278 lines
12 KiB
C#
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
|
||
}
|
||
}
|
||
}
|