diff --git a/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs b/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs index 0826b3b..e187efc 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Components/LiveAnnouncementViewComponent.cs @@ -28,52 +28,52 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Components var currency = await workContext.GetWorkingCurrencyAsync(); await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Before lock; widgetZone: {widgetZone}", null, customer); - using (await lockService.SemaphoreSlim.UseWaitAsync()) - { - await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Enter lock; widgetZone: {widgetZone}", null, customer); + //using (await lockService.SemaphoreSlim.UseWaitAsync()) + //{ + // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); Enter lock; widgetZone: {widgetZone}", null, customer); - await Task.Delay(1000); + // await Task.Delay(1000); - var auctions = await auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); - if (auctions.Count > 0) - { - await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}"); + // var auctions = await auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); + // if (auctions.Count > 0) + // { + // await logger.InformationAsync($"LiveAnnouncementViewComponent.InvokeAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}"); - var statusChangedMessageWrapper = new MessageWrapper - { - MessageType = nameof(ProductToAuctionStatusNotification), - SenderId = 0, - ResponseType = ResponseType.ToAllClients - }; + // var statusChangedMessageWrapper = new MessageWrapper + // { + // MessageType = nameof(ProductToAuctionStatusNotification), + // SenderId = 0, + // ResponseType = ResponseType.ToAllClients + // }; - foreach (var auction in auctions) - { - auction.Closed = false; - await auctionService.UpdateAuctionAsync(auction); + // foreach (var auction in auctions) + // { + // auction.Closed = false; + // await auctionService.UpdateAuctionAsync(auction); - var auctionDto = new AuctionDto(auction); - var productToAuctions = (await auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList(); + // var auctionDto = new AuctionDto(auction); + // var productToAuctions = (await auctionService.GetProductToAuctionsByAuctionIdAsync(auction.Id, false)).Where(x => x.AuctionStatus == AuctionStatus.None).ToList(); - foreach (var productToAuction in productToAuctions) - { - productToAuction.AuctionStatus = AuctionStatus.Active; - auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); + // foreach (var productToAuction in productToAuctions) + // { + // productToAuction.AuctionStatus = AuctionStatus.Active; + // auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); - ////TEMPOPRARY - J. - //statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); - //await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); - ////TEMPOPRARY - J. - } + // ////TEMPOPRARY - J. + // //statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); + // //await _auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); + // ////TEMPOPRARY - J. + // } - await auctionService.UpdateProductToAuctionMappingAsync(productToAuctions); + // await auctionService.UpdateProductToAuctionMappingAsync(productToAuctions); - statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").ToJson(); - await auctionHubContext.Clients.All.SendAsync("send", statusChangedMessageWrapper.ToJson()); - } - } + // statusChangedMessageWrapper.Data = new ProductToAuctionStatusNotification(auctionDto, 0, $"Az aukciót megnyitottuk: {auction.AuctionName}").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}"); diff --git a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js index a18dc0b..68d5074 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js +++ b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js @@ -47,6 +47,10 @@ console.log("SignalR connected! connectionId: " + window.ConnectionId); }); + connection.on("OnDateTimeReceive", dateTime => { + console.log("SignalR date received! dateTime: " + dateTime); + }); + function start() { connection.start().catch(function (err) { setTimeout(function () { diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionBidDbTable.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionBidDbTable.cs index cc436d7..eebf05d 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionBidDbTable.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionBidDbTable.cs @@ -15,13 +15,24 @@ public class AuctionBidDbTable : MgDbTableBase { } - public IQueryable GetLastAuctionBidByProductToAuctionId(int productToAuctionId) - => GetByProductToAuctionId(productToAuctionId).OrderByDescending(x => x.Id); + public IOrderedQueryable GetAllLastBidByAuctionId(int auctionId) + { + return GetAllByAuctionId(auctionId) + .OrderByDescending(x => x.Id) + .GroupBy(x => x.AuctionId, (_, bids) => bids.FirstOrDefault()) + .OrderByDescending(percentGroup => percentGroup.Id); + } + + public IOrderedQueryable GetLastAuctionBidByProductToAuctionId(int productToAuctionId) + => GetAllByProductToAuctionId(productToAuctionId).OrderByDescending(x => x.Id); public Task GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) => Table.CountAsync(x => x.ProductAuctionMappingId == productToAuctionId); - - public IQueryable GetByProductToAuctionId(int productToAuctionId) + + public IQueryable GetAllByAuctionId(int auctionId) + => Table.Where(x => x.AuctionId == auctionId); + + public IQueryable GetAllByProductToAuctionId(int productToAuctionId) => Table.Where(x => x.ProductAuctionMappingId == productToAuctionId); public Task HasBidByProductToAuctionIdAsync(int productToAuctionId) diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbContext.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbContext.cs index 80cdc8b..ff8c2c6 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbContext.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbContext.cs @@ -19,7 +19,7 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet, public AuctionDbTable Auctions { get; set; } public ProductToAuctionDbTable ProductToAuctions { get; set; } public AuctionBidDbTable AuctionBids { get; set; } - + //public EntityRepository Auctions2 { get; set; } //public IRepository AuctionBids2 { get; set; } @@ -33,7 +33,7 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet, Auctions = auctionDbTable; ProductToAuctions = productToAuctionDbTable; AuctionBids = auctionBidDbTable; - + //Auctions.Table //var auctions = DataProvider.GetTable().Where(x => x.Closed); } @@ -44,6 +44,11 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet, // AuctionBids2 = _auctionBidRepository; //} + public Task> GetAllLastBidByAuctionIdAsync(int auctionId) => AuctionBids.GetAllLastBidByAuctionId(auctionId).ToListAsync(); + + public Task> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId) + => AuctionBids.GetAllLastBidByAuctionId(auctionId).ToDictionaryAsync(x => x.ProductAuctionMappingId); + public async Task> GetProductToAuctionsByProductIdAsync(int productId) { return [..await ProductToAuctions.GetByProductId(productId).ToListAsync()]; @@ -61,9 +66,9 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet, => AuctionBids.GetLastAuctionBidByProductToAuctionId(productToAuctionId).FirstOrDefaultAsync(); public Task GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) - => AuctionBids.GetBidsCountByProductToAuctionIdAsync(productToAuctionId); + => AuctionBids.GetBidsCountByProductToAuctionIdAsync(productToAuctionId); + - public Task RevertAuctionBidByProductToAuctionId(int productToAuctionId) => AuctionBids.RevertByProductToAuctionIdAsync(productToAuctionId); diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbTable.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbTable.cs index 2810284..308d3c1 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbTable.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbTable.cs @@ -10,9 +10,9 @@ using Nop.Services.Logging; namespace Nop.Plugin.Misc.AuctionPlugin.Domains.DataLayer; -public class AuctionDbTable: MgDbTableBase +public class AuctionDbTable : MgDbTableBase { - 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) { } @@ -26,9 +26,12 @@ public class AuctionDbTable: MgDbTableBase /// x.StartDateUtc <= utcNow && x.EndDateUtc >= utcNow /// /// - public IQueryable GetAllCurrentAutoOpenAndClosedAuctions() + public IOrderedQueryable GetAllCurrentAutoOpenAndClosedAuctions() { 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); } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs index 8b10b46..7a0f782 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs @@ -24,7 +24,7 @@ public class ProductToAuctionDbTable : MgDbTableBase private static bool HasActiveAuctionStatus(AuctionStatus auctionStatus) { //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); } @@ -36,13 +36,13 @@ public class ProductToAuctionDbTable : MgDbTableBase public IQueryable GetByProductId(int productId, bool activeProductOnly = false) { 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 GetProductToAuctionsByAuctionId(int auctionId, bool activeProductOnly = false) { 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 GetNotClosedItemsByAuctionId(int auctionId) diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Auction.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Auction.cs index a94e8b7..f7c3f35 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Auction.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Auction.cs @@ -8,8 +8,9 @@ using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; 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; } //[NotMapped] diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/AuctionBid.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/AuctionBid.cs index b7e70c1..2205d7b 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/AuctionBid.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/AuctionBid.cs @@ -8,6 +8,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities { public partial class AuctionBid : MgEntityBase, IAuctionBid { + public int AuctionId { get; set; } public int ProductAuctionMappingId { get; set; } public int CustomerId { get; set; } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IAuction.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IAuction.cs index 905dd6c..904dadf 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IAuction.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IAuction.cs @@ -6,5 +6,6 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces; public interface IAuction : IAuctionDtoBase, ITimeStampInfo //, ISoftRemoveEntityInt { + public int StoreId { get; set; } public int? CategoryId { get; set; } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs index 1588b64..6b7ba03 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs @@ -5,6 +5,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces; public interface IProductToAuctionMapping : IProductToAuctionDtoBase, ITimeStampInfo //, ISoftRemoveEntityInt { + public decimal MinimumPrice{ get; set; } + public int OrderId { get; set; } public int OrderItemId { get; set; } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs index 15690e2..4e22cd4 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs @@ -30,6 +30,7 @@ public partial class ProductToAuctionMapping : MgEntityBase, IProductToAuctionMa public decimal StartingPrice { get; set; } public decimal CurrentPrice { get; set; } + public decimal MinimumPrice { get; set; } public int ProductAmount { get; set; } = 1; public int SortIndex { get; set; } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs index bdce78e..bb3b24f 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -15,19 +15,17 @@ using Nop.Core.Domain.Customers; using Nop.Services.Catalog; using Newtonsoft.Json.Linq; using DocumentFormat.OpenXml.Spreadsheet; +using Microsoft.IdentityModel.Tokens; 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 { - //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() { var connectionId = Context.ConnectionId; - + var customer = await workContext.GetCurrentCustomerAsync(); //if (sessionService.GetOrCreateSessionItem(connectionId) == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}"); //await _logger.InformationAsync($"AuctionHub.OnConnectedAsync(); Caller connected with id: {connectionId}"); @@ -37,34 +35,45 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs else { var sessionItem = sessionService.GetOrCreateSessionItem(httpContext.Session.Id); - + if (sessionItem == null) await logger.ErrorAsync($"AuctionHub.OnConnectedAsync(); (sessionItem == null); connectionId: {connectionId}; sessionId: {httpContext.Session.Id}"); - else sessionItem.SignaRConnectionId = connectionId; + else + { + sessionItem.CustomerId = customer.Id; + sessionItem.SignaRConnectionId = 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 base.OnConnectedAsync(); 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) { - 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 SendMessageWrapperAsync(messageWrapper); } public async Task 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); //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()) { try { 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); 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; } @@ -151,11 +159,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs var productToAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(revertAuctionBidRequest.ProductToAuctionId)); 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; } - 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); if (product == null) @@ -166,7 +174,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs 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); return ResponseType.Error; @@ -174,7 +182,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs var revertLastBid = await auctionService.RevertAuctionBidByProductToAuctionIdAsync(productToAuction.Id); - if (revertLastBid == null) await ResetProductToAuction(productToAuction); + if (revertLastBid == null) await auctionService.ResetProductToAuction(productToAuction); else { productToAuction.BidsCount = await auctionService.GetBidsCountByProductToAuctionIdAsync(productToAuction.Id); @@ -186,7 +194,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs } 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; @@ -203,7 +211,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs 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); if (auction == null || auction.Closed) @@ -223,8 +231,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs var activeProductAuction = (await auctionService.GetProductToAuctionMappingByIdAsync(bidRequestMessage.ProductAuctionMappingId)); if (activeProductAuction is not { IsActiveItem: true } || (activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer))) { - logger.Warning($"AuctionHub.HandleBidRequestAsync(); (activeProductAuction is not {{ IsActiveItem: true }} || activeProductAuction.WinnerCustomerId == customer.Id && !await customerService.IsAdminAsync(customer)); AuctionStatus: {activeProductAuction?.AuctionStatus}; WinnerCustomerId: {activeProductAuction?.WinnerCustomerId}", null, customer); - + 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); return ResponseType.Error; } @@ -242,6 +250,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs } var auctionBid = bidRequestMessage.CreateMainEntity(); + auctionBid.AuctionId = auction.Id; auctionBid.ProductAuctionMappingId = activeProductAuction.Id; await auctionService.InsertBidAsync(auctionBid); @@ -260,7 +269,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs } 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; @@ -272,100 +281,113 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (auctionProductStatusRequest == null) { logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); auctionProductStatusRequest == null", null, customer); - return ResponseType.Error; + return ResponseType.None; } try { //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); - if (productToAuction == null) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (productToAuction == null)", null, customer); - return ResponseType.Error; - } + var (auction, productToAuction, responseType) = await auctionService.GetAndUpdateProductToAuctionStatusIfValidAsync(auctionProductStatusRequest.ProductToAuctionId, auctionProductStatusRequest.AuctionStatus, customer); + if (auction == null || productToAuction == null || responseType == ResponseType.None) return ResponseType.None; - var auction = await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId); - if (auction == null || auction.Closed) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (auction == null || auction.Closed); Closed: {auction?.Closed}", null, customer); - return ResponseType.Error; - } - - if (!IsValidRequestAuctionStatus(auctionProductStatusRequest.AuctionStatus, productToAuction.AuctionStatus)) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); RequestAuctionStatusIsValid() == false; newStatus: {auctionProductStatusRequest.AuctionStatus}; oldStatus: {productToAuction.AuctionStatus}", null, customer); - - await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToCaller); - return ResponseType.Error; - } - else if (auctionProductStatusRequest.AuctionStatus == AuctionStatus.None) await ResetProductToAuction(productToAuction, auction.CategoryId); - else - { - switch (auctionProductStatusRequest.AuctionStatus) - { - case AuctionStatus.Active: - productToAuction.AuctionStatus = AuctionStatus.Active; - await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, true); - break; - - case AuctionStatus.FirstWarning: - case AuctionStatus.SecondWarning: - productToAuction.AuctionStatus = auctionProductStatusRequest.AuctionStatus; - break; - - case AuctionStatus.Sold: - var lastAuctionBid = await auctionService.GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id); - if (lastAuctionBid == null) productToAuction.AuctionStatus = AuctionStatus.NotSold; - else - { - productToAuction.AuctionStatus = AuctionStatus.Sold; - productToAuction.CurrentPrice = lastAuctionBid.BidPrice; - productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId; - - var placeOrderResult = await auctionService.CreateOrderForWinnerAsync(productToAuction); - if (placeOrderResult == null || placeOrderResult.Id == 0) - { - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); (placeOrderResult == null || placeOrderResult.Id == 0)", null, customer); - //return; //TODO: EGYELŐRE HAGYJUK LEZÁRNI AKKOR IS, HA NEM SIKERÜLT AZ ORDERPLACE()! - J. - } - } - - await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, auction.CategoryId, false); - break; - - case AuctionStatus.Pause: - productToAuction.AuctionStatus = AuctionStatus.Pause; - break; - - default: - logger.Error($"AuctionHub.HandleProductToAuctionStatusChangedRequest(); AuctionStatus not found; (auctionProductStatusRequest.AuctionStatus == {auctionProductStatusRequest.AuctionStatus})", null, customer); - - await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToCaller); - return ResponseType.Error; - } - - await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); - } - - await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, ResponseType.ToAllClients); + await SendStatusChangedNotificationAsync(customer, statusChangedMessageWrapper, productToAuction, responseType); //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); return ResponseType.ToAllClients; } 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; } + //private async Task 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) { 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. productToAuction.CurrentPrice = bidPrice; productToAuction.WinnerCustomerId = lastBidCustomerId; - await auctionService.UpdateProductToAuctionMappingAsync(productToAuction); + await auctionService.UpdateProductToAuctionAsync(productToAuction); return true; } @@ -485,35 +507,35 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs }.ToJson(); } - private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null) - { - productToAuction.AuctionStatus = AuctionStatus.None; - await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice); + //private async Task ResetProductToAuction(ProductToAuctionMapping productToAuction, int? categoryId = null) + //{ + // productToAuction.AuctionStatus = AuctionStatus.None; + // await auctionService.ResetProductToAuctionAsync(productToAuction, productToAuction.StartingPrice); - categoryId ??= (await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId; - await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false); - } + // categoryId ??= (await auctionService.GetAuctionByIdAsync(productToAuction.AuctionId))?.CategoryId; + // await UpdateProductCategoryIsFeaturedAsync(productToAuction.ProductId, categoryId, false); + //} - private async Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured) - { - //Leszarjuk ha elszáll, az aukció menjen tovább... - J. - try - { - if (categoryId.GetValueOrDefault(0) == 0) return; + //private async Task UpdateProductCategoryIsFeaturedAsync(int productId, int? categoryId, bool isFeatured) + //{ + // //Leszarjuk ha elszáll, az aukció menjen tovább... - J. + // try + // { + // if (categoryId.GetValueOrDefault(0) == 0) return; - var productCategory = (await categoryService.GetProductCategoriesByProductIdAsync(productId)).FirstOrDefault(x => x.CategoryId == categoryId); - if (productCategory == null) return; + // var productCategory = (await categoryService.GetProductCategoriesByProductIdAsync(productId)).FirstOrDefault(x => x.CategoryId == categoryId); + // if (productCategory == null) return; - if (productCategory.IsFeaturedProduct == isFeatured) 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); - } - } + // productCategory.IsFeaturedProduct = isFeatured; + // await categoryService.UpdateProductCategoryAsync(productCategory); + // } + // catch (Exception ex) + // { + // logger.Error($"AuctionHub.UpdateProductCategoryIsFeaturedAsync(); categoryId: {categoryId}; productId: {productId}; isFeatured: {isFeatured}", ex); + // } + //} public async Task SendAuctionBidMessageAsync(MessageWrapper messageWrapper, ProductToAuctionMapping productToAuction, Product product, int customerId, ResponseType responseType) { @@ -538,16 +560,20 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs if (messageWrapper.HideToaster) await Clients.All.send(messageWrapperJson); else { + //messageWrapperJObject["senderId" /*nameof(MessageWrapper.SenderId)*/] = "-1"; await Clients.Others.send(messageWrapperJson); - + var messageWrapperJObject = JObject.Parse(messageWrapperJson); messageWrapperJObject["hideToaster" /*nameof(MessageWrapper.HideToaster)*/] = "true"; - + await Clients.Caller.send(messageWrapperJObject.ToString(Formatting.None)); } break; case ResponseType.Error: + messageWrapper.HideToaster = false; + await Clients.Caller.send(messageWrapper.ToJson()); + break; default: throw new ArgumentOutOfRangeException(); @@ -560,35 +586,33 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs // else await Clients.All.send(messageWrapper.ToJson()); //} - private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus) - { - switch (oldStatus) - { - case AuctionStatus.None: - return newStatus is AuctionStatus.Active or AuctionStatus.Pause; - case AuctionStatus.Active: - return newStatus is AuctionStatus.FirstWarning or AuctionStatus.Pause; - case AuctionStatus.FirstWarning: - return newStatus is AuctionStatus.SecondWarning or AuctionStatus.Pause; - case AuctionStatus.SecondWarning: - return newStatus is AuctionStatus.Sold or AuctionStatus.Pause; - case AuctionStatus.Pause: - return newStatus is AuctionStatus.None or AuctionStatus.Active; - case AuctionStatus.Sold: - case AuctionStatus.NotSold: - default: - return false; - } - } + //private static bool IsValidRequestAuctionStatus(AuctionStatus newStatus, AuctionStatus oldStatus) + //{ + // switch (oldStatus) + // { + // case AuctionStatus.None: + // return newStatus is AuctionStatus.Active or AuctionStatus.Pause; + // case AuctionStatus.Active: + // return newStatus is AuctionStatus.FirstWarning or AuctionStatus.Pause; + // case AuctionStatus.FirstWarning: + // return newStatus is AuctionStatus.SecondWarning or AuctionStatus.Pause; + // case AuctionStatus.SecondWarning: + // return newStatus is AuctionStatus.Sold or AuctionStatus.Pause; + // case AuctionStatus.Pause: + // return newStatus is AuctionStatus.None or AuctionStatus.Active; + // case AuctionStatus.Sold: + // case AuctionStatus.NotSold: + // default: + // return false; + // } + //} - private SessionItem IncrementRequestCount() + private bool TryGetCurrentSessionItem(out SessionItem sessionItem) { - SessionItem sessionItem = null; + sessionItem = null; var httpContext = Context.GetHttpContext(); - if (httpContext != null && sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem)) sessionItem.RequestCount++; - - return sessionItem; + return httpContext != null && sessionService.TryGetSessionItem(httpContext.Session.Id, out sessionItem); } } } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs index 1f7a2a8..026f958 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs @@ -52,11 +52,6 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(10); }); - //register services and interfaces - //IRepository _customerBidRepository; - //protected readonly IShortTermCacheManager _shortTermCacheManager; - // protected readonly IStaticCacheManager _staticCacheManager; - services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -72,13 +67,15 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure services.AddScoped(); services.AddScoped(); - services.AddScoped(); - //services.AddScoped(); + services.AddScoped(); //TODO: ez mi? - J. + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); + + services.AddHostedService(); } /// diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs new file mode 100644 index 0000000..9966f72 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs @@ -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 _auctionHubContext; + private readonly ILockService _lockService; + + private readonly AuctionService _auctionService; + private readonly Customer _auctionSystemCustomer; + + public AuctionBackgroundService(ILogger logger, IServiceProvider service, IHubContext auctionHubContext, AuctionService auctionService, ILockService lockService, IRepository 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(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); + } + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs index 06f8c56..a096e81 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs @@ -22,6 +22,7 @@ using Nop.Services.Common; using Nop.Services.Customers; using Nop.Services.Shipping; using NUglify.Helpers; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces; namespace Nop.Plugin.Misc.AuctionPlugin.Services; @@ -39,8 +40,144 @@ public class AuctionService( IAddressService addressService, ICustomerService customerService, IOrderService orderService, - ILogger logger) : IAuctionService + ILogger logger, + ICategoryService categoryService) : IAuctionService { + #region AuctionHub + + public async Task 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 public static decimal GetStepAmount(decimal currentPrice) @@ -103,29 +240,35 @@ public class AuctionService( public Task ResetProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0) => ctx.ResetProductToAuctionAsync(productToAuction, basePrice); - public Task GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId) - => ctx.GetLastAuctionBidByProductToAuctionId(productToAuctionId); + public Task> GetAllLastBidByAuctionIdAsync(int auctionId) + => ctx.GetAllLastBidByAuctionIdAsync(auctionId); - public Task GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) - => ctx.GetBidsCountByProductToAuctionIdAsync(productToAuctionId); + public Task> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId) + => ctx.GetAllLastBidDictionaryByAuctionIdAsync(auctionId); - public Task HasBidByProductToAuctionIdAsync(int productToAuctionId) - => ctx.HasBidByProductToAuctionIdAsync(productToAuctionId); + public Task GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId) + => ctx.GetLastAuctionBidByProductToAuctionId(productToAuctionId); - public Task RevertAuctionBidByProductToAuctionIdAsync(int productToAuctionId) - => ctx.RevertAuctionBidByProductToAuctionId(productToAuctionId); + public Task GetBidsCountByProductToAuctionIdAsync(int productToAuctionId) + => ctx.GetBidsCountByProductToAuctionIdAsync(productToAuctionId); - public async Task GetProductById(int productId) - { - var product = await productService.GetProductByIdAsync(productId); - if (product != null) return product; + public Task HasBidByProductToAuctionIdAsync(int productToAuctionId) + => ctx.HasBidByProductToAuctionIdAsync(productToAuctionId); - logger.Error($"AuctionService.GetProductById(); (product == null)", null, await workContext.GetCurrentCustomerAsync()); - return null; + public Task RevertAuctionBidByProductToAuctionIdAsync(int productToAuctionId) + => ctx.RevertAuctionBidByProductToAuctionId(productToAuctionId); - } + public async Task GetProductById(int productId) + { + var product = await productService.GetProductByIdAsync(productId); + if (product != null) return product; - /// + logger.Error($"AuctionService.GetProductById(); (product == null)", null, await workContext.GetCurrentCustomerAsync()); + return null; + + } + + /// /// Gets all bids /// /// The store identifier; pass 0 to load all records @@ -258,7 +401,7 @@ public class AuctionService( var winnerCustomer = await customerService.GetCustomerByIdAsync(productToAuction.WinnerCustomerId); var storeId = winnerCustomer.RegisteredInStoreId; - + var billingAddress = await InsertOrUpdateBillingAddressAsync(winnerCustomer); if (billingAddress == null) { @@ -386,6 +529,7 @@ public class AuctionService( } #region auctions + public async Task InsertAuctionAsync(Auction auction) { await ctx.Auctions.InsertAsync(auction, false); @@ -396,19 +540,20 @@ public class AuctionService( await ctx.Auctions.UpdateAsync(auction); } - public Task> GetAllAuctionsAsync() =>ctx.Auctions.GetAllAuctions().ToListAsync(); - public Task> GetAllCurrentAutoOpenAndClosedAuctionsAsync() =>ctx.Auctions.GetAllCurrentAutoOpenAndClosedAuctions().ToListAsync(); + public Task> GetAllAuctionsAsync() => ctx.Auctions.GetAllAuctions().ToListAsync(); + public Task> GetAllCurrentAutoOpenAndClosedAuctionsAsync() => ctx.Auctions.GetAllCurrentAutoOpenAndClosedAuctions().ToListAsync(); public async Task> GetProductToAuctionsByAuctionIdAsync(int auctionId, bool onlyActiveItems) => await ctx.ProductToAuctions.GetProductToAuctionsByAuctionId(auctionId, onlyActiveItems).OrderBy(x => x.SortIndex).ToListAsync(); - - public Task GetNextProductToAuctionByAuctionIdAsync(int auctionId) + + public Task GetNextProductToAuctionByAuctionIdAsync(int auctionId) => ctx.ProductToAuctions.GetNextItemByAuctionIdAsync(auctionId); public Task> GetNotClosedProductToAuctionsByAuctionId(int auctionId) => ctx.ProductToAuctions.GetNotClosedItemsByAuctionId(auctionId).OrderBy(x => x.SortIndex).ToListAsync(); #endregion + #endregion #region Dtos @@ -420,7 +565,7 @@ public class AuctionService( 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; @@ -435,7 +580,7 @@ public class AuctionService( var auctionDto = new AuctionDto(auction); if (widthProducts) auctionDto.ProductToAuctionDtos.AddRange((await GetProductToAuctionDtosByAuctionId(auctionId, activeProductOnly))); - + return auctionDto; } @@ -474,22 +619,22 @@ public class AuctionService( public async Task> 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 GetAuctionBidDtoByIdAsync(int auctionBidId) { var auctionBid = await ctx.AuctionBids.GetByIdAsync(auctionBidId); - + return auctionBid == null ? null : new AuctionBidDto(auctionBid); } - public Task> GetProductToAuctionsByProductIdAsync(int productId) + public Task> GetProductToAuctionsByProductIdAsync(int productId) => ctx.GetProductToAuctionsByProductIdAsync(productId); public Task> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly) => ctx.GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, activeProductOnly); - + public async Task AssignProductToAuctionAsync(int productId, decimal startingPrice, decimal bidPrice, int auctionId) { @@ -528,12 +673,12 @@ public class AuctionService( return await ctx.ProductToAuctions.GetByIdAsync(productToAuctionMappingId); } - public async Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping) + public async Task UpdateProductToAuctionAsync(ProductToAuctionMapping productToAuctionMapping) { await ctx.ProductToAuctions.UpdateAsync(productToAuctionMapping); } - public async Task UpdateProductToAuctionMappingAsync(IList productToAuctionMappings) + public async Task UpdateProductToAuctionAsync(IList productToAuctionMappings) { await ctx.ProductToAuctions.UpdateAsync(productToAuctionMappings); } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs index a65c1be..0e75c90 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs @@ -1,9 +1,11 @@ using Microsoft.AspNetCore.Mvc; using Nop.Core; +using Nop.Core.Domain.Customers; using Nop.Core.Domain.Orders; using Nop.Plugin.Misc.AuctionPlugin.Domains; using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Services.Orders; namespace Nop.Plugin.Misc.AuctionPlugin.Services; @@ -14,7 +16,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services; public interface IAuctionService { //decimal GetStepAmount(decimal currentPrice); - + Task 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); /// /// Gets all bids @@ -29,6 +35,8 @@ public interface IAuctionService Task> GetAllBidsAsync(int customerId = 0, int pageIndex = 0, int pageSize = int.MaxValue); Task GetBidsCountByProductToAuctionIdAsync(int productToAuctionId); + Task> GetAllLastBidByAuctionIdAsync(int auctionId); + Task> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId); Task HasBidByProductToAuctionIdAsync(int productToAuctionId); Task GetBidByIdAsync(int bidId); @@ -65,8 +73,8 @@ public interface IAuctionService Task> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly); Task GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId); - Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping); - Task UpdateProductToAuctionMappingAsync(IList productToAuctionMappings); + Task UpdateProductToAuctionAsync(ProductToAuctionMapping productToAuctionMapping); + Task UpdateProductToAuctionAsync(IList productToAuctionMappings); Task CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuctionMapping); } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs index 213a488..bb7083d 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionItem.cs @@ -4,5 +4,5 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services; public interface ISessionItem : IMgSessionItem { - + int CustomerId { get; set; } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs index 3f72369..e5c92bb 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/ISessionService.cs @@ -4,5 +4,5 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services; public interface ISessionService : IMgSessionService { - + bool TryGetSessionItemByCustomerId(int customerId, out SessionItem sessionItem); } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs index 737cfbd..3db6b2c 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionItem.cs @@ -4,5 +4,5 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Services; public class SessionItem(string sessionKey) : MgSessionItem(sessionKey), ISessionItem { - + public int CustomerId { get; set; } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs index 374ed63..f73533c 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/SessionService.cs @@ -1,8 +1,13 @@ using Mango.Nop.Services; +using Nop.Core.Domain.Customers; namespace Nop.Plugin.Misc.AuctionPlugin.Services; public class SessionService : MgSessionService, ISessionService { - + public bool TryGetSessionItemByCustomerId(int customerId, out SessionItem sessionItem) + { + sessionItem = Sessions.Values.FirstOrDefault(x => x.CustomerId == customerId); + return sessionItem != null; + } } \ No newline at end of file