590 lines
32 KiB
C#
590 lines
32 KiB
C#
using System.Text.Json.Nodes;
|
|
using AyCode.Core.Extensions;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Nop.Services.Logging;
|
|
using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
|
|
using Nop.Plugin.Misc.AuctionPlugin.Services;
|
|
using AyCode.Utils.Extensions;
|
|
using Newtonsoft.Json;
|
|
using Nop.Services.Customers;
|
|
using Nop.Core;
|
|
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
|
|
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
|
|
using Nop.Core.Domain.Catalog;
|
|
using Nop.Core.Domain.Customers;
|
|
using Nop.Services.Catalog;
|
|
using Newtonsoft.Json.Linq;
|
|
using DocumentFormat.OpenXml.Spreadsheet;
|
|
|
|
namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
|
|
{
|
|
public class AuctionHub(SessionService sessionService, ILogger logger, IProductService productService, AuctionService auctionService, IWorkContext workContext, ICustomerService customerService, ICategoryService categoryService)
|
|
: Hub<IAuctionHubClient>
|
|
{
|
|
private readonly SemaphoreSlim _handleMessageMutex = new(1);
|
|
|
|
public override async Task OnConnectedAsync()
|
|
{
|
|
var connectionId = Context.ConnectionId;
|
|
|
|
//if (sessionService.GetOrCreateSessionItem(connectionId) == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}");
|
|
|
|
//await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with id: {connectionId}");
|
|
|
|
var httpContext = Context.GetHttpContext();
|
|
if (httpContext == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (httpContext == null); connectionId: {connectionId}");
|
|
else
|
|
{
|
|
var sessionItem = sessionService.GetOrCreateSessionItem(httpContext.Session.Id);
|
|
|
|
if (sessionItem == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}; sessionId: {httpContext.Session.Id}");
|
|
else sessionItem.SignaRConnectionId = connectionId;
|
|
|
|
var userName = httpContext.Request.Query["ConnectionId"];
|
|
if (!string.IsNullOrEmpty(userName))
|
|
{
|
|
await logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with name: {userName}; connectionId: {connectionId}");
|
|
}
|
|
}
|
|
|
|
await base.OnConnectedAsync();
|
|
}
|
|
|
|
public override Task OnDisconnectedAsync(Exception exception)
|
|
{
|
|
sessionService.TryRemoveSessionItem(Context.ConnectionId, out _);
|
|
|
|
return base.OnDisconnectedAsync(exception);
|
|
}
|
|
|
|
public async Task ReceiveMessageFromClient(MessageWrapper messageWrapper)
|
|
{
|
|
var sessionItem = IncrementRequestCount();
|
|
|
|
await HandleMessageAsync(messageWrapper, sessionItem, Context.ConnectionId);
|
|
//await SendMessageWrapperAsync(messageWrapper);
|
|
}
|
|
|
|
public async Task<ResponseType> HandleMessageAsync(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId)
|
|
{
|
|
var customer = await workContext.GetCurrentCustomerAsync();
|
|
//var connectionId = sessionItem?.SessionId;
|
|
|
|
//ArgumentNullException.ThrowIfNull(messageWrapper?.Data);
|
|
|
|
if (messageWrapper?.Data == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleMessageAsync(); message?.Data == null; connectionId: {connectionId}", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
if (sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount)
|
|
await logger.WarningAsync($"AuctionHub.HandleMessageAsync(); sessionItem == null || sessionItem.RequestCount != messageWrapper.RequestCount; connectionId: {connectionId}; sessionId: {sessionItem?.SessionId}; sessionRequests: {sessionItem?.RequestCount}; wrapperRequests: {messageWrapper.RequestCount}", null, customer);
|
|
|
|
if (customer == null || messageWrapper.SenderId <= 0 || messageWrapper.SenderId != customer.Id || await customerService.IsGuestAsync(customer))
|
|
{
|
|
logger.Error($"AuctionHub.HandleMessageAsync(); (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || IsGuestAsync() == true); connectionId: {connectionId}", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer);
|
|
|
|
//TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J.
|
|
using (await _handleMessageMutex.UseWaitAsync())
|
|
{
|
|
try
|
|
{
|
|
await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer);
|
|
|
|
if (messageWrapper.MessageType == "BidRequestMessage") return await HandleBidRequestAsync(customer, messageWrapper);
|
|
else
|
|
{
|
|
if (!await customerService.IsAdminAsync(customer))
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
switch (messageWrapper.MessageType)
|
|
{
|
|
case nameof(AuctionProductStatusRequest):
|
|
return await HandleProductToAuctionStatusChangedRequest(customer, messageWrapper);
|
|
|
|
case nameof(RevertAuctionBidRequest):
|
|
return await HandleRevertAuctionBidRequest(customer, messageWrapper);
|
|
|
|
default:
|
|
await logger.ErrorAsync($"AuctionHub.HandleMessageAsync(); Unknown message type; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"AuctionHub.HandleMessageAsync(); switch (message.MessageType); MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; Exception: {ex.Message}", ex, customer);
|
|
}
|
|
finally
|
|
{
|
|
await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Exit lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer);
|
|
}
|
|
}
|
|
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
public async Task<ResponseType> HandleRevertAuctionBidRequest(Customer customer, MessageWrapper messageWrapper)
|
|
{
|
|
var revertAuctionBidRequest = messageWrapper.Data.JsonTo<RevertAuctionBidRequest>();
|
|
if (revertAuctionBidRequest == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); auctionProductStatusRequest == null", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
try
|
|
{
|
|
var productToAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(revertAuctionBidRequest.ProductToAuctionId));
|
|
if (productToAuction == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction == null);", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
await logger.InformationAsync($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction.AuctionStatus}", null, customer);
|
|
|
|
var product = await auctionService.GetProductById(productToAuction.ProductId);
|
|
if (product == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleBidRequestAsync(); (product == null);", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
if (productToAuction.AuctionStatus != AuctionStatus.Pause)
|
|
{
|
|
logger.Warning($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction.AuctionStatus != AuctionStatus.Pause; AuctionStatus: {productToAuction.AuctionStatus}", null, customer);
|
|
|
|
await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id, ResponseType.ToCaller);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
|
|
|
|
if (revertLastBid == null) await ResetProductToAuction(productToAuction);
|
|
else
|
|
{
|
|
productToAuction.BidsCount = await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id);
|
|
await SetAuctionBidPriceAsync(revertLastBid.BidPrice, productToAuction, product, revertLastBid.CustomerId);
|
|
}
|
|
|
|
await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id, ResponseType.ToAllClients);
|
|
return ResponseType.ToAllClients;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); Exception: {ex.Message}", ex, customer);
|
|
}
|
|
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
public async Task<ResponseType> HandleBidRequestAsync(Customer customer, MessageWrapper messageWrapper)
|
|
{
|
|
var bidRequestMessage = messageWrapper.Data.JsonTo<AuctionBidRequest>();
|
|
if (bidRequestMessage == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleBidRequestAsync(); (bidRequestMessage == null)", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
try
|
|
{
|
|
await logger.InformationAsync($"AuctionHub.HandleBidRequestAsync(); Bid received; Auction: {bidRequestMessage.AuctionId}; ProductToAuction: {bidRequestMessage.ProductAuctionMappingId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}", null, customer);
|
|
|
|
var auction = await auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId, false, false);
|
|
if (auction == null || auction.Closed)
|
|
{
|
|
logger.Error($"AuctionHub.HandleBidRequestAsync(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
var product = await auctionService.GetProductById(bidRequestMessage.ProductId);
|
|
if (product == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleBidRequestAsync(); (product == null);", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
//var activeProductAuction = (await auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault();
|
|
var activeProductAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(bidRequestMessage.ProductAuctionMappingId));
|
|
if (activeProductAuction is not { IsActiveItem: true } || (activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)))
|
|
{
|
|
logger.Warning($"AuctionHub.HandleBidRequestAsync(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer);
|
|
|
|
await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
if (!await IsValidProductPricesAndSyncIfNeedAsync(activeProductAuction, product, customer))
|
|
{
|
|
await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToAllClients);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
if (!IsValidBidPrice(activeProductAuction, bidRequestMessage.BidPrice, customer))
|
|
{
|
|
await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
var auctionBid = bidRequestMessage.CreateMainEntity();
|
|
auctionBid.ProductAuctionMappingId = activeProductAuction.Id;
|
|
|
|
await auctionService.InsertBidAsync(auctionBid);
|
|
activeProductAuction.BidsCount++;
|
|
|
|
activeProductAuction.AuctionStatus = AuctionStatus.Active;
|
|
if (!await SetAuctionBidPriceAsync(auctionBid.BidPrice, activeProductAuction, product, customer.Id))
|
|
{
|
|
await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToAllClients);
|
|
|
|
return ResponseType.ToAllClients;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"AuctionHub.HandleBidRequestAsync(); Exception: {ex.Message}", ex, customer);
|
|
}
|
|
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
public async Task<ResponseType> HandleProductToAuctionStatusChangedRequest(Customer customer, MessageWrapper statusChangedMessageWrapper)
|
|
{
|
|
var auctionProductStatusRequest = statusChangedMessageWrapper.Data.JsonTo<AuctionProductStatusRequest>();
|
|
if (auctionProductStatusRequest == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
try
|
|
{
|
|
//var responseType = ResponseType.ToAllClients;
|
|
await logger.InformationAsync($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer);
|
|
|
|
var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId);
|
|
if (productToAuction == null)
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId);
|
|
if (auction == null || auction.Closed)
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus))
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); RequestAuctionStatusIsValid() == false; newStatus: {auctionProductStatusRequest.AuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer);
|
|
|
|
await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToCaller);
|
|
return ResponseType.Error;
|
|
}
|
|
else if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId);
|
|
else
|
|
{
|
|
switch (auctionProductStatusRequest.AuctionStatus)
|
|
{
|
|
case AuctionStatus.Active:
|
|
productToAuction.AuctionStatus = AuctionStatus.Active;
|
|
await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true);
|
|
break;
|
|
|
|
case AuctionStatus.FirstWarning:
|
|
case AuctionStatus.SecondWarning:
|
|
productToAuction.AuctionStatus = auctionProductStatusRequest.AuctionStatus;
|
|
break;
|
|
|
|
case AuctionStatus.Sold:
|
|
var lastAuctionBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
|
|
if (lastAuctionBid == null) productToAuction.AuctionStatus = AuctionStatus.NotSold;
|
|
else
|
|
{
|
|
productToAuction.AuctionStatus = AuctionStatus.Sold;
|
|
productToAuction.CurrentPrice = lastAuctionBid.BidPrice;
|
|
productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId;
|
|
|
|
var placeOrderResult = await auctionService.CreateOrderForWinnerAsync(productToAuction);
|
|
if (placeOrderResult == null || placeOrderResult.Id == 0)
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (placeOrderResult == null || placeOrderResult.Id == 0)", null, customer);
|
|
//return; //TODO: EGYELŐRE HAGYJUK LEZÁRNI AKKOR IS, HA NEM SIKERÜLT AZ ORDERPLACE()! - J.
|
|
}
|
|
}
|
|
|
|
await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, false);
|
|
break;
|
|
|
|
case AuctionStatus.Pause:
|
|
productToAuction.AuctionStatus = AuctionStatus.Pause;
|
|
break;
|
|
|
|
default:
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer);
|
|
|
|
await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToCaller);
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
await auctionService.UpdateProductToAuctionMappingAsync(productToAuction);
|
|
}
|
|
|
|
await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToAllClients);
|
|
|
|
//TODO: gond van ha az Admin valamit módosít és újrazár egy régi ProductToAuction-t!!!! AuctionRequestMode.Normal...- J.
|
|
if (/*AuctionRequestMode.Normal &&*/ auction.AuctionType == AuctionType.AutomaticNext && productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold)
|
|
await StepNextProductToAuctionAsync(statusChangedMessageWrapper, customer, productToAuction, auctionProductStatusRequest);
|
|
|
|
return ResponseType.ToAllClients;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); Exception: {ex.Message}", ex, customer);
|
|
}
|
|
|
|
return ResponseType.Error;
|
|
}
|
|
|
|
private async Task SendStatusChangedNotificationAsync(Customer customer, MessageWrapper statusChangedMessageWrapper, ProductToAuctionMapping productToAuction, ResponseType responseType)
|
|
{
|
|
await UpdateStatusChangedNotificationMessageWrapperAsync(statusChangedMessageWrapper, customer, productToAuction, responseType);
|
|
await SendMessageWrapperAsync(statusChangedMessageWrapper);
|
|
}
|
|
|
|
private async Task StepNextProductToAuctionAsync(MessageWrapper statusChangedMessageWrapper, Customer customer, ProductToAuctionMapping productToAuction, AuctionProductStatusRequest auctionProductStatusRequest)
|
|
{
|
|
var nextProductToAuction = await auctionService.GetNextProductToAuctionByAuctionIdAsync(productToAuction.AuctionId);
|
|
if (nextProductToAuction == null) return;
|
|
|
|
await logger.InformationAsync($"AuctionHub.StepNextProductToAuctionAsync(); NextProductToAuctionId: {nextProductToAuction.Id};", null, customer);
|
|
|
|
if (nextProductToAuction.AuctionStatus != AuctionStatus.None)
|
|
{
|
|
await logger.WarningAsync($"AuctionHub.StepNextProductToAuctionAsync(); (nextProductToAuction.AuctionStatus != AuctionStatus.None); NextProductToAuctionId: {nextProductToAuction.Id}; Status: {nextProductToAuction.AuctionStatus}({(int)nextProductToAuction.AuctionStatus})", null, customer);
|
|
return; //TODO: Ilyenkor mi legyen?! - J.
|
|
}
|
|
|
|
auctionProductStatusRequest.AuctionStatus = AuctionStatus.Active;
|
|
auctionProductStatusRequest.ProductToAuctionId = nextProductToAuction.Id;
|
|
statusChangedMessageWrapper.Data = auctionProductStatusRequest.ToJson();
|
|
|
|
await HandleProductToAuctionStatusChangedRequest(customer, statusChangedMessageWrapper);
|
|
}
|
|
|
|
private async Task<bool> SetAuctionBidPriceAsync(decimal bidPrice, ProductToAuctionMapping productToAuction, Product product, int lastBidCustomerId)
|
|
{
|
|
try
|
|
{
|
|
product.Price = bidPrice;
|
|
await productService.UpdateProductAsync(product);
|
|
|
|
//activeProductAuction.StartingPrice = product.OldPrice; //TODO: ez biztosan kezelve van mikor összerendeljük? - J.
|
|
productToAuction.CurrentPrice = bidPrice;
|
|
productToAuction.WinnerCustomerId = lastBidCustomerId;
|
|
await auctionService.UpdateProductToAuctionMappingAsync(productToAuction);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"AuctionHub.SetAuctionBidPriceAsync();", ex);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private async Task<bool> IsValidProductPricesAndSyncIfNeedAsync(ProductToAuctionMapping productToAuction, Product product, Customer customer = null)
|
|
{
|
|
if (product.Price == productToAuction.CurrentPrice) return true;
|
|
|
|
if (productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold)
|
|
{
|
|
await logger.ErrorAsync($"AuctionHub.SyncProductPricesIfNeedAsync(); (product.Price != productToAuction.CurrentPrice && (productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold)); productPrice: {product.Price}; productToAuctionCurrentPrice: {productToAuction.CurrentPrice}; auctionStatus: {productToAuction.AuctionStatus}", null, customer);
|
|
return false;
|
|
}
|
|
|
|
await logger.ErrorAsync($"AuctionHub.SyncProductPricesIfNeedAsync(); (product.Price != productToAuction.CurrentPrice); productPrice: {product.Price}; productToAuctionCurrentPrice: {productToAuction.CurrentPrice}", null, customer);
|
|
|
|
var lastBidPrice = product.OldPrice;
|
|
var lastBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
|
|
|
|
if (lastBid == null)
|
|
{
|
|
productToAuction.StartingPrice = lastBidPrice;
|
|
productToAuction.BidsCount = 0;
|
|
}
|
|
else lastBidPrice = lastBid.BidPrice;
|
|
|
|
await SetAuctionBidPriceAsync(lastBidPrice, productToAuction, product, lastBid?.CustomerId ?? 0);
|
|
|
|
await logger.InformationAsync($"AuctionHub.SyncProductPricesIfNeedAsync(); Synchronize the price was successful! lastBidPrice: {lastBidPrice};", null, customer);
|
|
return false;
|
|
}
|
|
|
|
private bool IsValidBidPrice(ProductToAuctionMapping productToAuction, decimal bidRequestPrice, Customer customer = null)
|
|
{
|
|
var hasAuctionBidInDb = productToAuction.BidsCount > 0;
|
|
var nextBidPrice = AuctionService.GetNextBidPrice(productToAuction.CurrentPrice, hasAuctionBidInDb);
|
|
|
|
if (bidRequestPrice != nextBidPrice)
|
|
{
|
|
logger.Warning($"AuctionHub.IsValidBidPrice(); (bidRequestPrice != nextBidPrice); productToAuctionCurrentPrice: {productToAuction.CurrentPrice}; bidRequestPrice: {bidRequestPrice}; hasAuctionBidInDb: {hasAuctionBidInDb}", null, customer);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task UpdateStatusChangedNotificationMessageWrapperAsync(MessageWrapper statusChangedMessageWrapper, Customer customer, ProductToAuctionMapping productToAuction, ResponseType responseType)
|
|
{
|
|
var bidsCount = productToAuction.BidsCount;
|
|
|
|
statusChangedMessageWrapper.MessageType = nameof(ProductToAuctionStatusNotification);
|
|
statusChangedMessageWrapper.SenderId = customer.Id;
|
|
statusChangedMessageWrapper.ResponseType = responseType;
|
|
statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY").ToJson();
|
|
}
|
|
|
|
public async Task UpdateBidNotificationMessageWrapperAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType)
|
|
{
|
|
var bidsCount = productToAuction.BidsCount; //await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id);
|
|
|
|
var stepAmount = AuctionService.GetStepAmount(productToAuction.CurrentPrice);
|
|
var nextBidPrice = AuctionService.GetNextBidPrice(productToAuction.CurrentPrice, stepAmount, bidsCount > 0);
|
|
|
|
messageWrapper.SenderId = customerId;
|
|
messageWrapper.ResponseType = responseType;
|
|
messageWrapper.MessageType = "bidNotification";
|
|
messageWrapper.Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true), bidsCount, "EMPTY") //TODO: NE KÉRJÜK LE DB-BŐL!!! - J.
|
|
{
|
|
ProductName = product.Name,
|
|
CurrentPrice = productToAuction.CurrentPrice,
|
|
NextStepAmount = stepAmount,
|
|
NextBidPrice = nextBidPrice,
|
|
}.ToJson();
|
|
}
|
|
|
|
private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null)
|
|
{
|
|
productToAuction.AuctionStatus = AuctionStatus.None;
|
|
await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice);
|
|
|
|
categoryId ??= (await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId;
|
|
await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false);
|
|
}
|
|
|
|
private async Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured)
|
|
{
|
|
//Leszarjuk ha elszáll, az aukció menjen tovább... - J.
|
|
try
|
|
{
|
|
if (categoryId.GetValueOrDefault(0) == 0) return;
|
|
|
|
var productCategory = (await categoryService.GetProductCategoriesByProductIdAsync(productId)).FirstOrDefault(x => x.CategoryId == categoryId);
|
|
if (productCategory == null) return;
|
|
|
|
if (productCategory.IsFeaturedProduct == isFeatured) return;
|
|
|
|
productCategory.IsFeaturedProduct = isFeatured;
|
|
await categoryService.UpdateProductCategoryAsync(productCategory);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"AuctionHub.UpdateProductCategoryIsFeaturedAsync(); categoryId: {categoryId}; productId: {productId}; isFeatured: {isFeatured}", ex);
|
|
}
|
|
}
|
|
|
|
public async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType)
|
|
{
|
|
await UpdateBidNotificationMessageWrapperAsync(messageWrapper, productToAuction, product, customerId, responseType);
|
|
await SendMessageWrapperAsync(messageWrapper);
|
|
}
|
|
|
|
public async Task SendMessageWrapperAsync(MessageWrapper messageWrapper)
|
|
{
|
|
await logger.InformationAsync($"AuctionHub.SendMessageWrapperAsync(); MessageType: {messageWrapper.MessageType}; ResponseType: {messageWrapper.ResponseType}; jsonData: {messageWrapper.Data}");
|
|
|
|
switch (messageWrapper.ResponseType)
|
|
{
|
|
case ResponseType.ToCaller:
|
|
messageWrapper.HideToaster = true;
|
|
await Clients.Caller.send(messageWrapper.ToJson());
|
|
|
|
break;
|
|
case ResponseType.ToAllClients:
|
|
var messageWrapperJson = messageWrapper.ToJson();
|
|
|
|
if (messageWrapper.HideToaster) await Clients.All.send(messageWrapperJson);
|
|
else
|
|
{
|
|
await Clients.Others.send(messageWrapperJson);
|
|
|
|
var messageWrapperJObject = JObject.Parse(messageWrapperJson);
|
|
messageWrapperJObject["hideToaster" /*nameof(MessageWrapper.HideToaster)*/] = "true";
|
|
|
|
await Clients.Caller.send(messageWrapperJObject.ToString(Formatting.None));
|
|
}
|
|
|
|
break;
|
|
case ResponseType.Error:
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
|
|
//private async Task SendMessageToClientsAsync(MessageWrapper messageWrapper, bool sendToCaller = false)
|
|
//{
|
|
// if (sendToCaller) await Clients.Caller.send(messageWrapper.ToJson());
|
|
// else await Clients.All.send(messageWrapper.ToJson());
|
|
//}
|
|
|
|
private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus)
|
|
{
|
|
switch (oldStatus)
|
|
{
|
|
case AuctionStatus.None:
|
|
return newStatus is AuctionStatus.Active or AuctionStatus.Pause;
|
|
case AuctionStatus.Active:
|
|
return newStatus is AuctionStatus.FirstWarning or AuctionStatus.Pause;
|
|
case AuctionStatus.FirstWarning:
|
|
return newStatus is AuctionStatus.SecondWarning or AuctionStatus.Pause;
|
|
case AuctionStatus.SecondWarning:
|
|
return newStatus is AuctionStatus.Sold or AuctionStatus.Pause;
|
|
case AuctionStatus.Pause:
|
|
return newStatus is AuctionStatus.None or AuctionStatus.Active;
|
|
case AuctionStatus.Sold:
|
|
case AuctionStatus.NotSold:
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private SessionItem IncrementRequestCount()
|
|
{
|
|
SessionItem sessionItem = null;
|
|
|
|
var httpContext = Context.GetHttpContext();
|
|
if (httpContext != null && sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem)) sessionItem.RequestCount++;
|
|
|
|
return sessionItem;
|
|
}
|
|
}
|
|
}
|