improvements, fixes, etc...

This commit is contained in:
Loretta 2024-11-25 17:44:36 +01:00
parent f1e022523e
commit 5c1c721d2e
9 changed files with 287 additions and 124 deletions

View File

@ -15,13 +15,35 @@ public class AuctionBidDbTable : MgDbTableBase<AuctionBid>
{ {
} }
public Task<AuctionBid> GetLastAuctionBidByProductToAuctionIdAsync(int prouctToAuctionId) public IQueryable<AuctionBid> GetLastAuctionBidByProductToAuctionId(int productToAuctionId)
=> GetByProductToAuctionId(productToAuctionId).OrderByDescending(x => x.Id);
public IQueryable<AuctionBid> GetByProductToAuctionId(int productToAuctionId)
=> Table.Where(x => x.ProductAuctionMappingId == productToAuctionId);
public Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId)
{ {
return Table.Where(x => x.ProductAuctionMappingId == prouctToAuctionId).OrderByDescending(x => x.Id).FirstOrDefaultAsync(); return Table.AnyAsync(x => x.ProductAuctionMappingId == productToAuctionId);
} }
public IQueryable<AuctionBid> GetByProductToAuctionIdAsync(int prouctToAuctionId) public async Task<AuctionBid> RevertByProductToAuctionIdAsync(int productToAuctionId)
{ {
return Table.Where(x => x.ProductAuctionMappingId == prouctToAuctionId); var lastBid = await GetLastAuctionBidByProductToAuctionId(productToAuctionId).FirstOrDefaultAsync();
if (lastBid == null)
{
await Logger.InformationAsync($"AuctionBidDbTable.RevertByProductToAuctionIdAsync(); (lastBid == null); productToAuction.Id: {productToAuctionId}");
return null;
}
await DeleteAsync(lastBid);
return await GetLastAuctionBidByProductToAuctionId(productToAuctionId).FirstOrDefaultAsync();
}
public async Task<int> DeleteAllByProductToAuctionIdAsync(int productToAuctionId)
{
var deletedBids = await DeleteAsync(x => x.ProductAuctionMappingId == productToAuctionId);
await Logger.InformationAsync($"AuctionBidDbTable.DeleteAllByProductToAuctionIdAsync(); productToAuction.Id: {productToAuctionId}; deletedBids: {deletedBids}");
return deletedBids;
} }
} }

View File

@ -1,14 +1,19 @@
using Mango.Nop.Core.Repositories; using Mango.Nop.Core.Repositories;
using Nop.Core; using Nop.Core;
using Nop.Core.Caching;
using Nop.Data; using Nop.Data;
using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer.Interfaces; using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer.Interfaces;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Services.Catalog;
using System; using System;
using Nop.Services.Logging;
namespace Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; namespace Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer;
public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>, IProductToAuctionDbSet<ProductToAuctionDbTable>, IAuctionBidDbSet<AuctionBidDbTable> public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>, IProductToAuctionDbSet<ProductToAuctionDbTable>, IAuctionBidDbSet<AuctionBidDbTable>
{ {
private readonly IProductService _productService;
public AuctionDbTable Auctions { get; set; } public AuctionDbTable Auctions { get; set; }
public ProductToAuctionDbTable ProductToAuctions { get; set; } public ProductToAuctionDbTable ProductToAuctions { get; set; }
public AuctionBidDbTable AuctionBids { get; set; } public AuctionBidDbTable AuctionBids { get; set; }
@ -18,8 +23,10 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>,
//public IRepository<AuctionBid> AuctionBids2 { get; set; } //public IRepository<AuctionBid> AuctionBids2 { get; set; }
public AuctionDbContext(INopDataProvider dataProvider, AuctionDbTable auctionDbTable, ProductToAuctionDbTable productToAuctionDbTable, AuctionBidDbTable auctionBidDbTable) : base(dataProvider) public AuctionDbContext(INopDataProvider dataProvider, AuctionDbTable auctionDbTable, ProductToAuctionDbTable productToAuctionDbTable, AuctionBidDbTable auctionBidDbTable, IProductService productService, ILogger logger) : base(dataProvider, logger)
{ {
_productService = productService;
Auctions = auctionDbTable; Auctions = auctionDbTable;
ProductToAuctions = productToAuctionDbTable; ProductToAuctions = productToAuctionDbTable;
AuctionBids = auctionBidDbTable; AuctionBids = auctionBidDbTable;
@ -44,4 +51,42 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>,
return [..await ProductToAuctions.GetByAuctionAndProductId(auctionId, productId, activeProductOnly).ToListAsync()]; return [..await ProductToAuctions.GetByAuctionAndProductId(auctionId, productId, activeProductOnly).ToListAsync()];
} }
public Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId)
=> AuctionBids.HasBidByProductToAuctionIdAsync(productToAuctionId);
public Task<AuctionBid> GetLastAuctionBidByProductToAuctionId(int productToAuctionId)
=> AuctionBids.GetLastAuctionBidByProductToAuctionId(productToAuctionId).FirstOrDefaultAsync();
public Task<AuctionBid> RevertAuctionBidByProductToAuctionId(int productToAuctionId)
=> AuctionBids.RevertByProductToAuctionIdAsync(productToAuctionId);
public async Task ResetProductToAuctionByProductId(int productId)
=> await ResetProductToAuctionAsync(await ProductToAuctions.GetByProductId(productId).FirstOrDefaultAsync());
public async Task ResetProductToAuctionByIdAsync(int productToAuctionId, decimal basePrice = 0)
=> await ResetProductToAuctionAsync(ProductToAuctions.GetById(productToAuctionId), basePrice);
public async Task ResetProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0)
{
if (productToAuction == null)
{
Logger.Error($"AuctionDbContext.ResetProductToAuctionAsync(); productToAuction == null");
return;
}
await Logger.InformationAsync($"AuctionDbContext.ResetProductToAuctionAsync(); productToAuction.Id: {productToAuction.Id}; basePrice: {basePrice}");
var product = await _productService.GetProductByIdAsync(productToAuction.ProductId);
if (product == null)
{
Logger.Error($"AuctionDbContext.ResetProductToAuctionAsync(); product == null");
return;
}
if (basePrice <= 0) basePrice = product.Price;
else product.Price = basePrice;
await ProductToAuctions.ResetAsync(productToAuction, basePrice);
await AuctionBids.DeleteAllByProductToAuctionIdAsync(productToAuction.Id);
}
} }

View File

@ -44,16 +44,18 @@ public class ProductToAuctionDbTable : MgDbTableBase<ProductToAuctionMapping>
(!activeProductOnly || x.AuctionStatus == AuctionStatus.Active || x.AuctionStatus == AuctionStatus.FirstWarning || x.AuctionStatus == AuctionStatus.SecondWarning /*HasActiveAuctionStatus(x.AuctionStatus)*/)); (!activeProductOnly || x.AuctionStatus == AuctionStatus.Active || x.AuctionStatus == AuctionStatus.FirstWarning || x.AuctionStatus == AuctionStatus.SecondWarning /*HasActiveAuctionStatus(x.AuctionStatus)*/));
} }
public async Task DeactivateItemByProductId(int productId, decimal basePrice) => await DeactivateItem(await GetByProductId(productId).FirstOrDefaultAsync(), basePrice); public async Task ResetByProductIdAsync(int productId, decimal basePrice) => await ResetAsync(await GetByProductId(productId).FirstOrDefaultAsync(), basePrice);
public async Task DeactivateItemById(int productToAuctionId, decimal basePrice) => await DeactivateItem(await GetByIdAsync(productToAuctionId), basePrice); public async Task ResetByIdAsync(int productToAuctionId, decimal basePrice) => await ResetAsync(await GetByIdAsync(productToAuctionId), basePrice);
public async Task DeactivateItem(ProductToAuctionMapping productToAuction, decimal basePrice) public async Task ResetAsync(ProductToAuctionMapping productToAuction, decimal basePrice)
{ {
if (productToAuction == null) if (productToAuction == null)
{ {
Logger.Error($"ProductToAuctionDbTable.DeactivateItem(); productToAuction == null"); Logger.Error($"ProductToAuctionDbTable.ResetAsync(); productToAuction == null");
return; return;
} }
await Logger.InformationAsync($"ProductToAuctionDbTable.ResetAsync(); productToAuction.Id: {productToAuction.Id}; basePrice: {basePrice}");
//TODO: ezt kivegyem egyelőre? amíg a Product.Price-t használjuk, addig nem sok értelme //TODO: ezt kivegyem egyelőre? amíg a Product.Price-t használjuk, addig nem sok értelme
productToAuction.StartingPrice = basePrice; productToAuction.StartingPrice = basePrice;
productToAuction.CurrentPrice = basePrice; productToAuction.CurrentPrice = basePrice;

View File

@ -1,23 +1,31 @@
using Mango.Nop.Services; using DocumentFormat.OpenXml.Office2010.Drawing;
using Mango.Nop.Services;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Catalog;
using Nop.Core.Events; using Nop.Core.Events;
using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using Nop.Services.Logging;
namespace Nop.Plugin.Misc.AuctionPlugin.Domains.EventConsumers; namespace Nop.Plugin.Misc.AuctionPlugin.Domains.EventConsumers;
public class AuctionEventConsumer(IHttpContextAccessor httpContextAccessor, AuctionDbContext ctx) : MgEventConsumer(httpContextAccessor) public class AuctionEventConsumer(IHttpContextAccessor httpContextAccessor, ILogger logger, AuctionDbContext ctx) : MgEventConsumer(httpContextAccessor, logger)
{ {
public override async Task HandleEventAsync(EntityUpdatedEvent<Product> eventMessage) public override async Task HandleEventAsync(EntityUpdatedEvent<Product> eventMessage)
{ {
//TODO: itt lehetne ciklussal az összes ProductToAuction-re! - J. await Logger.InformationAsync($"AuctionEventConsumer.HandleEventAsync<Product>();");
var productToAuction = await ctx.ProductToAuctions.GetByProductId(eventMessage.Entity.Id).FirstOrDefaultAsync();
//foreach var productToAuctions = await ctx.ProductToAuctions.GetByProductId(eventMessage.Entity.Id).Where(x => x.AuctionStatus == AuctionStatus.None).ToListAsync();
if (productToAuction is { AuctionStatus: AuctionStatus.None })
foreach (var productToAuction in productToAuctions)
{ {
await ctx.ProductToAuctions.DeactivateItem(productToAuction, eventMessage.Entity.Price); if (await ctx.HasBidByProductToAuctionIdAsync(productToAuction.Id))
{
await Logger.InformationAsync($"AuctionEventConsumer.HandleEventAsync<Product>(); HasAuctionBids->continue");
continue;
}
await ctx.ProductToAuctions.ResetAsync(productToAuction, eventMessage.Entity.Price);
} }
await base.HandleEventAsync(eventMessage); await base.HandleEventAsync(eventMessage);

View File

@ -1,11 +1,6 @@
using System; using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos;
namespace Nop.Plugin.Misc.AuctionPlugin.Models namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages
{ {
public class AuctionBidRequest : AuctionBidDto public class AuctionBidRequest : AuctionBidDto
{ {

View File

@ -0,0 +1,6 @@
namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
public class RevertAuctionBidRequest
{
public int ProductToAuctionId { get; set; }
}

View File

@ -7,7 +7,12 @@ using Nop.Services.Catalog;
using Nop.Services.Logging; using Nop.Services.Logging;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Nop.Core; using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using Nop.Core.Domain.Customers;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Services.Customers;
using DocumentFormat.OpenXml.Wordprocessing;
namespace Nop.Plugin.Misc.AuctionPlugin.Hubs namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
{ {
@ -23,23 +28,25 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
//- ha bid-elt 1x is, kerüljön a watch-ba //- ha bid-elt 1x is, kerüljön a watch-ba
//- DbTransaction-t vhogy megcsinánli! //- DbTransaction-t vhogy megcsinánli!
public class SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext<AuctionHub> hubContext, IWorkContext workContext) public class SignalRMessageHandler(ILogger logger, IProductService productService, AuctionService auctionService, IHubContext<AuctionHub> hubContext, IWorkContext workContext, ICustomerService customerService)
{ {
private readonly Mutex _handleMessageMutex = new(); private readonly Mutex _handleMessageMutex = new();
public async Task HandleMessage(MessageWrapper message) public async Task HandleMessage(MessageWrapper message)
{ {
var customer = await workContext.GetCurrentCustomerAsync();
if (message?.Data == null) if (message?.Data == null)
{ {
logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null"); logger.Error($"SignalRMessageHandler.HandleMessage(); message?.Data == null", null, customer);
return; return;
} }
await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); jsonData: {message.Data}"); await logger.InformationAsync($"SignalRMessageHandler.HandleMessage(); jsonData: {message.Data}", null, customer);
if (message.SenderId <= 0 || message.SenderId != (await workContext.GetCurrentCustomerAsync()).Id) if (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || await customerService.IsGuestAsync(customer))
{ {
logger.Error($"SignalRMessageHandler.HandleMessage(); message.SenderId <= 0 || message.SenderId != (await _workContext.GetCurrentCustomerAsync()).Id; SenderId: {message.SenderId}"); logger.Error($"SignalRMessageHandler.HandleMessage(); (customer == null || message.SenderId <= 0 || message.SenderId != customer.Id || IsGuestAsync() == true)", null, customer);
return; return;
} }
@ -47,74 +54,118 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
{ {
try try
{ {
if (message.MessageType == "BidRequestMessage") await HandleBidRequest(customer, message.Data.JsonTo<AuctionBidRequest>());
else
{
if (!await customerService.IsAdminAsync(customer))
{
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false!", null, customer);
return;
}
switch (message.MessageType) switch (message.MessageType)
{ {
case "BidRequestMessage": case nameof(AuctionProductStatusRequest):
await HandleBidRequest(message.SenderId, message.Data.JsonTo<AuctionBidRequest>()); await HandleProductToAuctionStatusChangedRequest(customer, message.Data.JsonTo<AuctionProductStatusRequest>());
break; break;
case "AuctionProductStatusRequest": case nameof(RevertAuctionBidRequest):
await HandleProductToAuctionStatusChangedRequest(message.SenderId, message.Data.JsonTo<AuctionProductStatusRequest>()); await HandleRevertAuctionBidRequest(customer, message.Data.JsonTo<RevertAuctionBidRequest>());
break; break;
// Add other message types here
default: default:
await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {message.MessageType}"); // Add other message types here
await logger.ErrorAsync($"SignalRMessageHandler.HandleMessage(); Unknown message type; MessageType: {message.MessageType}", null, customer);
break; break;
} }
} }
}
catch (Exception ex) catch (Exception ex)
{ {
logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {message.MessageType}; ex: {ex}"); logger.Error($"SignalRMessageHandler.HandleMessage(); switch (message.MessageType); MessageType: {message.MessageType}; Exception: {ex.Message}", ex, customer);
} }
} }
} }
private async Task HandleProductToAuctionStatusChangedRequest(int senderId, AuctionProductStatusRequest auctionProductStatusRequest) private async Task HandleRevertAuctionBidRequest(Customer customer, RevertAuctionBidRequest revertAuctionBidRequest)
{ {
if (auctionProductStatusRequest == null) if (revertAuctionBidRequest == null)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null"); logger.Error($"SignalRMessageHandler.HanldeRevertAuctionBidRequest(); auctionProductStatusRequest == null", null, customer);
return; return;
} }
try try
{ {
await logger.InformationAsync($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})"); var productToAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(revertAuctionBidRequest.ProductToAuctionId));
if (productToAuction is not { AuctionStatus: AuctionStatus.Pause })
{
logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction?.AuctionStatus}", null, customer);
return; //TODO: - J.
}
//TODO: if IsAdmin.. - J. var product = await auctionService.GetProductById(productToAuction.ProductId);
//productBidBoxViewModel.IsAdmin = await _customerService.IsAdminAsync(customer); if (product == null) return;
//productBidBoxViewModel.IsGuest = await _customerService.IsGuestAsync(customer);
//TODO: if nincs aktív item.. - J. var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
if (revertLastBid == null)
{
//TODO: NA ILYENKOR VAN A CUMI... - J.
return;
}
await SetAuctionBidPrice(revertLastBid.BidPrice, productToAuction, product);
await SendAuctionBidMessageAsync(revertLastBid, productToAuction, product, customer.Id);
}
catch (Exception ex)
{
logger.Error($"SignalRMessageHandler.HanldeRevertAuctionBidRequest(); Exception: {ex.Message}", ex, customer);
}
}
private async Task HandleProductToAuctionStatusChangedRequest(Customer customer, AuctionProductStatusRequest auctionProductStatusRequest)
{
if (auctionProductStatusRequest == null)
{
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer);
return;
}
try
{
await logger.InformationAsync($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer);
var auction = await auctionService.GetAuctionDtoByProductToAuctionIdAsync(auctionProductStatusRequest.ProductToAuctionId, false); var auction = await auctionService.GetAuctionDtoByProductToAuctionIdAsync(auctionProductStatusRequest.ProductToAuctionId, false);
if (auction == null || auction.Closed) if (auction == null || auction.Closed)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}"); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer);
return; return;
} }
var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId); var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId);
if (productToAuction == null) if (productToAuction == null)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)"); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer);
return;
}
if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus))
{
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); RequestAuctionStatusIsValid() == false; newStatus: {auctionProductStatusRequest.AuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer);
return; return;
} }
//TODO: mi van ha már lezárt a productToAuction? - J.
if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None)
{ {
//TODO: a ProductPrice-t ne változtassuk, mert emiatt nem jó a reset! - J.
productToAuction.AuctionStatus = AuctionStatus.None; productToAuction.AuctionStatus = AuctionStatus.None;
await auctionService.DeactivateProductToAuctionAsync(productToAuction); //TODO: Reset legyen és ne deactivate! - J. await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice);
} }
else else
{ {
switch (auctionProductStatusRequest.AuctionStatus) switch (auctionProductStatusRequest.AuctionStatus)
{ {
case AuctionStatus.Pause: case AuctionStatus.Pause:
//TODO: Pause - J. productToAuction.AuctionStatus = AuctionStatus.Pause;
break; break;
case AuctionStatus.Sold: case AuctionStatus.Sold:
@ -126,11 +177,12 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
} }
productToAuction.AuctionStatus = AuctionStatus.Sold; productToAuction.AuctionStatus = AuctionStatus.Sold;
productToAuction.CurrentPrice = lastAuctionBid.BidPrice;
productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId; productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId;
break; break;
case AuctionStatus.NotSold: case AuctionStatus.NotSold:
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auctionProductStatusRequest.AuctionStatus == AuctionStatus.NotSold)"); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (auctionProductStatusRequest.AuctionStatus == AuctionStatus.NotSold)", null, customer);
break; break;
case AuctionStatus.FirstWarning: case AuctionStatus.FirstWarning:
@ -147,7 +199,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
var productToauctionChangedNotification = new MessageWrapper var productToauctionChangedNotification = new MessageWrapper
{ {
MessageType = nameof(ProductToAuctionStatusNotification), MessageType = nameof(ProductToAuctionStatusNotification),
SenderId = senderId, SenderId = customer.Id,
Data = new ProductToAuctionStatusNotification(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true)) Data = new ProductToAuctionStatusNotification(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true))
{ {
ToasterMessage = "EMPTY", //TODO: - J. ToasterMessage = "EMPTY", //TODO: - J.
@ -158,52 +210,38 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); Error {ex.Message}"); logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); Exception: {ex.Message}", ex, customer);
}
} }
} private async Task HandleBidRequest(Customer customer, AuctionBidRequest bidRequestMessage)
private async Task HandleBidRequest(int senderId, AuctionBidRequest bidRequestMessage)
{ {
if (bidRequestMessage == null) if (bidRequestMessage == null)
{ {
logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)"); logger.Error($"SignalRMessageHandler.HandleBidRequest(); (bidRequestMessage == null)", null, customer);
return; return;
} }
try try
{ {
await logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received; Auction: {bidRequestMessage.AuctionId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}"); await logger.InformationAsync($"SignalRMessageHandler.HandleBidRequest(); Bid received; Auction: {bidRequestMessage.AuctionId}; ProductToAuction: {bidRequestMessage.ProductAuctionMappingId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}", null, customer);
//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); var auction = await auctionService.GetAuctionDtoByIdAsync(bidRequestMessage.AuctionId, false, false);
if (auction == null || auction.Closed) if (auction == null || auction.Closed)
{ {
logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}"); logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer);
return; return;
} }
var activeProductAuction = (await auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault(); var activeProductAuction = (await auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(bidRequestMessage.AuctionId, bidRequestMessage.ProductId, true)).FirstOrDefault();
if (activeProductAuction is not { IsActiveItem: true } || activeProductAuction.WinnerCustomerId == customer.Id) 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}"); logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer);
return; //TODO: - J. return; //TODO: - J.
} }
var product = await productService.GetProductByIdAsync(bidRequestMessage.ProductId); var product = await auctionService.GetProductById(bidRequestMessage.ProductId);
if (product == null) if (product == null) return;
{
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(); var auctionBid = bidRequestMessage.CreateMainEntity();
auctionBid.ProductAuctionMappingId = activeProductAuction.Id; auctionBid.ProductAuctionMappingId = activeProductAuction.Id;
@ -211,33 +249,36 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
//TODO: validate the bidprice amount //TODO: validate the bidprice amount
if (product.Price >= auctionBid.BidPrice || activeProductAuction.CurrentPrice >= auctionBid.BidPrice) 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}"); logger.Warning($"SignalRMessageHandler.HandleBidRequest(); (product.Price >= bidRequestMessage.BidPrice || activeProductAuction.CurrentPrice >= auctionBid.BidPrice); productPrice: {product.Price}; bidRequestPrice: {auctionBid.BidPrice}; activeProductAuctionPrice: {activeProductAuction.CurrentPrice}", null, customer);
return; return;
} }
//save bid //save bid
await auctionService.InsertBidAsync(auctionBid); 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; activeProductAuction.AuctionStatus = AuctionStatus.Active;
if (!await SetAuctionBidPrice(bidRequestMessage.BidPrice, activeProductAuction, product)) return;
await auctionService.UpdateProductToAuctionMappingAsync(activeProductAuction); await SendAuctionBidMessageAsync(auctionBid, activeProductAuction, product, customer.Id);
}
catch (Exception ex)
{
logger.Error($"SignalRMessageHandler.HandleBidRequest(); Exception: {ex.Message}", ex, customer);
}
}
private async Task SendAuctionBidMessageAsync(AuctionBid auctionBid, ProductToAuctionMapping productToAuction, Product product, int customerId)
{
var stepAmount = AuctionService.GetStepAmount(auctionBid.BidPrice); var stepAmount = AuctionService.GetStepAmount(auctionBid.BidPrice);
var nextBidPrice = auctionBid.BidPrice + stepAmount; var nextBidPrice = auctionBid.BidPrice + stepAmount;
var bid = new MessageWrapper var bidMessage = new MessageWrapper
{ {
MessageType = "bidNotification", MessageType = "bidNotification",
SenderId = senderId, SenderId = customerId,
Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(activeProductAuction.Id, true)) Data = new BidNotificationMessage(await auctionService.GetAuctionDtoByProductToAuctionIdAsync(productToAuction.Id, true)) //TODO: NE KÉRJÜK LE DB-BŐL!!! - j.
{ {
ProductName = auctionBid.ProductId.ToString(), ProductName = product.Name,
CurrentPrice = auctionBid.BidPrice, CurrentPrice = auctionBid.BidPrice,
NextStepAmount = stepAmount, NextStepAmount = stepAmount,
NextBidPrice = nextBidPrice, NextBidPrice = nextBidPrice,
@ -245,11 +286,48 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
}.ToJson() }.ToJson()
}; };
await hubContext.Clients.All.SendAsync("send", bid.ToJson()); await hubContext.Clients.All.SendAsync("send", bidMessage.ToJson());
}
private async Task<bool> SetAuctionBidPrice(decimal bidPrice, ProductToAuctionMapping productToAuction, Product product)
{
try
{
product.Price = bidPrice;
await productService.UpdateProductAsync(product);
//activeProductAuction.StartingPrice = product.OldPrice; //TODO: ez biztosan kezelve van mikor összerendeljük? - J.
productToAuction.CurrentPrice = product.Price;
await auctionService.UpdateProductToAuctionMappingAsync(productToAuction);
return true;
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.Error($"SignalRMessageHandler.HandleBidRequest(); MessageHandling error: {ex}"); logger.Error($"SignalRMessageHandler.HandleBidRequest(); SetAuctionBidPrice() == false", ex);
}
return false;
}
private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus)
{
switch (oldStatus)
{
case AuctionStatus.None:
return newStatus == AuctionStatus.Active;
case AuctionStatus.Active:
return newStatus is AuctionStatus.None or AuctionStatus.FirstWarning or AuctionStatus.Pause;
case AuctionStatus.FirstWarning:
return newStatus is AuctionStatus.None or AuctionStatus.SecondWarning or AuctionStatus.Pause;
case AuctionStatus.SecondWarning:
return newStatus is AuctionStatus.None or 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;
} }
} }
} }

View File

@ -1,10 +1,12 @@
using Nop.Core; using Nop.Core;
using Nop.Core.Caching; using Nop.Core.Caching;
using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Customers;
using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
using Nop.Services.Catalog; using Nop.Services.Catalog;
using Nop.Services.Logging; using Nop.Services.Logging;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
@ -52,6 +54,7 @@ public class AuctionService : IAuctionService
public AuctionService( public AuctionService(
AuctionDbContext ctx, AuctionDbContext ctx,
IProductService productService, IProductService productService,
//IRepository<Auction> auctionRepository, //IRepository<Auction> auctionRepository,
//IRepository<ProductToAuctionMapping> productToAuctionRepository, //IRepository<ProductToAuctionMapping> productToAuctionRepository,
IShortTermCacheManager shortTermCacheManager, IShortTermCacheManager shortTermCacheManager,
@ -124,27 +127,31 @@ public class AuctionService : IAuctionService
return true; return true;
} }
public async Task DeactivateProductToAuctionByProductId(int productId) public async Task ResetProductToAuctionByProductId(int productId)
=> await DeactivateProductToAuctionAsync(await _ctx.ProductToAuctions.GetByProductId(productId).FirstOrDefaultAsync()); => await ResetProductToAuctionAsync(await _ctx.ProductToAuctions.GetByProductId(productId).FirstOrDefaultAsync());
public async Task DeactivateProductToAuctionByIdAsync(int productToAuctionId, decimal basePrice = 0) public Task ResetProductToAuctionByIdAsync(int productToAuctionId, decimal basePrice = 0)
=> await DeactivateProductToAuctionAsync(_ctx.ProductToAuctions.GetById(productToAuctionId), basePrice); => ResetProductToAuctionAsync(_ctx.ProductToAuctions.GetById(productToAuctionId), basePrice);
public async Task DeactivateProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0) public Task ResetProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0)
=> _ctx.ResetProductToAuctionAsync(productToAuction, basePrice);
public Task<AuctionBid> GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId)
=> _ctx.GetLastAuctionBidByProductToAuctionId(productToAuctionId);
public Task<AuctionBid> RevertAuctionBidByProductToAuctionIdAsync(int productToAuctionId)
=> _ctx.RevertAuctionBidByProductToAuctionId(productToAuctionId);
public async Task<Product> GetProductById(int productId)
{ {
if (basePrice <= 0) var product = await _productService.GetProductByIdAsync(productId);
{ if (product != null) return product;
var product = await _productService.GetProductByIdAsync(productToAuction.ProductId);
_logger.Error($"AuctionService.GetProductById(); (product == null)", null, await _workContext.GetCurrentCustomerAsync());
return null;
if (product == null) _logger.Error($"AuctionService.DeactivateProductToAuctionByIdAsync(); product == null");
else basePrice = product.Price;
} }
await _ctx.ProductToAuctions.DeactivateItem(productToAuction, basePrice);
}
public Task<AuctionBid> GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId) => _ctx.AuctionBids.GetLastAuctionBidByProductToAuctionIdAsync(productToAuctionId);
/// <summary> /// <summary>
/// Gets all bids /// Gets all bids
/// </summary> /// </summary>
@ -240,7 +247,7 @@ public class AuctionService : IAuctionService
foreach (var auctionDtoProductToAuctionDto in auctionDto.ProductToAuctionDtos) foreach (var auctionDtoProductToAuctionDto in auctionDto.ProductToAuctionDtos)
{ {
auctionDtoProductToAuctionDto.AuctionBidDtos.AddRange(await _ctx.AuctionBids.GetByProductToAuctionIdAsync(auctionDtoProductToAuctionDto.Id).OrderByDescending(x => x.Id).Select(x => new AuctionBidDto(x)).ToListAsync()); auctionDtoProductToAuctionDto.AuctionBidDtos.AddRange(await _ctx.AuctionBids.GetByProductToAuctionId(auctionDtoProductToAuctionDto.Id).OrderByDescending(x => x.Id).Select(x => new AuctionBidDto(x)).ToListAsync());
} }
return auctionDto; return auctionDto;

View File

@ -148,7 +148,7 @@
document.getElementById("signalRCloseItemButton").disabled = true; document.getElementById("signalRCloseItemButton").disabled = true;
event.preventDefault(); event.preventDefault();
handleAuctionStatusChange(AuctionStatus.Sold); //Itt SoldOut volt, átírtam Sold-ra! - J. handleAuctionStatusChange(AuctionStatus.None); //Itt SoldOut volt, átírtam Sold-ra! - J.
return false; return false;
}); });