185 lines
8.4 KiB
C#
185 lines
8.4 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<CustomPriceCalculationService>(logWriters.ToArray());
|
|
|
|
_dbContext = dbContext;
|
|
// assign all base deps to local private vars if needed
|
|
_productAttributeService = productAttributeService;
|
|
_specificationAttributeService = specificationAttributeService;
|
|
_localizationService = localizationService;
|
|
}
|
|
|
|
public static decimal CalculateOrderItemFinalPrice(bool isMeasurable, decimal unitPrice, int quantity, double netWeight)
|
|
=> decimal.Round(unitPrice * (isMeasurable ? (decimal)netWeight: quantity), 0);
|
|
|
|
private static (decimal finalPriceInclTax, decimal finalPriceExclTax) CalculateOrderItemFinalPrices(int quantity, decimal unitPriceInclTax, decimal unitPriceExclTax, bool isMeasurable, double netWeight)
|
|
{
|
|
var finalPriceInclTax = CalculateOrderItemFinalPrice(isMeasurable, unitPriceInclTax, quantity, netWeight);
|
|
var finalPriceExclTax = CalculateOrderItemFinalPrice(isMeasurable, unitPriceExclTax, quantity, netWeight);
|
|
|
|
return (finalPriceInclTax, finalPriceExclTax);
|
|
}
|
|
|
|
public async Task<bool> CheckAndUpdateOrderItemFinalPricesAsync(OrderItem orderItem, OrderItemDto? orderItemDtoHelper = null)
|
|
{
|
|
orderItemDtoHelper ??= await _dbContext.OrderItemDtos.GetByIdAsync(orderItem.Id, true);
|
|
return await CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDtoHelper.IsMeasurable, orderItemDtoHelper.NetWeight);
|
|
}
|
|
|
|
//public async Task<bool> CheckAndUpdateOrderItemFinalPricesAsync(OrderItemDto orderItemDto)
|
|
//{
|
|
// var orderItem = await _dbContext.OrderItems.GetByIdAsync(orderItemDto.Id);
|
|
// return await CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDto.IsMeasurable, orderItemDto.NetWeight);
|
|
//}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="orderItem"></param>
|
|
/// <param name="isMeasurable"></param>
|
|
/// /// <param name="netWeight"></param>
|
|
/// <returns>true if has changes</returns>
|
|
public async Task<bool> CheckAndUpdateOrderItemFinalPricesAsync(OrderItem orderItem, bool isMeasurable, double netWeight)
|
|
{
|
|
_logger.Info($"orderItem.Id: {orderItem.Id}");
|
|
|
|
var finalPrices = CalculateOrderItemFinalPrices(orderItem.Quantity, orderItem.UnitPriceInclTax, orderItem.UnitPriceExclTax, isMeasurable, netWeight);
|
|
|
|
if (finalPrices.finalPriceInclTax == orderItem.PriceInclTax && finalPrices.finalPriceExclTax == orderItem.PriceExclTax) return false;
|
|
|
|
_logger.Info($"orderItem.PriceInclTax({orderItem.PriceInclTax}) != finalPriceInclTax({finalPrices.finalPriceInclTax}) || " +
|
|
$"orderItem.PriceExclTax({orderItem.PriceExclTax}) != finalPriceExclTax({finalPrices.finalPriceExclTax})");
|
|
|
|
orderItem.PriceInclTax = finalPrices.finalPriceInclTax;
|
|
orderItem.PriceExclTax = finalPrices.finalPriceExclTax;
|
|
|
|
await _dbContext.OrderItems.UpdateAsync(orderItem, false);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="order"></param>
|
|
/// <returns>true if has changes</returns>
|
|
public async Task<bool> CheckAndUpdateOrderTotalPrice(Order order)
|
|
{
|
|
var prevOrderTotal = order.OrderTotal;
|
|
|
|
var orderItemDtosById = await _dbContext.OrderItemDtos.GetAllByOrderId(order.Id).ToDictionaryAsync(k => k.Id, v => v);
|
|
var orderItems = await _dbContext.OrderItems.GetByIdsAsync(orderItemDtosById.Keys.ToList());
|
|
|
|
order.OrderTotal = 0;
|
|
|
|
foreach (var orderItem in orderItems)
|
|
{
|
|
var orderItemDto = orderItemDtosById[orderItem.Id];
|
|
|
|
await CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDto.IsMeasurable, orderItemDto.NetWeight);
|
|
order.OrderTotal += orderItem.PriceInclTax;
|
|
}
|
|
|
|
if (order.OrderTotal == prevOrderTotal) return false;
|
|
|
|
_logger.Info($"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, false);
|
|
return true;
|
|
}
|
|
|
|
//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);
|
|
|
|
|
|
var finalPrice = await base.GetFinalPriceAsync(product, customer, store, overriddenProductPrice, additionalCharge, includeDiscounts, quantity, rentalStartDate, rentalEndDate);
|
|
|
|
if (productDto.IsMeasurable)
|
|
{
|
|
//finalPrice.priceWithoutDiscounts = 0;
|
|
//return (0, finalPrice.finalPrice, finalPrice.appliedDiscountAmount, []);
|
|
return finalPrice;
|
|
//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 finalPrice;
|
|
}
|
|
}
|