using Nop.Core; using Nop.Core.Caching; using Nop.Core.Domain.Catalog; 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.Services.Catalog; using Nop.Services.Logging; using Org.BouncyCastle.Crypto; namespace Nop.Plugin.Misc.AuctionPlugin.Services; /// /// Store pickup point service /// public class AuctionService : IAuctionService { #region Constants /// /// Cache key for pickup points /// /// /// {0} : current store ID /// private readonly CacheKey _auctionAllKey = new("Nop.auction.all-{0}", AUCTION_PATTERN_KEY); //nem ezt használjuk a kódban, nem gond?! - J. private const string AUCTION_PATTERN_KEY = "Nop.auction."; #endregion #region Fields private readonly AuctionDbContext _ctx; private readonly IProductService _productService; private readonly IShortTermCacheManager _shortTermCacheManager; private readonly IStaticCacheManager _staticCacheManager; private readonly IWorkContext _workContext; private readonly ILogger _logger; #endregion #region Ctor /// /// Ctor /// /// /// Short term cache manager /// Cache manager /// /// public AuctionService( AuctionDbContext ctx, IProductService productService, //IRepository auctionRepository, //IRepository productToAuctionRepository, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, IWorkContext workContext, ILogger logger) { _ctx = ctx; _productService = productService; //_customerBidRepository = customerBidRepository; //_auctionRepository = auctionRepository; //_productToAuctionRepository = productToAuctionRepository; _shortTermCacheManager = shortTermCacheManager; _staticCacheManager = staticCacheManager; _workContext = workContext; _logger = logger; } #endregion #region Methods public static decimal GetStepAmount(decimal currentPrice) { return currentPrice switch { >= 0 and < 100000 => 10000, //Ezt csak hasraütésszerűen adtam meg!!! - J. //100 000 - 1 000 000 >= 100000 and < 200000 => 10000, >= 200000 and < 500000 => 20000, >= 500000 and < 1000000 => 50000, //1 000 000 - 10 000 000 >= 1000000 and < 2000000 => 100000, >= 2000000 and < 5000000 => 200000, >= 5000000 and < 10000000 => 500000, //10 000 000 - 100 000 000 >= 10000000 and < 20000000 => 1000000, >= 20000000 and < 50000000 => 2000000, >= 50000000 and < 100000000 => 5000000, //100 000 000 - ~ >= 100000000 and < 200000000 => 10000000, _ => 20000000 }; //100 000 Ft – 200 000 Ft között 10 000 Ft-tal //200 000 Ft – 500 000 Ft között 20 000 Ft-tal //500 000 Ft – 1 000 000 Ft között 50 000 Ft-tal //1 000 000 Ft – 2 000 000 Ft között 100 000 Ft-tal //2 000 000 Ft – 5 000 000 Ft között 200 000 Ft-tal //5 000 000 Ft – 10 000 000 Ft között 500 000 Ft-tal //10 000 000 Ft – 20 000 000 Ft között 1 000 000 Ft-tal //20 000 000 Ft – 50 000 000 Ft között 2 000 000 Ft-tal //50 000 000 Ft – 100 000 000 Ft között 5 000 000 Ft-tal //100 000 000 Ft – 200 000 000 Ft között 10 000 000 Ft-tal //200 000 000 Ft fölött 20 000 000 Ft-tal } private async Task ValidateAuctionBid(AuctionBid auctionBid) { //auctionBid.CustomerId = (await _workContext.GetCurrentCustomerAsync()).Id; //elvileg megnézi cache-ben, csak utána DB-zik! - J. //etc... return true; } public async Task DeactivateProductToAuctionByProductId(int productId) => await DeactivateProductToAuctionAsync(await _ctx.ProductToAuctions.GetByProductId(productId).FirstOrDefaultAsync()); public async Task DeactivateProductToAuctionByIdAsync(int productToAuctionId, decimal basePrice = 0) => await DeactivateProductToAuctionAsync(_ctx.ProductToAuctions.GetById(productToAuctionId), basePrice); public async Task DeactivateProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0) { if (basePrice <= 0) { var product = await _productService.GetProductByIdAsync(productToAuction.ProductId); if (product == null) _logger.Error($"AuctionService.DeactivateProductToAuctionByIdAsync(); product == null"); else basePrice = product.Price; } await _ctx.ProductToAuctions.DeactivateItem(productToAuction, basePrice); } public Task GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId) => _ctx.AuctionBids.GetLastAuctionBidByProductToAuctionIdAsync(productToAuctionId); /// /// Gets all bids /// /// The store identifier; pass 0 to load all records /// Page index /// Page size /// /// A task that represents the asynchronous operation /// The task result contains the bids /// public async Task> GetAllBidsAsync(int customerId = 0, int pageIndex = 0, int pageSize = int.MaxValue) { //TODO: megcsinálni! - J. var rez = new List(); //var rez = await _shortTermCacheManager.GetAsync(async () => await _customerBidRepository.GetAllAsync(query => //{ // if (customerId > 0) // query = query.Where(bid => bid.CustomerId == customerId || bid.CustomerId == 0); // query = query.OrderBy(bid => bid.CreateDate).ThenBy(bid => bid.ProductId); // return query; //}), _pickupPointAllKey, customerId); return new PagedList(rez, pageIndex, pageSize); } public async Task GetBidByIdAsync(int bidId) { return await _ctx.AuctionBids.GetByIdAsync(bidId); } public async Task InsertBidAsync(AuctionBid auctionBid) { if (await ValidateAuctionBid(auctionBid)) { await _ctx.AuctionBids.InsertAsync(auctionBid, false); await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } } public async Task UpdateBidAsync(AuctionBid auctionBid) { if (await ValidateAuctionBid(auctionBid)) { await _ctx.AuctionBids.UpdateAsync(auctionBid, false); await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } } /// /// Deletes a pickup point /// /// Pickup point /// A task that represents the asynchronous operation public async Task DeleteBidAsync(AuctionBid pickupPoint) { await _ctx.AuctionBids.DeleteAsync(pickupPoint, false); await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } #region auctions public async Task InsertAuctionAsync(Auction auction) { await _ctx.Auctions.InsertAsync(auction, false); await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } public async Task UpdateAuctionAsync(Auction auction) { await _ctx.Auctions.UpdateAsync(auction); await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } public async Task> GetAllAuctionsAsync() { return await _ctx.Auctions.GetAllAuctionsAsync(); } public async Task> GetProductToAuctionsByAuctionIdAsync(int auctionId, bool onlyActiveItems) { return await _ctx.ProductToAuctions.GetProductToAuctionsByAuctionId(auctionId, onlyActiveItems).ToListAsync(); } #endregion #endregion #region Dtos public async Task GetAuctionDtoWithAuctionBids(int auctionId, bool activeProductOnly) { var auctionDto = await GetAuctionDtoByIdAsync(auctionId, true, activeProductOnly); foreach (var auctionDtoProductToAuctionDto in auctionDto.ProductToAuctionDtos) { auctionDtoProductToAuctionDto.AuctionBidDtos.AddRange(await _ctx.AuctionBids.GetByProductToAuctionIdAsync(auctionDtoProductToAuctionDto.Id).OrderByDescending(x => x.Id).Select(x => new AuctionBidDto(x)).ToListAsync()); } return auctionDto; } public async Task GetAuctionDtoByIdAsync(int auctionId, bool widthProducts, bool activeProductOnly) { var auction = await _ctx.Auctions.GetByIdAsync(auctionId); if (auction == null) return null; var auctionDto = new AuctionDto(auction); if (widthProducts) auctionDto.ProductToAuctionDtos.AddRange((await GetProductToAuctionDtosByAuctionId(auctionId, activeProductOnly))); return auctionDto; } public async Task> GetProductToAuctionDtosByAuctionId(int auctionId, bool activeProductOnly) { return (await GetProductToAuctionsByAuctionIdAsync(auctionId, activeProductOnly)).Select(x => new ProductToAuctionDto(x)).ToList(); } public async Task GetAuctionDtoWithProductByIdAsync(int auctionId, int productId, bool activeProductOnly) { var auction = await _ctx.Auctions.GetByIdAsync(auctionId); if (auction == null) return null; var auctionDto = new AuctionDto(auction); auctionDto.ProductToAuctionDtos.AddRange((await GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, activeProductOnly)).Select(x => new ProductToAuctionDto(x))); return auctionDto; } public async Task GetProductToAuctionDtoByIdAsync(int productToAuctionId) { var productToAuction = await _ctx.ProductToAuctions.GetByIdAsync(productToAuctionId); return productToAuction == null ? null : new ProductToAuctionDto(productToAuction); } public async Task GetAuctionDtoByProductToAuctionIdAsync(int productToAuctionId, bool includeProductToAuctionDto) { var productTouctionDto = await GetProductToAuctionDtoByIdAsync(productToAuctionId); if (productTouctionDto == null) return null; var auctionDto = await GetAuctionDtoByIdAsync(productTouctionDto.AuctionId, false, false); //Ez sosem lehet null! - J. if (includeProductToAuctionDto) auctionDto.ProductToAuctionDtos.Add(productTouctionDto); return auctionDto; } public async Task> GetProductToAuctionDtosByProductIdAsync(int productId) { 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 async Task> GetProductToAuctionsByProductIdAsync(int productId) { return [..await _ctx.ProductToAuctions.GetByProductId(productId).ToListAsync()]; } public async Task> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly) { return [..await _ctx.ProductToAuctions.GetByAuctionAndProductId(auctionId, productId, activeProductOnly).ToListAsync()]; } public async Task AssignProductToAuctionAsync(int productId, decimal startingPrice, decimal bidPrice, int auctionId) { var auction = await GetAuctionDtoByIdAsync(auctionId, false, false); if (auction == null) return null; var existedProductToAuction = (await GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, false)).FirstOrDefault(); if (existedProductToAuction != null) return existedProductToAuction; var mapping = new ProductToAuctionMapping { ProductId = productId, StartingPrice = startingPrice, CurrentPrice = bidPrice, ProductAmount = 1, AuctionStatus = AuctionStatus.None, AuctionId = auctionId }; try { await _ctx.ProductToAuctions.InsertAsync(mapping); } catch (Exception ex) { await _logger.InformationAsync(ex.ToString()); } return mapping; } public async Task GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId) { return await _ctx.ProductToAuctions.GetByIdAsync(productToAuctionMappingId); } public async Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping) { await _ctx.ProductToAuctions.UpdateAsync(productToAuctionMapping); await _staticCacheManager.RemoveByPrefixAsync(AUCTION_PATTERN_KEY); } #endregion Dtos }