diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbContext.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/AuctionDbContext.cs index cb0254b..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); } @@ -45,7 +45,8 @@ public class AuctionDbContext : MgDbContextBase, IAuctionDbSet, //} public Task> GetAllLastBidByAuctionIdAsync(int auctionId) => AuctionBids.GetAllLastBidByAuctionId(auctionId).ToListAsync(); - public Task> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId) + + public Task> GetAllLastBidDictionaryByAuctionIdAsync(int auctionId) => AuctionBids.GetAllLastBidByAuctionId(auctionId).ToDictionaryAsync(x => x.ProductAuctionMappingId); public async Task> GetProductToAuctionsByProductIdAsync(int productId) @@ -65,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/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 c9e829c..bb3b24f 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -159,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) @@ -174,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; @@ -194,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; @@ -211,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) @@ -231,7 +231,7 @@ 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; @@ -250,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); @@ -268,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; @@ -286,7 +287,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs 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 (auction, productToAuction, responseType) = await auctionService.GetAndUpdateProductToAuctionStatusIfValidAsync(auctionProductStatusRequest.ProductToAuctionId, auctionProductStatusRequest.AuctionStatus, customer); if (auction == null || productToAuction == null || responseType == ResponseType.None) return ResponseType.None; @@ -301,7 +302,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs } 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; @@ -423,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; } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs index e9475a4..9966f72 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionBackgroundService.cs @@ -7,16 +7,20 @@ 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; @@ -40,7 +44,7 @@ public class AuctionBackgroundService : MgBackgroundServiceBase protected override async Task OnExecuteAsync() { - await Task.Delay(15000); //Az elejére kell tenni! ha exception lenne, akkor ne kezdje el darálni... - J. + 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; @@ -50,49 +54,115 @@ public class AuctionBackgroundService : MgBackgroundServiceBase { await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); Enter lock;", null, _auctionSystemCustomer); - var auctions = await _auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); - if (auctions.Count > 0) + var currentAutomaticAuctions = await _auctionService.GetAllCurrentAutoOpenAndClosedAuctionsAsync(); + if (currentAutomaticAuctions.Count > 0) { - await _logger.InformationAsync($"AuctionBackgroundService.OnExecuteAsync(); auctions.Count > 0; count: {auctions.Count}; names: {string.Join("; ", auctions.Select(x => x.AuctionName))}", null, _auctionSystemCustomer); + 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, + SenderId = _auctionSystemCustomer.Id, //TODO: -1; - J. ResponseType = ResponseType.ToAllClients }; - foreach (var auction in auctions) + foreach (var automaticAuction in currentAutomaticAuctions) { - 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(); - - if (productToAuctions.Count == 0) continue; - - var allLastBidbyPtaId = await _auctionService.GetAllLastBidDictionaryByAuctionIdAsync(auction.Id); - - foreach (var productToAuction in productToAuctions) - { - allLastBidbyPtaId.TryGetValue(productToAuction.Id, out var lastBid); - - var responseType = await _auctionService.UpdateProductToAuctionStatusIfValidAsync(AuctionStatus.Active, auction, productToAuction, _auctionSystemCustomer, false); - - if (responseType != ResponseType.None) - auctionDto.ProductToAuctionDtos.Add(new ProductToAuctionDto(productToAuction)); - } - - 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()); + 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 _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 f142270..a096e81 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs @@ -68,10 +68,11 @@ public class AuctionService( case AuctionStatus.SecondWarning: productToAuction.AuctionStatus = newProductToAuctionStatus; break; - + case AuctionStatus.Sold: + case AuctionStatus.NotSold: var lastAuctionBid = await GetLastAuctionBidByProductToAuctionIdAsync(productToAuction.Id); - if (lastAuctionBid == null) productToAuction.AuctionStatus = AuctionStatus.NotSold; + if (lastAuctionBid == null || lastAuctionBid.BidPrice < productToAuction.MinimumPrice) productToAuction.AuctionStatus = AuctionStatus.NotSold; else { productToAuction.AuctionStatus = AuctionStatus.Sold; @@ -95,12 +96,11 @@ public class AuctionService( default: logger.Error($"AuctionHub.UpdateProductToAuctionStatusIfValidAsync(); AuctionStatus not found; (newStatus == {newProductToAuctionStatus})", null, customer); - return ResponseType.ToCaller; } if (updateInDatabase) - await UpdateProductToAuctionMappingAsync(productToAuction); + await UpdateProductToAuctionAsync(productToAuction); } return ResponseType.ToAllClients; @@ -673,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 05dfa1c..0e75c90 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs @@ -73,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