This commit is contained in:
Adam 2024-12-18 20:54:25 +01:00
commit 1b6ad7e33d
20 changed files with 625 additions and 249 deletions

View File

@ -28,52 +28,52 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Components
var currency = await workContext.GetWorkingCurrencyAsync(); var currency = await workContext.GetWorkingCurrencyAsync();
await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Before lock; widgetZone: {widgetZone}", null, customer); await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Before lock; widgetZone: {widgetZone}", null, customer);
using (await lockService.SemaphoreSlim.UseWaitAsync()) //using (await lockService.SemaphoreSlim.UseWaitAsync())
{ //{
await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Enter lock; widgetZone: {widgetZone}", null, customer); // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Enter lock; widgetZone: {widgetZone}", null, customer);
await Task.Delay(1000); // await Task.Delay(1000);
var auctions = await auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); // var auctions = await auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync();
if (auctions.Count > 0) // if (auctions.Count > 0)
{ // {
await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}"); // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}");
var statusChangedMessageWrapper = new MessageWrapper // var statusChangedMessageWrapper = new MessageWrapper
{ // {
MessageType = nameof(ProductToAuctionStatusNotification), // MessageType = nameof(ProductToAuctionStatusNotification),
SenderId = 0, // SenderId = 0,
ResponseType = ResponseType.ToAllClients // ResponseType = ResponseType.ToAllClients
}; // };
foreach (var auction in auctions) // foreach (var auction in auctions)
{ // {
auction.Closed = false; // auction.Closed = false;
await auctionService.UpdateAuctionAsync(auction); // await auctionService.UpdateAuctionAsync(auction);
var auctionDto = new AuctionDto(auction); // var auctionDto = new AuctionDto(auction);
var productToAuctions = (await auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList(); // var productToAuctions = (await auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList();
foreach (var productToAuction in productToAuctions) // foreach (var productToAuction in productToAuctions)
{ // {
productToAuction.AuctionStatus = AuctionStatus.Active; // productToAuction.AuctionStatus = AuctionStatus.Active;
auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); // auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction));
////TEMPOPRARY - J. // ////TEMPOPRARY - J.
//statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); // //statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson();
//await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); // //await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson());
////TEMPOPRARY - J. // ////TEMPOPRARY - J.
} // }
await auctionService.UpdateProductToAuctionMappingAsync(productToAuctions); // await auctionService.UpdateProductToAuctionMappingAsync(productToAuctions);
statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); // statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson();
await auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); // await auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson());
} // }
} // }
await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Exit lock; widgetZone: {widgetZone}", null, customer); // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Exit lock; widgetZone: {widgetZone}", null, customer);
} //}
await logger.InformationAsync($"SignalR Widget called customer: {customer.Email}"); await logger.InformationAsync($"SignalR Widget called customer: {customer.Email}");

View File

@ -47,6 +47,10 @@
console.log("SignalR connected! connectionId: " + window.ConnectionId); console.log("SignalR connected! connectionId: " + window.ConnectionId);
}); });
connection.on("OnDateTimeReceive", dateTime => {
console.log("SignalR date received! dateTime: " + dateTime);
});
function start() { function start() {
connection.start().catch(function (err) { connection.start().catch(function (err) {
setTimeout(function () { setTimeout(function () {

View File

@ -15,13 +15,24 @@ public class AuctionBidDbTable : MgDbTableBase<AuctionBid>
{ {
} }
public IQueryable<AuctionBid> GetLastAuctionBidByProductToAuctionId(int productToAuctionId) public IOrderedQueryable<AuctionBid> GetAllLastBidByAuctionId(int auctionId)
=> GetByProductToAuctionId(productToAuctionId).OrderByDescending(x => x.Id); {
return GetAllByAuctionId(auctionId)
.OrderByDescending(x => x.Id)
.GroupBy(x => x.AuctionId, (_, bids) => bids.FirstOrDefault())
.OrderByDescending(percentGroup => percentGroup.Id);
}
public IOrderedQueryable<AuctionBid> GetLastAuctionBidByProductToAuctionId(int productToAuctionId)
=> GetAllByProductToAuctionId(productToAuctionId).OrderByDescending(x => x.Id);
public Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) public Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId)
=> Table.CountAsync(x => x.ProductAuctionMappingId == productToAuctionId); => Table.CountAsync(x => x.ProductAuctionMappingId == productToAuctionId);
public IQueryable<AuctionBid> GetByProductToAuctionId(int productToAuctionId) public IQueryable<AuctionBid> GetAllByAuctionId(int auctionId)
=> Table.Where(x => x.AuctionId == auctionId);
public IQueryable<AuctionBid> GetAllByProductToAuctionId(int productToAuctionId)
=> Table.Where(x => x.ProductAuctionMappingId == productToAuctionId); => Table.Where(x => x.ProductAuctionMappingId == productToAuctionId);
public Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId) public Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId)

View File

@ -19,7 +19,7 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>,
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; }
//public EntityRepository<Auction> Auctions2 { get; set; } //public EntityRepository<Auction> Auctions2 { get; set; }
//public IRepository<AuctionBid> AuctionBids2 { get; set; } //public IRepository<AuctionBid> AuctionBids2 { get; set; }
@ -33,7 +33,7 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>,
Auctions = auctionDbTable; Auctions = auctionDbTable;
ProductToAuctions = productToAuctionDbTable; ProductToAuctions = productToAuctionDbTable;
AuctionBids = auctionBidDbTable; AuctionBids = auctionBidDbTable;
//Auctions.Table //Auctions.Table
//var auctions = DataProvider.GetTable<Auction>().Where(x => x.Closed); //var auctions = DataProvider.GetTable<Auction>().Where(x => x.Closed);
} }
@ -44,6 +44,11 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>,
// AuctionBids2 = _auctionBidRepository; // AuctionBids2 = _auctionBidRepository;
//} //}
public Task<List<AuctionBid>> GetAllLastBidByAuctionIdAsync(int auctionId) => AuctionBids.GetAllLastBidByAuctionId(auctionId).ToListAsync();
public Task<Dictionary<int, AuctionBid>> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId)
=> AuctionBids.GetAllLastBidByAuctionId(auctionId).ToDictionaryAsync(x => x.ProductAuctionMappingId);
public async Task<List<ProductToAuctionMapping>> GetProductToAuctionsByProductIdAsync(int productId) public async Task<List<ProductToAuctionMapping>> GetProductToAuctionsByProductIdAsync(int productId)
{ {
return [..await ProductToAuctions.GetByProductId(productId).ToListAsync()]; return [..await ProductToAuctions.GetByProductId(productId).ToListAsync()];
@ -61,9 +66,9 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet<AuctionDbTable>,
=> AuctionBids.GetLastAuctionBidByProductToAuctionId(productToAuctionId).FirstOrDefaultAsync(); => AuctionBids.GetLastAuctionBidByProductToAuctionId(productToAuctionId).FirstOrDefaultAsync();
public Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) public Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId)
=> AuctionBids.GetBidsCountByProductToAuctionIdAsync(productToAuctionId); => AuctionBids.GetBidsCountByProductToAuctionIdAsync(productToAuctionId);
public Task<AuctionBid> RevertAuctionBidByProductToAuctionId(int productToAuctionId) public Task<AuctionBid> RevertAuctionBidByProductToAuctionId(int productToAuctionId)
=> AuctionBids.RevertByProductToAuctionIdAsync(productToAuctionId); => AuctionBids.RevertByProductToAuctionIdAsync(productToAuctionId);

View File

@ -10,9 +10,9 @@ using Nop.Services.Logging;
namespace Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; namespace Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer;
public class AuctionDbTable: MgDbTableBase<Auction> public class AuctionDbTable : MgDbTableBase<Auction>
{ {
public AuctionDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger) public AuctionDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger)
: base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger) : base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger)
{ {
} }
@ -26,9 +26,12 @@ public class AuctionDbTable: MgDbTableBase<Auction>
/// x.StartDateUtc <= utcNow && x.EndDateUtc >= utcNow /// x.StartDateUtc <= utcNow && x.EndDateUtc >= utcNow
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IQueryable<Auction> GetAllCurrentAutoOpenAndClosedAuctions() public IOrderedQueryable<Auction> GetAllCurrentAutoOpenAndClosedAuctions()
{ {
var utcNow = DateTime.UtcNow; var utcNow = DateTime.UtcNow;
return Table.Where(x => x.AuctionType == AuctionType.AutomaticAll && x.Closed && x.StartDateUtc <= utcNow && x.EndDateUtc >= utcNow).OrderByDescending(x=>x.StartDateUtc);
return GetAllAuctions()
.Where(x => x.AuctionType == AuctionType.AutomaticAll && x.StartDateUtc <= utcNow && (!x.Closed || (x.Closed && x.EndDateUtc >= utcNow)))
.OrderByDescending(x => x.StartDateUtc);
} }
} }

View File

@ -24,7 +24,7 @@ public class ProductToAuctionDbTable : MgDbTableBase<ProductToAuctionMapping>
private static bool HasActiveAuctionStatus(AuctionStatus auctionStatus) private static bool HasActiveAuctionStatus(AuctionStatus auctionStatus)
{ {
//TODO: erre a problémára kitalálni valamit! - J. //TODO: erre a problémára kitalálni valamit! - J.
return auctionStatus == AuctionStatus.Active || auctionStatus == AuctionStatus.FirstWarning || auctionStatus == AuctionStatus.SecondWarning; return auctionStatus == AuctionStatus.Active || auctionStatus == AuctionStatus.FirstWarning || auctionStatus == AuctionStatus.SecondWarning || auctionStatus == AuctionStatus.Pause;
//return auctionStatus.HasFlag(AuctionStatus.Active) || auctionStatus.HasFlag(AuctionStatus.FirstWarning) || auctionStatus.HasFlag(AuctionStatus.SecondWarning); //return auctionStatus.HasFlag(AuctionStatus.Active) || auctionStatus.HasFlag(AuctionStatus.FirstWarning) || auctionStatus.HasFlag(AuctionStatus.SecondWarning);
} }
@ -36,13 +36,13 @@ public class ProductToAuctionDbTable : MgDbTableBase<ProductToAuctionMapping>
public IQueryable<ProductToAuctionMapping> GetByProductId(int productId, bool activeProductOnly = false) public IQueryable<ProductToAuctionMapping> GetByProductId(int productId, bool activeProductOnly = false)
{ {
return Table.Where(x => x.ProductId == productId && return Table.Where(x => x.ProductId == productId &&
(!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 || x.AuctionStatus == AuctionStatus.Pause /*HasActiveAuctionStatus(x.AuctionStatus)*/));
} }
public IQueryable<ProductToAuctionMapping> GetProductToAuctionsByAuctionId(int auctionId, bool activeProductOnly = false) public IQueryable<ProductToAuctionMapping> GetProductToAuctionsByAuctionId(int auctionId, bool activeProductOnly = false)
{ {
return Table.Where(x => x.AuctionId == auctionId && return Table.Where(x => x.AuctionId == auctionId &&
(!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 || x.AuctionStatus == AuctionStatus.Pause /*HasActiveAuctionStatus(x.AuctionStatus)*/));
} }
public IQueryable<ProductToAuctionMapping> GetNotClosedItemsByAuctionId(int auctionId) public IQueryable<ProductToAuctionMapping> GetNotClosedItemsByAuctionId(int auctionId)

View File

@ -8,8 +8,9 @@ using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
public partial class Auction: MgEntityBase, IAuction public class Auction: MgEntityBase, IAuction
{ {
public int StoreId { get; set; }
public string AuctionName { get; set; } public string AuctionName { get; set; }
//[NotMapped] //[NotMapped]

View File

@ -8,6 +8,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities
{ {
public partial class AuctionBid : MgEntityBase, IAuctionBid public partial class AuctionBid : MgEntityBase, IAuctionBid
{ {
public int AuctionId { get; set; }
public int ProductAuctionMappingId { get; set; } public int ProductAuctionMappingId { get; set; }
public int CustomerId { get; set; } public int CustomerId { get; set; }

View File

@ -6,5 +6,6 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces;
public interface IAuction : IAuctionDtoBase, ITimeStampInfo //, ISoftRemoveEntityInt public interface IAuction : IAuctionDtoBase, ITimeStampInfo //, ISoftRemoveEntityInt
{ {
public int StoreId { get; set; }
public int? CategoryId { get; set; } public int? CategoryId { get; set; }
} }

View File

@ -5,6 +5,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces;
public interface IProductToAuctionMapping : IProductToAuctionDtoBase, ITimeStampInfo //, ISoftRemoveEntityInt public interface IProductToAuctionMapping : IProductToAuctionDtoBase, ITimeStampInfo //, ISoftRemoveEntityInt
{ {
public decimal MinimumPrice{ get; set; }
public int OrderId { get; set; } public int OrderId { get; set; }
public int OrderItemId { get; set; } public int OrderItemId { get; set; }
} }

View File

@ -30,6 +30,7 @@ public partial class ProductToAuctionMapping : MgEntityBase, IProductToAuctionMa
public decimal StartingPrice { get; set; } public decimal StartingPrice { get; set; }
public decimal CurrentPrice { get; set; } public decimal CurrentPrice { get; set; }
public decimal MinimumPrice { get; set; }
public int ProductAmount { get; set; } = 1; public int ProductAmount { get; set; } = 1;
public int SortIndex { get; set; } public int SortIndex { get; set; }

View File

@ -15,19 +15,17 @@ using Nop.Core.Domain.Customers;
using Nop.Services.Catalog; using Nop.Services.Catalog;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.IdentityModel.Tokens;
namespace Nop.Plugin.Misc.AuctionPlugin.Hubs namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
{ {
public class AuctionHub(SessionService sessionService, ILockService lockService, ILogger logger, IProductService productService, AuctionService auctionService, IWorkContext workContext, ICustomerService customerService, ICategoryService categoryService) public class AuctionHub(SessionService sessionService, ILockService lockService, ILogger logger, IProductService productService, AuctionService auctionService, IWorkContext workContext, ICustomerService customerService)
: Hub<IAuctionHubClient> : Hub<IAuctionHubClient>
{ {
//private static readonly SemaphoreSlim _handleMessageMutex = new(1);
//private readonly Semaphore _handleMessageMutex = new(1, 1, "Nop.Plugin.Misc.AuctionPlugin.Hubs.AuctionHub");
public override async Task OnConnectedAsync() public override async Task OnConnectedAsync()
{ {
var connectionId = Context.ConnectionId; var connectionId = Context.ConnectionId;
var customer = await workContext.GetCurrentCustomerAsync();
//if (sessionService.GetOrCreateSessionItem(connectionId) == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {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}"); //await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with id: {connectionId}");
@ -37,34 +35,45 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
else else
{ {
var sessionItem = sessionService.GetOrCreateSessionItem(httpContext.Session.Id); var sessionItem = sessionService.GetOrCreateSessionItem(httpContext.Session.Id);
if (sessionItem == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}; sessionId: {httpContext.Session.Id}"); if (sessionItem == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}; sessionId: {httpContext.Session.Id}");
else sessionItem.SignaRConnectionId = connectionId; else
{
sessionItem.CustomerId = customer.Id;
sessionItem.SignaRConnectionId = connectionId;
}
var userName = httpContext.Request.Query["ConnectionId"]; var userName = httpContext.Request.Query["ConnectionId"];
if (!string.IsNullOrEmpty(userName)) if (!userName.IsNullOrEmpty())
{ {
await logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with name: {userName}; connectionId: {connectionId}"); await logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with name: {userName}; connectionId: {connectionId}");
} }
} }
await base.OnConnectedAsync(); await base.OnConnectedAsync();
await Clients.Caller.OnConnected(connectionId); await Clients.Caller.OnConnected(connectionId);
} }
public override Task OnDisconnectedAsync(Exception exception) public override async Task OnDisconnectedAsync(Exception exception)
{ {
sessionService.TryRemoveSessionItem(Context.ConnectionId, out _); var httpContext = Context.GetHttpContext();
return base.OnDisconnectedAsync(exception); if (httpContext == null) await logger.ErrorAsync($"AuctionHub.OnDisconnectedAsync(); (httpContext == null); connectionId: {Context.ConnectionId}");
else sessionService.TryRemoveSessionItem(httpContext.Session.Id, out _);
await base.OnDisconnectedAsync(exception);
} }
public async Task ReceiveMessageFromClient(MessageWrapper messageWrapper) public async Task ReceiveMessageFromClient(MessageWrapper messageWrapper)
{ {
var sessionItem = IncrementRequestCount(); if (!TryGetCurrentSessionItem(out var sessionItem) || sessionItem == null)
{
await logger.ErrorAsync($"AuctionHub.ReceiveMessageFromClient(); (TryGetCurrentSessionItem(out var sessionItem) == false || sessionItem == null); connectionId: {Context.ConnectionId}");
return;
}
sessionItem.RequestCount++;
await HandleMessageAsync(messageWrapper, sessionItem, Context.ConnectionId); await HandleMessageAsync(messageWrapper, sessionItem, Context.ConnectionId);
//await SendMessageWrapperAsync(messageWrapper);
} }
public async Task<ResponseType> HandleMessageAsync(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId) public async Task<ResponseType> HandleMessageAsync(MessageWrapper messageWrapper, SessionItem sessionItem, string connectionId)
@ -92,21 +101,20 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Before lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}; jsonData: {messageWrapper.Data}", null, customer); 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. //TODO: az összes request-et egy base-ből származtatni és beletenni az AuctionRequestMode-ot! - J.
//using (await _handleMessageMutex.WaitOne())
using (await lockService.SemaphoreSlim.UseWaitAsync()) using (await lockService.SemaphoreSlim.UseWaitAsync())
{ {
try try
{ {
await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer); await logger.InformationAsync($"AuctionHub.HandleMessageAsync(); Enter lock; MessageType: {messageWrapper.MessageType}; connectionId: {connectionId}", null, customer);
await Task.Delay(3000); //await Task.Delay(3000); //TODO: ez csak a teszt időszakig van itt!!! - J.
if (messageWrapper.MessageType == "BidRequestMessage") return await HandleBidRequestAsync(customer, messageWrapper); if (messageWrapper.MessageType == "BidRequestMessage") return await HandleBidRequestAsync(customer, messageWrapper);
else else
{ {
if (!await customerService.IsAdminAsync(customer)) if (!customer.IsSystemAccount && !await customerService.IsAdminAsync(customer))
{ {
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); IsAdminAsync() == false; connectionId: {connectionId}", null, customer); logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (!customer.IsSystemAccount && !await customerService.IsAdminAsync(customer)); connectionId: {connectionId}", null, customer);
return ResponseType.Error; return ResponseType.Error;
} }
@ -151,11 +159,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
var productToAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(revertAuctionBidRequest.ProductToAuctionId)); var productToAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(revertAuctionBidRequest.ProductToAuctionId));
if (productToAuction == null) if (productToAuction == null)
{ {
logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction == null);", null, customer); logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction == null); ptaId: {revertAuctionBidRequest.ProductToAuctionId}", null, customer);
return ResponseType.Error; return ResponseType.Error;
} }
await logger.InformationAsync($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction.AuctionStatus}", null, customer); await logger.InformationAsync($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction is not {{ AuctionStatus: AuctionStatus.Pause }}); AuctionStatus: {productToAuction.AuctionStatus}; ptaId: {revertAuctionBidRequest.ProductToAuctionId}", null, customer);
var product = await auctionService.GetProductById(productToAuction.ProductId); var product = await auctionService.GetProductById(productToAuction.ProductId);
if (product == null) if (product == null)
@ -166,7 +174,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
if (productToAuction.AuctionStatus != AuctionStatus.Pause) if (productToAuction.AuctionStatus != AuctionStatus.Pause)
{ {
logger.Warning($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction.AuctionStatus != AuctionStatus.Pause; AuctionStatus: {productToAuction.AuctionStatus}", null, customer); logger.Warning($"AuctionHub.HandleRevertAuctionBidRequest(); (productToAuction.AuctionStatus != AuctionStatus.Pause); AuctionStatus: {productToAuction.AuctionStatus}; ptaId: {revertAuctionBidRequest.ProductToAuctionId}", null, customer);
await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id, ResponseType.ToCaller); await SendAuctionBidMessageAsync(messageWrapper, productToAuction, product, customer.Id, ResponseType.ToCaller);
return ResponseType.Error; return ResponseType.Error;
@ -174,7 +182,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id); var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
if (revertLastBid == null) await ResetProductToAuction(productToAuction); if (revertLastBid == null) await auctionService.ResetProductToAuction(productToAuction);
else else
{ {
productToAuction.BidsCount = await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); productToAuction.BidsCount = await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id);
@ -186,7 +194,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); Exception: {ex.Message}", ex, customer); logger.Error($"AuctionHub.HandleRevertAuctionBidRequest(); ptaId: {revertAuctionBidRequest.ProductToAuctionId}; Exception: {ex.Message}", ex, customer);
} }
return ResponseType.Error; return ResponseType.Error;
@ -203,7 +211,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
try 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); await logger.InformationAsync($"AuctionHub.HandleBidRequestAsync(); Bid received; Auction: {bidRequestMessage.AuctionId}; ptaId: {bidRequestMessage.ProductAuctionMappingId}; Product: {bidRequestMessage.ProductId}; Bid: {bidRequestMessage.BidPrice}; Customer: {bidRequestMessage.CustomerId}", null, customer);
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)
@ -223,8 +231,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
var activeProductAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(bidRequestMessage.ProductAuctionMappingId)); var activeProductAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(bidRequestMessage.ProductAuctionMappingId));
if (activeProductAuction is not { IsActiveItem: true } || (activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer))) 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); logger.Warning($"AuctionHub.HandleBidRequestAsync(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)); ptaId: {bidRequestMessage.ProductAuctionMappingId}; AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer);
await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller); await SendAuctionBidMessageAsync(messageWrapper, activeProductAuction, product, customer.Id, ResponseType.ToCaller);
return ResponseType.Error; return ResponseType.Error;
} }
@ -242,6 +250,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
} }
var auctionBid = bidRequestMessage.CreateMainEntity(); var auctionBid = bidRequestMessage.CreateMainEntity();
auctionBid.AuctionId = auction.Id;
auctionBid.ProductAuctionMappingId = activeProductAuction.Id; auctionBid.ProductAuctionMappingId = activeProductAuction.Id;
await auctionService.InsertBidAsync(auctionBid); await auctionService.InsertBidAsync(auctionBid);
@ -260,7 +269,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.Error($"AuctionHub.HandleBidRequestAsync(); Exception: {ex.Message}", ex, customer); logger.Error($"AuctionHub.HandleBidRequestAsync(); ptaId: {bidRequestMessage.ProductAuctionMappingId}; Exception: {ex.Message}", ex, customer);
} }
return ResponseType.Error; return ResponseType.Error;
@ -272,100 +281,113 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
if (auctionProductStatusRequest == null) if (auctionProductStatusRequest == null)
{ {
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer);
return ResponseType.Error; return ResponseType.None;
} }
try try
{ {
//var responseType = ResponseType.ToAllClients; //var responseType = ResponseType.ToAllClients;
await logger.InformationAsync($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); ProductToAuctionMappingId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer); await logger.InformationAsync($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); ptaId: {auctionProductStatusRequest.ProductToAuctionId}; Status: {auctionProductStatusRequest.AuctionStatus}({(int)auctionProductStatusRequest.AuctionStatus})", null, customer);
var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(auctionProductStatusRequest.ProductToAuctionId); var (auction, productToAuction, responseType) = await auctionService.GetAndUpdateProductToAuctionStatusIfValidAsync(auctionProductStatusRequest.ProductToAuctionId, auctionProductStatusRequest.AuctionStatus, customer);
if (productToAuction == null) if (auction == null || productToAuction == null || responseType == ResponseType.None) return ResponseType.None;
{
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer);
return ResponseType.Error;
}
var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, responseType);
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. //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) if ( /*AuctionRequestMode.Normal &&*/ auction.AuctionType == AuctionType.AutomaticNext && productToAuction.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold)
await StepNextProductToAuctionAsync(statusChangedMessageWrapper, customer, productToAuction, auctionProductStatusRequest); await StepNextProductToAuctionAsync(statusChangedMessageWrapper, customer, productToAuction, auctionProductStatusRequest);
return ResponseType.ToAllClients; return ResponseType.ToAllClients;
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); Exception: {ex.Message}", ex, customer); logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); ptaId: {auctionProductStatusRequest.ProductToAuctionId}; Exception: {ex.Message}", ex, customer);
} }
return ResponseType.Error; return ResponseType.Error;
} }
//private async Task<ResponseType> UpdateProductToAuctionStatusIfValidAsync(AuctionStatus newProductToAuctionStatus, Auction auction, ProductToAuctionMapping productToAuction, Customer customer)
//{
// if (!IsValidRequestAuctionStatus(newProductToAuctionStatus, productToAuction.AuctionStatus))
// {
// logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); RequestAuctionStatusIsValid() == false; newStatus: {newProductToAuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer);
// return ResponseType.ToCaller;
// }
// if (newProductToAuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId);
// else
// {
// switch (newProductToAuctionStatus)
// {
// case AuctionStatus.Active:
// productToAuction.AuctionStatus = AuctionStatus.Active;
// await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true);
// break;
// case AuctionStatus.FirstWarning:
// case AuctionStatus.SecondWarning:
// productToAuction.AuctionStatus = newProductToAuctionStatus;
// 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.UpdateProductToAuctionStatusIfValidAsync(); (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.UpdateProductToAuctionStatusIfValidAsync(); AuctionStatus not found; (newStatus == {newProductToAuctionStatus})", null, customer);
// return ResponseType.ToCaller;
// }
// await auctionService.UpdateProductToAuctionMappingAsync(productToAuction);
// }
// return ResponseType.ToAllClients;
//}
//private async Task<(Auction auction, ProductToAuctionMapping productToAuction, ResponseType responseType)> GetAndUpdateProductToAuctionStatusIfValidAsync(int productToAuctionId, AuctionStatus newProductToAuctionStatus, Customer customer)
//{
// var productToAuction = await auctionService.GetProductToAuctionMappingByIdAsync(productToAuctionId);
// if (productToAuction == null)
// {
// logger.Error($"AuctionHub.GetAndUpdateProductToAuctionStatusIfValidAsync(); (productToAuction == null)", null, customer);
// return (null, null, ResponseType.None);
// }
// var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId);
// if (auction == null || auction.Closed)
// {
// logger.Error($"AuctionHub.GetAndUpdateProductToAuctionStatusIfValidAsync(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer);
// return (null, null, ResponseType.None);
// }
// var responseType = await UpdateProductToAuctionStatusIfValidAsync(newProductToAuctionStatus, auction, productToAuction, customer);
// return (auction, productToAuction, responseType);
//}
private async Task SendStatusChangedNotificationAsync(Customer customer, MessageWrapper statusChangedMessageWrapper, ProductToAuctionMapping productToAuction, ResponseType responseType) private async Task SendStatusChangedNotificationAsync(Customer customer, MessageWrapper statusChangedMessageWrapper, ProductToAuctionMapping productToAuction, ResponseType responseType)
{ {
await UpdateStatusChangedNotificationMessageWrapperAsync(statusChangedMessageWrapper, customer, productToAuction, responseType); await UpdateStatusChangedNotificationMessageWrapperAsync(statusChangedMessageWrapper, customer, productToAuction, responseType);
@ -402,7 +424,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
//activeProductAuction.StartingPrice = product.OldPrice; //TODO: ez biztosan kezelve van mikor összerendeljük? - J. //activeProductAuction.StartingPrice = product.OldPrice; //TODO: ez biztosan kezelve van mikor összerendeljük? - J.
productToAuction.CurrentPrice = bidPrice; productToAuction.CurrentPrice = bidPrice;
productToAuction.WinnerCustomerId = lastBidCustomerId; productToAuction.WinnerCustomerId = lastBidCustomerId;
await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); await auctionService.UpdateProductToAuctionAsync(productToAuction);
return true; return true;
} }
@ -485,35 +507,35 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
}.ToJson(); }.ToJson();
} }
private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null) //private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null)
{ //{
productToAuction.AuctionStatus = AuctionStatus.None; // productToAuction.AuctionStatus = AuctionStatus.None;
await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice); // await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice);
categoryId ??= (await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId; // categoryId ??= (await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId;
await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false); // await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false);
} //}
private async Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured) //private async Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured)
{ //{
//Leszarjuk ha elszáll, az aukció menjen tovább... - J. // //Leszarjuk ha elszáll, az aukció menjen tovább... - J.
try // try
{ // {
if (categoryId.GetValueOrDefault(0) == 0) return; // if (categoryId.GetValueOrDefault(0) == 0) return;
var productCategory = (await categoryService.GetProductCategoriesByProductIdAsync(productId)).FirstOrDefault(x => x.CategoryId == categoryId); // var productCategory = (await categoryService.GetProductCategoriesByProductIdAsync(productId)).FirstOrDefault(x => x.CategoryId == categoryId);
if (productCategory == null) return; // if (productCategory == null) return;
if (productCategory.IsFeaturedProduct == isFeatured) return; // if (productCategory.IsFeaturedProduct == isFeatured) return;
productCategory.IsFeaturedProduct = isFeatured; // productCategory.IsFeaturedProduct = isFeatured;
await categoryService.UpdateProductCategoryAsync(productCategory); // await categoryService.UpdateProductCategoryAsync(productCategory);
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
logger.Error($"AuctionHub.UpdateProductCategoryIsFeaturedAsync(); categoryId: {categoryId}; productId: {productId}; isFeatured: {isFeatured}", 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) public async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType)
{ {
@ -538,16 +560,20 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
if (messageWrapper.HideToaster) await Clients.All.send(messageWrapperJson); if (messageWrapper.HideToaster) await Clients.All.send(messageWrapperJson);
else else
{ {
//messageWrapperJObject["senderId" /*nameof(MessageWrapper.SenderId)*/] = "-1";
await Clients.Others.send(messageWrapperJson); await Clients.Others.send(messageWrapperJson);
var messageWrapperJObject = JObject.Parse(messageWrapperJson); var messageWrapperJObject = JObject.Parse(messageWrapperJson);
messageWrapperJObject["hideToaster" /*nameof(MessageWrapper.HideToaster)*/] = "true"; messageWrapperJObject["hideToaster" /*nameof(MessageWrapper.HideToaster)*/] = "true";
await Clients.Caller.send(messageWrapperJObject.ToString(Formatting.None)); await Clients.Caller.send(messageWrapperJObject.ToString(Formatting.None));
} }
break; break;
case ResponseType.Error: case ResponseType.Error:
messageWrapper.HideToaster = false;
await Clients.Caller.send(messageWrapper.ToJson());
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
@ -560,35 +586,33 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs
// else await Clients.All.send(messageWrapper.ToJson()); // else await Clients.All.send(messageWrapper.ToJson());
//} //}
private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus) //private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus)
{ //{
switch (oldStatus) // switch (oldStatus)
{ // {
case AuctionStatus.None: // case AuctionStatus.None:
return newStatus is AuctionStatus.Active or AuctionStatus.Pause; // return newStatus is AuctionStatus.Active or AuctionStatus.Pause;
case AuctionStatus.Active: // case AuctionStatus.Active:
return newStatus is AuctionStatus.FirstWarning or AuctionStatus.Pause; // return newStatus is AuctionStatus.FirstWarning or AuctionStatus.Pause;
case AuctionStatus.FirstWarning: // case AuctionStatus.FirstWarning:
return newStatus is AuctionStatus.SecondWarning or AuctionStatus.Pause; // return newStatus is AuctionStatus.SecondWarning or AuctionStatus.Pause;
case AuctionStatus.SecondWarning: // case AuctionStatus.SecondWarning:
return newStatus is AuctionStatus.Sold or AuctionStatus.Pause; // return newStatus is AuctionStatus.Sold or AuctionStatus.Pause;
case AuctionStatus.Pause: // case AuctionStatus.Pause:
return newStatus is AuctionStatus.None or AuctionStatus.Active; // return newStatus is AuctionStatus.None or AuctionStatus.Active;
case AuctionStatus.Sold: // case AuctionStatus.Sold:
case AuctionStatus.NotSold: // case AuctionStatus.NotSold:
default: // default:
return false; // return false;
} // }
} //}
private SessionItem IncrementRequestCount() private bool TryGetCurrentSessionItem(out SessionItem sessionItem)
{ {
SessionItem sessionItem = null; sessionItem = null;
var httpContext = Context.GetHttpContext(); var httpContext = Context.GetHttpContext();
if (httpContext != null && sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem)) sessionItem.RequestCount++; return httpContext != null && sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem);
return sessionItem;
} }
} }
} }

View File

@ -52,11 +52,6 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure
hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(10); hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(10);
}); });
//register services and interfaces
//IRepository<AuctionBid> _customerBidRepository;
//protected readonly IShortTermCacheManager _shortTermCacheManager;
// protected readonly IStaticCacheManager _staticCacheManager;
services.AddScoped<ILocalizationService, LocalizationService>(); services.AddScoped<ILocalizationService, LocalizationService>();
services.AddScoped<ISettingService, SettingService>(); services.AddScoped<ISettingService, SettingService>();
services.AddScoped<AuctionEventConsumer>(); services.AddScoped<AuctionEventConsumer>();
@ -72,13 +67,15 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure
services.AddScoped<AuctionBidDbTable>(); services.AddScoped<AuctionBidDbTable>();
services.AddScoped<AuctionDbContext>(); services.AddScoped<AuctionDbContext>();
services.AddScoped<MyProductModelFactory>(); services.AddScoped<MyProductModelFactory>(); //TODO: ez mi? - J.
//services.AddScoped<SignalRMessageHandler>();
services.AddScoped<IOrderService, OrderService>(); services.AddScoped<IOrderService, OrderService>();
services.AddScoped<IOrderProcessingService, OrderProcessingService>(); services.AddScoped<IOrderProcessingService, OrderProcessingService>();
services.AddScoped<IShoppingCartService, ShoppingCartService>(); services.AddScoped<IShoppingCartService, ShoppingCartService>();
services.AddScoped<IStoreContext, WebStoreContext>(); services.AddScoped<IStoreContext, WebStoreContext>();
services.AddScoped<ICurrencyService, CurrencyService>(); services.AddScoped<ICurrencyService, CurrencyService>();
services.AddHostedService<AuctionBackgroundService>();
} }
/// <summary> /// <summary>

View File

@ -0,0 +1,168 @@
using AyCode.Core.Extensions;
using AyCode.Utils.Extensions;
using Mango.Nop.Services;
using Microsoft.AspNetCore.SignalR;
using Nop.Core;
using Nop.Core.Domain.Customers;
using Nop.Data;
using Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums;
using Nop.Plugin.Misc.AuctionPlugin.Hubs;
using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
using Nop.Services.Customers;
using Nop.Services.Logging;
using System.Collections.Generic;
namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public class AuctionBackgroundService : MgBackgroundServiceBase
{
private const int WARNING_STATUS_INTERVAL_SECOND = 15;
private readonly ILogger _logger;
private readonly IHubContext<AuctionHub> _auctionHubContext;
private readonly ILockService _lockService;
private readonly AuctionService _auctionService;
private readonly Customer _auctionSystemCustomer;
public AuctionBackgroundService(ILogger logger, IServiceProvider service, IHubContext<AuctionHub> auctionHubContext, AuctionService auctionService, ILockService lockService, IRepository<Customer> customerService) : base(logger, service)
{
_logger = logger;
_auctionHubContext = auctionHubContext;
_lockService = lockService;
_auctionService = auctionService;
_auctionSystemCustomer = customerService.Table.FirstOrDefault(x => x.Email == "builtin@background_task_auction.com");
if (_auctionSystemCustomer == null)
_logger.Error($"AuctionBackgroundService.AuctionBackgroundService(); _auctionSystemCustomer == null;", null, null);
}
protected override async Task OnExecuteAsync()
{
await Task.Delay(WARNING_STATUS_INTERVAL_SECOND * 1000); //Az elejére kell tenni! ha exception lenne, akkor ne kezdje el darálni... - J.
if (_auctionSystemCustomer == null) return;
await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Before lock; ", null, _auctionSystemCustomer);
using (await _lockService.SemaphoreSlim.UseWaitAsync())
{
await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Enter lock;", null, _auctionSystemCustomer);
var currentAutomaticAuctions = await _auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync();
if (currentAutomaticAuctions.Count > 0)
{
await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); currentAutomaticAuctions.Count > 0; count: {currentAutomaticAuctions.Count}; names: {string.Join("; ", currentAutomaticAuctions.Select(x => x.AuctionName))}", null, _auctionSystemCustomer);
var statusChangedMessageWrapper = new MessageWrapper
{
MessageType = nameof(ProductToAuctionStatusNotification),
SenderId = _auctionSystemCustomer.Id, //TODO: -1; - J.
ResponseType = ResponseType.ToAllClients
};
foreach (var automaticAuction in currentAutomaticAuctions)
{
await CheckAndUpdateProductToAuctionsStatusAsync(automaticAuction, statusChangedMessageWrapper);
await OpenOrCloseAutomaticAuctionsAsync(automaticAuction, statusChangedMessageWrapper);
}
}
//await _auctionHubContext.Clients.All.SendAsync("OnDateTimeReceive", DateTime.Now.ToString("G")); //TODO: ez csak a teszt időszakig van itt!!! - J.
await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Exit lock;", null, _auctionSystemCustomer);
}
}
private async Task CheckAndUpdateProductToAuctionsStatusAsync(Auction automaticAuction, MessageWrapper statusChangedMessageWrapper)
{
try
{
if (automaticAuction.Closed || automaticAuction.EndDateUtc >= DateTime.UtcNow.AddSeconds(2 * WARNING_STATUS_INTERVAL_SECOND)) return;
var activeProductToAuctions = await _auctionService.GetProductToAuctionsByAuctionIdAsync(automaticAuction.Id, true);
if (activeProductToAuctions.Count == 0) return;
var auctionDto = new AuctionDto(automaticAuction);
var changedProductToAuctions = new List<ProductToAuctionMapping>(activeProductToAuctions.Count);
foreach (var activeProductToAuction in activeProductToAuctions)
{
var newPtaStatus = activeProductToAuction.AuctionStatus switch
{
AuctionStatus.Active => AuctionStatus.FirstWarning,
AuctionStatus.FirstWarning => AuctionStatus.SecondWarning,
AuctionStatus.SecondWarning => AuctionStatus.Sold,
_ => AuctionStatus.None
};
if (newPtaStatus == AuctionStatus.None) continue;
var responseType = await _auctionService.UpdateProductToAuctionStatusIfValidAsync(newPtaStatus, automaticAuction, activeProductToAuction, _auctionSystemCustomer, false);
if (responseType == ResponseType.None) continue;
changedProductToAuctions.Add(activeProductToAuction);
auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(activeProductToAuction));
}
if (changedProductToAuctions.Count == 0) return;
await _auctionService.UpdateProductToAuctionAsync(changedProductToAuctions);
statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, "EMPTY").ToJson();
await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson());
}
catch (Exception ex)
{
await _logger.ErrorAsync($"AuctionBackgroundService.CheckAndUpdateProductToAuctionsStatusAsync(); auctionId: {automaticAuction.Id}; auctionName: {automaticAuction.AuctionName}", ex, _auctionSystemCustomer);
}
}
private async Task OpenOrCloseAutomaticAuctionsAsync(Auction automaticAuction, MessageWrapper statusChangedMessageWrapper)
{
try
{
if (!automaticAuction.Closed)
{
var allItemsFinished = (await _auctionService.GetProductToAuctionsByAuctionIdAsync(automaticAuction.Id, false)).All(x => x.AuctionStatus is AuctionStatus.Sold or AuctionStatus.NotSold);
if (!allItemsFinished) return;
automaticAuction.Closed = true;
await _auctionService.UpdateAuctionAsync(automaticAuction);
//TODO: send message... - J.
return;
}
var productToAuctions = (await _auctionService.GetProductToAuctionsByAuctionIdAsync(automaticAuction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList();
if (productToAuctions.Count == 0) return;
automaticAuction.Closed = false;
var auctionDto = new AuctionDto(automaticAuction);
foreach (var productToAuction in productToAuctions)
{
var responseType = await _auctionService.UpdateProductToAuctionStatusIfValidAsync(AuctionStatus.Active, automaticAuction, productToAuction, _auctionSystemCustomer, false);
if (responseType == ResponseType.None) continue;
auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction));
}
await _auctionService.UpdateAuctionAsync(automaticAuction);
await _auctionService.UpdateProductToAuctionAsync(productToAuctions);
statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {automaticAuction.AuctionName}").ToJson();
statusChangedMessageWrapper.HideToaster = true;
await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson());
}
catch (Exception ex)
{
await _logger.ErrorAsync($"AuctionBackgroundService.OpenOrCloseAutomaticAuctionsAsync(); auctionId: {automaticAuction.Id}; name: {automaticAuction.AuctionName}", ex, _auctionSystemCustomer);
}
}
}

View File

@ -22,6 +22,7 @@ using Nop.Services.Common;
using Nop.Services.Customers; using Nop.Services.Customers;
using Nop.Services.Shipping; using Nop.Services.Shipping;
using NUglify.Helpers; using NUglify.Helpers;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces;
namespace Nop.Plugin.Misc.AuctionPlugin.Services; namespace Nop.Plugin.Misc.AuctionPlugin.Services;
@ -39,8 +40,144 @@ public class AuctionService(
IAddressService addressService, IAddressService addressService,
ICustomerService customerService, ICustomerService customerService,
IOrderService orderService, IOrderService orderService,
ILogger logger) : IAuctionService ILogger logger,
ICategoryService categoryService) : IAuctionService
{ {
#region AuctionHub
public async Task<ResponseType> UpdateProductToAuctionStatusIfValidAsync(AuctionStatus newProductToAuctionStatus, Auction auction, ProductToAuctionMapping productToAuction, Customer customer, bool updateInDatabase = true)
{
if (!IsValidRequestAuctionStatus(newProductToAuctionStatus, productToAuction.AuctionStatus))
{
logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); RequestAuctionStatusIsValid() == false; newStatus: {newProductToAuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer);
return ResponseType.ToCaller;
}
if (newProductToAuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId);
else
{
switch (newProductToAuctionStatus)
{
case AuctionStatus.Active:
productToAuction.AuctionStatus = AuctionStatus.Active;
await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true);
break;
case AuctionStatus.FirstWarning:
case AuctionStatus.SecondWarning:
productToAuction.AuctionStatus = newProductToAuctionStatus;
break;
case AuctionStatus.Sold:
case AuctionStatus.NotSold:
var lastAuctionBid = await GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id);
if (lastAuctionBid == null || lastAuctionBid.BidPrice < productToAuction.MinimumPrice) productToAuction.AuctionStatus = AuctionStatus.NotSold;
else
{
productToAuction.AuctionStatus = AuctionStatus.Sold;
productToAuction.CurrentPrice = lastAuctionBid.BidPrice;
productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId;
var placeOrderResult = await CreateOrderForWinnerAsync(productToAuction);
if (placeOrderResult == null || placeOrderResult.Id == 0)
{
logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); (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.UpdateProductToAuctionStatusIfValidAsync(); AuctionStatus not found; (newStatus == {newProductToAuctionStatus})", null, customer);
return ResponseType.ToCaller;
}
if (updateInDatabase)
await UpdateProductToAuctionAsync(productToAuction);
}
return ResponseType.ToAllClients;
}
public async Task<(Auction auction, ProductToAuctionMapping productToAuction, ResponseType responseType)> GetAndUpdateProductToAuctionStatusIfValidAsync(int productToAuctionId, AuctionStatus newProductToAuctionStatus, Customer customer)
{
var productToAuction = await GetProductToAuctionMappingByIdAsync(productToAuctionId);
if (productToAuction == null)
{
logger.Error($"AuctionHub.GetAndUpdateProductToAuctionStatusIfValidAsync(); (productToAuction == null)", null, customer);
return (null, null, ResponseType.None);
}
var auction = await GetAuctionByIdAsync(productToAuction.AuctionId);
if (auction == null || auction.Closed)
{
logger.Error($"AuctionHub.GetAndUpdateProductToAuctionStatusIfValidAsync(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer);
return (null, null, ResponseType.None);
}
var responseType = await UpdateProductToAuctionStatusIfValidAsync(newProductToAuctionStatus, auction, productToAuction, customer);
return (auction, productToAuction, responseType);
}
public async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null)
{
productToAuction.AuctionStatus = AuctionStatus.None;
await ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice);
categoryId ??= (await GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId;
await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false);
}
public 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 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;
}
}
#endregion
#region Methods #region Methods
public static decimal GetStepAmount(decimal currentPrice) public static decimal GetStepAmount(decimal currentPrice)
@ -103,29 +240,35 @@ public class AuctionService(
public Task ResetProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0) public Task ResetProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0)
=> ctx.ResetProductToAuctionAsync(productToAuction, basePrice); => ctx.ResetProductToAuctionAsync(productToAuction, basePrice);
public Task<AuctionBid> GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId) public Task<List<AuctionBid>> GetAllLastBidByAuctionIdAsync(int auctionId)
=> ctx.GetLastAuctionBidByProductToAuctionId(productToAuctionId); => ctx.GetAllLastBidByAuctionIdAsync(auctionId);
public Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) public Task<Dictionary<int, AuctionBid>> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId)
=> ctx.GetBidsCountByProductToAuctionIdAsync(productToAuctionId); => ctx.GetAllLastBidDictionaryByAuctionIdAsync(auctionId);
public Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId) public Task<AuctionBid> GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId)
=> ctx.HasBidByProductToAuctionIdAsync(productToAuctionId); => ctx.GetLastAuctionBidByProductToAuctionId(productToAuctionId);
public Task<AuctionBid> RevertAuctionBidByProductToAuctionIdAsync(int productToAuctionId) public Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId)
=> ctx.RevertAuctionBidByProductToAuctionId(productToAuctionId); => ctx.GetBidsCountByProductToAuctionIdAsync(productToAuctionId);
public async Task<Product> GetProductById(int productId) public Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId)
{ => ctx.HasBidByProductToAuctionIdAsync(productToAuctionId);
var product = await productService.GetProductByIdAsync(productId);
if (product != null) return product;
logger.Error($"AuctionService.GetProductById(); (product == null)", null, await workContext.GetCurrentCustomerAsync()); public Task<AuctionBid> RevertAuctionBidByProductToAuctionIdAsync(int productToAuctionId)
return null; => ctx.RevertAuctionBidByProductToAuctionId(productToAuctionId);
} public async Task<Product> GetProductById(int productId)
{
var product = await productService.GetProductByIdAsync(productId);
if (product != null) return product;
/// <summary> logger.Error($"AuctionService.GetProductById(); (product == null)", null, await workContext.GetCurrentCustomerAsync());
return null;
}
/// <summary>
/// Gets all bids /// Gets all bids
/// </summary> /// </summary>
/// <param name="customerId">The store identifier; pass 0 to load all records</param> /// <param name="customerId">The store identifier; pass 0 to load all records</param>
@ -258,7 +401,7 @@ public class AuctionService(
var winnerCustomer = await customerService.GetCustomerByIdAsync(productToAuction.WinnerCustomerId); var winnerCustomer = await customerService.GetCustomerByIdAsync(productToAuction.WinnerCustomerId);
var storeId = winnerCustomer.RegisteredInStoreId; var storeId = winnerCustomer.RegisteredInStoreId;
var billingAddress = await InsertOrUpdateBillingAddressAsync(winnerCustomer); var billingAddress = await InsertOrUpdateBillingAddressAsync(winnerCustomer);
if (billingAddress == null) if (billingAddress == null)
{ {
@ -386,6 +529,7 @@ public class AuctionService(
} }
#region auctions #region auctions
public async Task InsertAuctionAsync(Auction auction) public async Task InsertAuctionAsync(Auction auction)
{ {
await ctx.Auctions.InsertAsync(auction, false); await ctx.Auctions.InsertAsync(auction, false);
@ -396,19 +540,20 @@ public class AuctionService(
await ctx.Auctions.UpdateAsync(auction); await ctx.Auctions.UpdateAsync(auction);
} }
public Task<List<Auction>> GetAllAuctionsAsync() =>ctx.Auctions.GetAllAuctions().ToListAsync(); public Task<List<Auction>> GetAllAuctionsAsync() => ctx.Auctions.GetAllAuctions().ToListAsync();
public Task<List<Auction>> GetAllCurrentAutoOpenAndClosedAuctionsAsync() =>ctx.Auctions.GetAllCurrentAutoOpenAndClosedAuctions().ToListAsync(); public Task<List<Auction>> GetAllCurrentAutoOpenAndClosedAuctionsAsync() => ctx.Auctions.GetAllCurrentAutoOpenAndClosedAuctions().ToListAsync();
public async Task<List<ProductToAuctionMapping>> GetProductToAuctionsByAuctionIdAsync(int auctionId, bool onlyActiveItems) public async Task<List<ProductToAuctionMapping>> GetProductToAuctionsByAuctionIdAsync(int auctionId, bool onlyActiveItems)
=> await ctx.ProductToAuctions.GetProductToAuctionsByAuctionId(auctionId, onlyActiveItems).OrderBy(x => x.SortIndex).ToListAsync(); => await ctx.ProductToAuctions.GetProductToAuctionsByAuctionId(auctionId, onlyActiveItems).OrderBy(x => x.SortIndex).ToListAsync();
public Task<ProductToAuctionMapping> GetNextProductToAuctionByAuctionIdAsync(int auctionId) public Task<ProductToAuctionMapping> GetNextProductToAuctionByAuctionIdAsync(int auctionId)
=> ctx.ProductToAuctions.GetNextItemByAuctionIdAsync(auctionId); => ctx.ProductToAuctions.GetNextItemByAuctionIdAsync(auctionId);
public Task<List<ProductToAuctionMapping>> GetNotClosedProductToAuctionsByAuctionId(int auctionId) public Task<List<ProductToAuctionMapping>> GetNotClosedProductToAuctionsByAuctionId(int auctionId)
=> ctx.ProductToAuctions.GetNotClosedItemsByAuctionId(auctionId).OrderBy(x => x.SortIndex).ToListAsync(); => ctx.ProductToAuctions.GetNotClosedItemsByAuctionId(auctionId).OrderBy(x => x.SortIndex).ToListAsync();
#endregion #endregion
#endregion #endregion
#region Dtos #region Dtos
@ -420,7 +565,7 @@ public class AuctionService(
foreach (var auctionDtoProductToAuctionDto in auctionDto.ProductToAuctionDtos) foreach (var auctionDtoProductToAuctionDto in auctionDto.ProductToAuctionDtos)
{ {
auctionDtoProductToAuctionDto.AuctionBidDtos.AddRange(await ctx.AuctionBids.GetByProductToAuctionId(auctionDtoProductToAuctionDto.Id).OrderByDescending(x => x.Id).Take(maxBidsCount).Select(x => new AuctionBidDto(x)).ToListAsync()); auctionDtoProductToAuctionDto.AuctionBidDtos.AddRange(await ctx.AuctionBids.GetAllByProductToAuctionId(auctionDtoProductToAuctionDto.Id).OrderByDescending(x => x.Id).Take(maxBidsCount).Select(x => new AuctionBidDto(x)).ToListAsync());
} }
return auctionDto; return auctionDto;
@ -435,7 +580,7 @@ public class AuctionService(
var auctionDto = new AuctionDto(auction); var auctionDto = new AuctionDto(auction);
if (widthProducts) auctionDto.ProductToAuctionDtos.AddRange((await GetProductToAuctionDtosByAuctionId(auctionId, activeProductOnly))); if (widthProducts) auctionDto.ProductToAuctionDtos.AddRange((await GetProductToAuctionDtosByAuctionId(auctionId, activeProductOnly)));
return auctionDto; return auctionDto;
} }
@ -474,22 +619,22 @@ public class AuctionService(
public async Task<List<ProductToAuctionDto>> GetProductToAuctionDtosByProductIdAsync(int productId) public async Task<List<ProductToAuctionDto>> GetProductToAuctionDtosByProductIdAsync(int productId)
{ {
return [..await ctx.ProductToAuctions.GetByProductId(productId).Select(x=>new ProductToAuctionDto(x)).ToListAsync()]; return [..await ctx.ProductToAuctions.GetByProductId(productId).Select(x => new ProductToAuctionDto(x)).ToListAsync()];
} }
public async Task<AuctionBidDto> GetAuctionBidDtoByIdAsync(int auctionBidId) public async Task<AuctionBidDto> GetAuctionBidDtoByIdAsync(int auctionBidId)
{ {
var auctionBid = await ctx.AuctionBids.GetByIdAsync(auctionBidId); var auctionBid = await ctx.AuctionBids.GetByIdAsync(auctionBidId);
return auctionBid == null ? null : new AuctionBidDto(auctionBid); return auctionBid == null ? null : new AuctionBidDto(auctionBid);
} }
public Task<List<ProductToAuctionMapping>> GetProductToAuctionsByProductIdAsync(int productId) public Task<List<ProductToAuctionMapping>> GetProductToAuctionsByProductIdAsync(int productId)
=> ctx.GetProductToAuctionsByProductIdAsync(productId); => ctx.GetProductToAuctionsByProductIdAsync(productId);
public Task<List<ProductToAuctionMapping>> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly) public Task<List<ProductToAuctionMapping>> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly)
=> ctx.GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, activeProductOnly); => ctx.GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, activeProductOnly);
public async Task<ProductToAuctionMapping> AssignProductToAuctionAsync(int productId, decimal startingPrice, decimal bidPrice, int auctionId) public async Task<ProductToAuctionMapping> AssignProductToAuctionAsync(int productId, decimal startingPrice, decimal bidPrice, int auctionId)
{ {
@ -528,12 +673,12 @@ public class AuctionService(
return await ctx.ProductToAuctions.GetByIdAsync(productToAuctionMappingId); return await ctx.ProductToAuctions.GetByIdAsync(productToAuctionMappingId);
} }
public async Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping) public async Task UpdateProductToAuctionAsync(ProductToAuctionMapping productToAuctionMapping)
{ {
await ctx.ProductToAuctions.UpdateAsync(productToAuctionMapping); await ctx.ProductToAuctions.UpdateAsync(productToAuctionMapping);
} }
public async Task UpdateProductToAuctionMappingAsync(IList<ProductToAuctionMapping> productToAuctionMappings) public async Task UpdateProductToAuctionAsync(IList<ProductToAuctionMapping> productToAuctionMappings)
{ {
await ctx.ProductToAuctions.UpdateAsync(productToAuctionMappings); await ctx.ProductToAuctions.UpdateAsync(productToAuctionMappings);
} }

View File

@ -1,9 +1,11 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Nop.Core; using Nop.Core;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Orders; using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.AuctionPlugin.Domains; using Nop.Plugin.Misc.AuctionPlugin.Domains;
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.Services.Orders; using Nop.Services.Orders;
namespace Nop.Plugin.Misc.AuctionPlugin.Services; namespace Nop.Plugin.Misc.AuctionPlugin.Services;
@ -14,7 +16,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public interface IAuctionService public interface IAuctionService
{ {
//decimal GetStepAmount(decimal currentPrice); //decimal GetStepAmount(decimal currentPrice);
Task<ResponseType> UpdateProductToAuctionStatusIfValidAsync(AuctionStatus newProductToAuctionStatus, Auction auction, ProductToAuctionMapping productToAuction, Customer customer, bool updateInDatabase = true);
Task<(Auction auction, ProductToAuctionMapping productToAuction, ResponseType responseType)> GetAndUpdateProductToAuctionStatusIfValidAsync(int productToAuctionId, AuctionStatus newProductToAuctionStatus, Customer customer);
Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null);
Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured);
bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus);
/// <summary> /// <summary>
/// Gets all bids /// Gets all bids
@ -29,6 +35,8 @@ public interface IAuctionService
Task<IPagedList<AuctionBid>> GetAllBidsAsync(int customerId = 0, int pageIndex = 0, int pageSize = int.MaxValue); Task<IPagedList<AuctionBid>> GetAllBidsAsync(int customerId = 0, int pageIndex = 0, int pageSize = int.MaxValue);
Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId); Task<int> GetBidsCountByProductToAuctionIdAsync(int productToAuctionId);
Task<List<AuctionBid>> GetAllLastBidByAuctionIdAsync(int auctionId);
Task<Dictionary<int, AuctionBid>> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId);
Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId); Task<bool> HasBidByProductToAuctionIdAsync(int productToAuctionId);
Task<AuctionBid> GetBidByIdAsync(int bidId); Task<AuctionBid> GetBidByIdAsync(int bidId);
@ -65,8 +73,8 @@ public interface IAuctionService
Task<List<ProductToAuctionMapping>> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly); Task<List<ProductToAuctionMapping>> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly);
Task<ProductToAuctionMapping> GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId); Task<ProductToAuctionMapping> GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId);
Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping); Task UpdateProductToAuctionAsync(ProductToAuctionMapping productToAuctionMapping);
Task UpdateProductToAuctionMappingAsync(IList<ProductToAuctionMapping> productToAuctionMappings); Task UpdateProductToAuctionAsync(IList<ProductToAuctionMapping> productToAuctionMappings);
Task<Order> CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuctionMapping); Task<Order> CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuctionMapping);
} }

View File

@ -4,5 +4,5 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public interface ISessionItem : IMgSessionItem public interface ISessionItem : IMgSessionItem
{ {
int CustomerId { get; set; }
} }

View File

@ -4,5 +4,5 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public interface ISessionService : IMgSessionService<SessionItem> public interface ISessionService : IMgSessionService<SessionItem>
{ {
bool TryGetSessionItemByCustomerId(int customerId, out SessionItem sessionItem);
} }

View File

@ -4,5 +4,5 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public class SessionItem(string sessionKey) : MgSessionItem(sessionKey), ISessionItem public class SessionItem(string sessionKey) : MgSessionItem(sessionKey), ISessionItem
{ {
public int CustomerId { get; set; }
} }

View File

@ -1,8 +1,13 @@
using Mango.Nop.Services; using Mango.Nop.Services;
using Nop.Core.Domain.Customers;
namespace Nop.Plugin.Misc.AuctionPlugin.Services; namespace Nop.Plugin.Misc.AuctionPlugin.Services;
public class SessionService : MgSessionService<SessionItem>, ISessionService public class SessionService : MgSessionService<SessionItem>, ISessionService
{ {
public bool TryGetSessionItemByCustomerId(int customerId, out SessionItem sessionItem)
{
sessionItem = Sessions.Values.FirstOrDefault(x => x.CustomerId == customerId);
return sessionItem != null;
}
} }