362 lines
14 KiB
C#
362 lines
14 KiB
C#
using Nop.Core;
|
||
using Nop.Core.Caching;
|
||
using Nop.Core.Domain.Catalog;
|
||
using Nop.Core.Domain.Customers;
|
||
using Nop.Core.Domain.Orders;
|
||
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.Messages;
|
||
using Nop.Services.Catalog;
|
||
using Nop.Services.Logging;
|
||
using Nop.Services.Orders;
|
||
using Nop.Services.Payments;
|
||
using Org.BouncyCastle.Crypto;
|
||
|
||
namespace Nop.Plugin.Misc.AuctionPlugin.Services;
|
||
|
||
/// <summary>
|
||
/// Store pickup point service
|
||
/// </summary>
|
||
public class AuctionService : IAuctionService
|
||
{
|
||
#region Fields
|
||
|
||
private readonly AuctionDbContext _ctx;
|
||
private readonly IProductService _productService;
|
||
private readonly IWorkContext _workContext;
|
||
private readonly IOrderProcessingService _orderProcessingService;
|
||
private readonly ILogger _logger;
|
||
#endregion
|
||
|
||
#region Ctor
|
||
|
||
/// <summary>
|
||
/// Ctor
|
||
/// </summary>
|
||
/// <param name="ctx"></param>
|
||
/// <param name="productService"></param>
|
||
/// <param name="workContext"></param>
|
||
/// <param name="logger"></param>
|
||
public AuctionService(AuctionDbContext ctx, IProductService productService, IWorkContext workContext, IOrderProcessingService orderProcessingService, ILogger logger)
|
||
{
|
||
_ctx = ctx;
|
||
_productService = productService;
|
||
_workContext = workContext;
|
||
_orderProcessingService = orderProcessingService;
|
||
_logger = logger;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Methods
|
||
|
||
public static decimal GetStepAmount(decimal currentPrice)
|
||
{
|
||
return currentPrice switch
|
||
{
|
||
>= 0 and < 100000 => 10000,
|
||
|
||
//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<bool> 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 ResetProductToAuctionByProductId(int productId)
|
||
=> await ResetProductToAuctionAsync(await _ctx.ProductToAuctions.GetByProductId(productId).FirstOrDefaultAsync());
|
||
|
||
public Task ResetProductToAuctionByIdAsync(int productToAuctionId, decimal basePrice = 0)
|
||
=> ResetProductToAuctionAsync(_ctx.ProductToAuctions.GetById(productToAuctionId), basePrice);
|
||
|
||
public Task ResetProductToAuctionAsync(ProductToAuctionMapping productToAuction, decimal basePrice = 0)
|
||
=> _ctx.ResetProductToAuctionAsync(productToAuction, basePrice);
|
||
|
||
public Task<AuctionBid> GetLastAuctionBidByProductToAuctionIdAsync(int productToAuctionId)
|
||
=> _ctx.GetLastAuctionBidByProductToAuctionId(productToAuctionId);
|
||
|
||
public Task<AuctionBid> RevertAuctionBidByProductToAuctionIdAsync(int productToAuctionId)
|
||
=> _ctx.RevertAuctionBidByProductToAuctionId(productToAuctionId);
|
||
|
||
public async Task<Product> GetProductById(int productId)
|
||
{
|
||
var product = await _productService.GetProductByIdAsync(productId);
|
||
if (product != null) return product;
|
||
|
||
_logger.Error($"AuctionService.GetProductById(); (product == null)", null, await _workContext.GetCurrentCustomerAsync());
|
||
return null;
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets all bids
|
||
/// </summary>
|
||
/// <param name="customerId">The store identifier; pass 0 to load all records</param>
|
||
/// <param name="pageIndex">Page index</param>
|
||
/// <param name="pageSize">Page size</param>
|
||
/// <returns>
|
||
/// A task that represents the asynchronous operation
|
||
/// The task result contains the bids
|
||
/// </returns>
|
||
public async Task<IPagedList<AuctionBid>> GetAllBidsAsync(int customerId = 0, int pageIndex = 0, int pageSize = int.MaxValue)
|
||
{
|
||
//TODO: megcsinálni! - J.
|
||
|
||
var rez = new List<AuctionBid>();
|
||
//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<AuctionBid>(rez, pageIndex, pageSize);
|
||
}
|
||
|
||
public async Task<AuctionBid> 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);
|
||
}
|
||
}
|
||
|
||
public async Task UpdateBidAsync(AuctionBid auctionBid)
|
||
{
|
||
if (await ValidateAuctionBid(auctionBid))
|
||
{
|
||
await _ctx.AuctionBids.UpdateAsync(auctionBid, false);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Deletes a pickup point
|
||
/// </summary>
|
||
/// <param name="pickupPoint">Pickup point</param>
|
||
/// <returns>A task that represents the asynchronous operation</returns>
|
||
public async Task DeleteBidAsync(AuctionBid pickupPoint)
|
||
{
|
||
await _ctx.AuctionBids.DeleteAsync(pickupPoint, false);
|
||
}
|
||
|
||
public async Task<PlaceOrderResult> CreateOrderForWinnerAsync(ProductToAuctionMapping auctionItem)
|
||
{
|
||
if (auctionItem is not { AuctionStatus: AuctionStatus.Sold })
|
||
{
|
||
await _logger.InformationAsync($"AuctionService.CreateOrderForWinnerAsync(); (auctionItem is not {{ AuctionStatus: AuctionStatus.Sold }}); auctionItemId: {auctionItem?.Id}; status: {auctionItem?.AuctionStatus}");
|
||
return null;
|
||
}
|
||
|
||
try
|
||
{
|
||
var processPaymentRequest = new ProcessPaymentRequest();
|
||
processPaymentRequest.CustomerId = auctionItem.WinnerCustomerId;
|
||
processPaymentRequest.CustomValues.Add("ProductToAuctionMappingId", auctionItem.Id);
|
||
processPaymentRequest.OrderTotal = auctionItem.CurrentPrice;
|
||
|
||
//processPaymentRequest.OrderGuid = productToAuction.OrderGuid; //TODO: - J.
|
||
processPaymentRequest.OrderGuid = Guid.NewGuid();
|
||
|
||
var placeOrderResult = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);
|
||
//placeOrderResult.PlacedOrder //TODO:... - J.
|
||
|
||
return placeOrderResult.Success ? placeOrderResult : null;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.Error($"AuctionService.CreateOrderForWinnerAsync(); Exception; auctionItemId: {auctionItem.Id}", ex);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
#region auctions
|
||
public async Task InsertAuctionAsync(Auction auction)
|
||
{
|
||
await _ctx.Auctions.InsertAsync(auction, false);
|
||
}
|
||
|
||
public async Task UpdateAuctionAsync(Auction auction)
|
||
{
|
||
await _ctx.Auctions.UpdateAsync(auction);
|
||
}
|
||
|
||
public async Task<IList<Auction>> GetAllAuctionsAsync()
|
||
{
|
||
return await _ctx.Auctions.GetAllAuctionsAsync();
|
||
}
|
||
|
||
public async Task<List<ProductToAuctionMapping>> GetProductToAuctionsByAuctionIdAsync(int auctionId, bool onlyActiveItems)
|
||
{
|
||
return await _ctx.ProductToAuctions.GetProductToAuctionsByAuctionId(auctionId, onlyActiveItems).ToListAsync();
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
#region Dtos
|
||
|
||
public async Task<AuctionDto> GetAuctionDtoWithAuctionBids(int auctionId, bool activeProductOnly)
|
||
{
|
||
var auctionDto = await GetAuctionDtoByIdAsync(auctionId, true, activeProductOnly);
|
||
if (auctionDto == null) return null;
|
||
|
||
foreach (var auctionDtoProductToAuctionDto in auctionDto.ProductToAuctionDtos)
|
||
{
|
||
auctionDtoProductToAuctionDto.AuctionBidDtos.AddRange(await _ctx.AuctionBids.GetByProductToAuctionId(auctionDtoProductToAuctionDto.Id).OrderByDescending(x => x.Id).Select(x => new AuctionBidDto(x)).ToListAsync());
|
||
}
|
||
|
||
return auctionDto;
|
||
}
|
||
|
||
public async Task<AuctionDto> 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<List<ProductToAuctionDto>> GetProductToAuctionDtosByAuctionId(int auctionId, bool activeProductOnly)
|
||
{
|
||
return (await GetProductToAuctionsByAuctionIdAsync(auctionId, activeProductOnly)).Select(x => new ProductToAuctionDto(x)).ToList();
|
||
}
|
||
|
||
public async Task<AuctionDto> 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<ProductToAuctionDto> GetProductToAuctionDtoByIdAsync(int productToAuctionId)
|
||
{
|
||
var productToAuction = await _ctx.ProductToAuctions.GetByIdAsync(productToAuctionId);
|
||
return productToAuction == null ? null : new ProductToAuctionDto(productToAuction);
|
||
}
|
||
|
||
public async Task<AuctionDto> GetAuctionDtoByProductToAuctionIdAsync(int productToAuctionId, bool includeProductToAuctionDto)
|
||
{
|
||
var productTouctionDto = await GetProductToAuctionDtoByIdAsync(productToAuctionId);
|
||
if (productTouctionDto == null) return null;
|
||
|
||
var auctionDto = await GetAuctionDtoByIdAsync(productTouctionDto.AuctionId, false, false);
|
||
|
||
if (includeProductToAuctionDto) auctionDto.ProductToAuctionDtos.Add(productTouctionDto);
|
||
return auctionDto;
|
||
}
|
||
|
||
public async Task<List<ProductToAuctionDto>> GetProductToAuctionDtosByProductIdAsync(int productId)
|
||
{
|
||
return [..await _ctx.ProductToAuctions.GetByProductId(productId).Select(x=>new ProductToAuctionDto(x)).ToListAsync()];
|
||
}
|
||
|
||
public async Task<AuctionBidDto> GetAuctionBidDtoByIdAsync(int auctionBidId)
|
||
{
|
||
var auctionBid = await _ctx.AuctionBids.GetByIdAsync(auctionBidId);
|
||
|
||
return auctionBid == null ? null : new AuctionBidDto(auctionBid);
|
||
}
|
||
|
||
public Task<List<ProductToAuctionMapping>> GetProductToAuctionsByProductIdAsync(int productId)
|
||
=> _ctx.GetProductToAuctionsByProductIdAsync(productId);
|
||
|
||
public Task<List<ProductToAuctionMapping>> GetProductToAuctionByAuctionIdAndProductIdAsync(int auctionId, int productId, bool activeProductOnly)
|
||
=> _ctx.GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productId, activeProductOnly);
|
||
|
||
|
||
public async Task<ProductToAuctionMapping> 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<ProductToAuctionMapping> GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId)
|
||
{
|
||
return await _ctx.ProductToAuctions.GetByIdAsync(productToAuctionMappingId);
|
||
}
|
||
|
||
public async Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping)
|
||
{
|
||
await _ctx.ProductToAuctions.UpdateAsync(productToAuctionMapping);
|
||
}
|
||
|
||
#endregion Dtos
|
||
} |