Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/Services/CustomPriceCalculationServi...

156 lines
7.2 KiB
C#

using AyCode.Core.Loggers;
using AyCode.Entities;
using FruitBank.Common.Dtos;
using Mango.Nop.Core.Loggers;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Directory;
using Nop.Core.Domain.Discounts;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Stores;
using Nop.Data;
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
using Nop.Services.Catalog;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Discounts;
using Nop.Services.Localization;
namespace Nop.Plugin.Misc.FruitBankPlugin.Services;
public class CustomPriceCalculationService : PriceCalculationService
{
private FruitBankDbContext _dbContext;
private readonly IProductAttributeService _productAttributeService;
private readonly ISpecificationAttributeService _specificationAttributeService;
private readonly ILocalizationService _localizationService;
private ILogger _logger;
public CustomPriceCalculationService(
FruitBankDbContext dbContext,
// inject all base deps
CatalogSettings catalogSettings,
CurrencySettings currencySettings,
ICategoryService categoryService,
ICurrencyService currencyService,
IManufacturerService manufacturerService,
IProductAttributeParser productAttributeParser,
IProductAttributeService productAttributeService,
ISpecificationAttributeService specificationAttributeService,
IProductService productService,
ICustomerService customerService,
IDiscountService discountService,
IDiscountPluginManager discountPluginManager,
ILocalizationService localizationService,
IStaticCacheManager cacheManager,
IWorkContext workContext,
IEnumerable<IAcLogWriterBase> logWriters)
: base(catalogSettings, currencySettings, categoryService, currencyService, customerService, discountService, manufacturerService,
productAttributeParser, productService,
cacheManager)
{
_logger = new Logger(logWriters.ToArray());
_dbContext = dbContext;
// assign all base deps to local private vars if needed
_productAttributeService = productAttributeService;
_specificationAttributeService = specificationAttributeService;
_localizationService = localizationService;
}
public decimal CalculateOrderItemFinalPrice(OrderItemDto orderItemDto, decimal unitPrice, int quantity)
=> decimal.Round(unitPrice * (orderItemDto.IsMeasurable ? (decimal)orderItemDto.NetWeight : quantity), 0);
public async Task<bool> CheckAndUpdateOrderItemFinalPricesAsync(OrderItem orderItem)
{
var orderItemDto = await _dbContext.OrderItemDtos.GetByIdAsync(orderItem.Id, true);
return await CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDto);
}
public async Task<bool> CheckAndUpdateOrderItemFinalPricesAsync(OrderItemDto orderItemDto)
{
var orderItem = await _dbContext.OrderItems.GetByIdAsync(orderItemDto.Id);
return await CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDto);
}
public async Task<bool> CheckAndUpdateOrderItemFinalPricesAsync(OrderItem orderItem, OrderItemDto orderItemDto)
{
_logger.Info($"CustomPriceCalculationService->CheckAndUpdateOrderItemFinalPricesAsync; orderItem.Id: {orderItem.Id}");
var finalPriceInclTax = CalculateOrderItemFinalPrice(orderItemDto, orderItem.UnitPriceInclTax, orderItem.Quantity);
var finalPriceExclTax = CalculateOrderItemFinalPrice(orderItemDto, orderItem.UnitPriceExclTax, orderItem.Quantity);
if (orderItem.PriceInclTax == finalPriceInclTax && orderItem.PriceExclTax == finalPriceExclTax) return false;
_logger.Error($"CustomPriceCalculationService->CheckAndUpdateOrderItemFinalPricesAsync; " +
$"orderItem.PriceInclTax({orderItem.PriceInclTax}) != finalPriceInclTax({finalPriceInclTax}) || " +
$"orderItem.PriceExclTax({orderItem.PriceExclTax}) != finalPriceExclTax({finalPriceExclTax})");
orderItem.PriceInclTax = finalPriceInclTax;
orderItem.PriceExclTax = finalPriceExclTax;
await _dbContext.OrderItems.UpdateAsync(orderItem, false);
return true;
}
public async Task CheckAndUpdateOrderTotalPrice(Order order)
{
var prevOrderTotal = order.OrderTotal;
var orderItemDtos = await _dbContext.OrderItemDtos.GetAllByOrderId(order.Id).ToListAsync();
order.OrderTotal = 0;
foreach (var itemDto in orderItemDtos)
{
await CheckAndUpdateOrderItemFinalPricesAsync(itemDto);
order.OrderTotal += itemDto.PriceInclTax;
}
if (order.OrderTotal == prevOrderTotal) return;
_logger.Error($"HandleEventAsync->CheckAndUpdateOrderItemFinalPrices; order.OrderTotal({order.OrderTotal}) == prevOrderTotal({prevOrderTotal})");
order.OrderSubtotalInclTax = order.OrderTotal;
order.OrderSubtotalExclTax = order.OrderTotal;
order.OrderSubTotalDiscountInclTax = order.OrderTotal;
order.OrderSubTotalDiscountExclTax = order.OrderTotal;
await _dbContext.Orders.UpdateAsync(order);
}
//public override async Task<(decimal priceWithoutDiscounts, decimal finalPrice, decimal appliedDiscountAmount, List<Discount> appliedDiscounts)> GetFinalPriceAsync(
// Product product, Customer customer, Store store, decimal? overriddenProductPrice, decimal additionalCharge = 0, bool includeDiscounts = true,
// int quantity = 1, DateTime? rentalStartDate = null, DateTime? rentalEndDate = null)
public override async Task<(decimal priceWithoutDiscounts, decimal finalPrice, decimal appliedDiscountAmount, List<Discount> appliedDiscounts)> GetFinalPriceAsync
(Product product, Customer customer, Store store, decimal? overriddenProductPrice, decimal additionalCharge, bool includeDiscounts, int quantity,
DateTime? rentalStartDate, DateTime? rentalEndDate)
{
var productDto = await _dbContext.ProductDtos.GetByIdAsync(product.Id, true);
if (productDto.IsMeasurable)
{
return (0, 0, 0m, []);
//return (overriddenProductPrice.GetValueOrDefault(0), overriddenProductPrice.GetValueOrDefault(0), 0m, []);
}
//var productAttributeMappings = await _specificationAttributeService.GetProductSpecificationAttributesAsync(product.Id);
////Product Attributes
//foreach (var pam in productAttributeMappings)
//{
// //get option
// var attributeOtion = await _specificationAttributeService.GetSpecificationAttributeOptionByIdAsync(pam.SpecificationAttributeOptionId);
// //get attribute
// var attribute = await _specificationAttributeService.GetSpecificationAttributeByIdAsync(attributeOtion.SpecificationAttributeId);
// // you can check for specific attribute by its name or id
// if (attribute.Name == "Needs to be measured for price")
// {
// return (0m, 0m, 0m, []);
// }
//}
return await base.GetFinalPriceAsync(product, customer, store, overriddenProductPrice, additionalCharge, includeDiscounts, quantity, rentalStartDate, rentalEndDate);
}
}