Price calculation improvements, fixes, etc...
This commit is contained in:
parent
f9b302c5d9
commit
11b151a9ec
|
|
@ -160,7 +160,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
|||
return RedirectToAction("List", "Order");
|
||||
|
||||
// store attributes in GenericAttribute table
|
||||
await _genericAttributeService.SaveAttributeAsync(order, nameof(IMeasurable.IsMeasurable), model.IsMeasurable, _storeContext.GetCurrentStore().Id);
|
||||
//await _genericAttributeService.SaveAttributeAsync(order, nameof(IMeasurable.IsMeasurable), model.IsMeasurable, _storeContext.GetCurrentStore().Id);
|
||||
await _genericAttributeService.SaveAttributeAsync(order, nameof(IOrderDto.DateOfReceipt), model.DateOfReceipt, _storeContext.GetCurrentStore().Id);
|
||||
|
||||
_notificationService.SuccessNotification("Custom attributes saved successfully.");
|
||||
|
|
@ -226,11 +226,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
|||
|
||||
//var productDtosById = await _dbContext.ProductDtos.GetAllByIds(orderProducts.Select(op => op.Id)).ToDictionaryAsync(p => p.Id, prodDto => prodDto);
|
||||
var store = _storeContext.GetCurrentStore();
|
||||
var productDtosByOrderItemId = (await _dbContext.ProductDtos.GetByIdsAsync(orderProducts.Select(x => x.Id).ToArray())).ToDictionary(k => k.Id, v => v);
|
||||
|
||||
var transactionSuccess = await _dbContext.TransactionSafeAsync(async _ =>
|
||||
{
|
||||
await _orderService.InsertOrderAsync(order);
|
||||
order.CustomOrderNumber = order.Id.ToString();
|
||||
await _orderService.UpdateOrderAsync(order);
|
||||
|
||||
order.OrderTotal = 0;
|
||||
|
||||
foreach (var item in orderProducts)
|
||||
{
|
||||
|
|
@ -239,48 +241,47 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
|||
if (product == null || product.StockQuantity - item.Quantity < 0)
|
||||
{
|
||||
var errorText = $"product == null || product.StockQuantity - item.Quantity < 0; productId: {product?.Id}; product?.StockQuantity - item.Quantity: {product?.StockQuantity - item.Quantity}";
|
||||
|
||||
|
||||
_logger.Error($"{errorText}");
|
||||
throw new Exception($"{errorText}");
|
||||
}
|
||||
|
||||
//var (_, finalUnitPrice, _, _) = await _priceCalculationService.GetFinalPriceAsync(product, customer, store, item.Price, 0, true, item.Quantity, null, null);
|
||||
var productDto = productDtosByOrderItemId[item.Id];
|
||||
var isMeasurable = productDto.IsMeasurable;
|
||||
|
||||
//var (presetPriceInclTax, _) = await _taxService.GetProductPriceAsync(product, finalPrice, true, customer);
|
||||
//var (presetPriceExclTax, _) = await _taxService.GetProductPriceAsync(product, finalPrice, false, customer);
|
||||
//model.UnitPriceExclTax = presetPriceExclTax;
|
||||
//model.UnitPriceInclTax = presetPriceInclTax;
|
||||
//model.Quantity = item.Quantity;
|
||||
//model.SubTotalExclTax = presetPriceExclTax;
|
||||
//model.SubTotalInclTax = presetPriceInclTax;
|
||||
|
||||
//if (productDtosById.TryGetValue(item.Id, out var productDto))
|
||||
var orderItem = new OrderItem
|
||||
{
|
||||
var orderItem = new OrderItem
|
||||
{
|
||||
OrderId = order.Id,
|
||||
ProductId = item.Id,
|
||||
Quantity = item.Quantity,
|
||||
UnitPriceInclTax = item.Price,
|
||||
UnitPriceExclTax = item.Price,
|
||||
PriceInclTax = item.Price * item.Quantity,
|
||||
PriceExclTax = item.Price * item.Quantity,
|
||||
OriginalProductCost = product.ProductCost,
|
||||
AttributeDescription = string.Empty,
|
||||
AttributesXml = string.Empty,
|
||||
DiscountAmountInclTax = 0,
|
||||
DiscountAmountExclTax = 0
|
||||
};
|
||||
|
||||
await _orderService.InsertOrderItemAsync(orderItem);
|
||||
OrderId = order.Id,
|
||||
ProductId = item.Id,
|
||||
Quantity = item.Quantity,
|
||||
UnitPriceInclTax = item.Price,
|
||||
UnitPriceExclTax = item.Price,
|
||||
PriceInclTax = isMeasurable ? 0 : item.Price * item.Quantity,
|
||||
PriceExclTax = isMeasurable ? 0 : item.Price * item.Quantity,
|
||||
OriginalProductCost = product.ProductCost,
|
||||
AttributeDescription = string.Empty,
|
||||
AttributesXml = string.Empty,
|
||||
DiscountAmountInclTax = 0,
|
||||
DiscountAmountExclTax = 0
|
||||
};
|
||||
|
||||
//await _productService.AddStockQuantityHistoryEntryAsync(product, -orderItem.Quantity, product.StockQuantity, 1);
|
||||
await _productService.AdjustInventoryAsync(product, -orderItem.Quantity, orderItem.AttributesXml, "");
|
||||
//await _productService.BookReservedInventoryAsync(product, 1, item.Quantity, "");
|
||||
}
|
||||
//else _logger.Error($"(productDtosById.TryGetValue(item.Id, out var product) == false); {item}");
|
||||
order.OrderTotal += orderItem.PriceInclTax;
|
||||
await _orderService.InsertOrderItemAsync(orderItem);
|
||||
|
||||
//await _productService.AddStockQuantityHistoryEntryAsync(product, -orderItem.Quantity, product.StockQuantity, 1);
|
||||
await _productService.AdjustInventoryAsync(product, -orderItem.Quantity, orderItem.AttributesXml, "");
|
||||
//await _productService.BookReservedInventoryAsync(product, 1, item.Quantity, "");
|
||||
}
|
||||
|
||||
order.CustomOrderNumber = order.Id.ToString();
|
||||
|
||||
order.OrderSubtotalInclTax = order.OrderTotal;
|
||||
order.OrderSubtotalExclTax = order.OrderTotal;
|
||||
order.OrderSubTotalDiscountInclTax = order.OrderTotal;
|
||||
order.OrderSubTotalDiscountExclTax = order.OrderTotal;
|
||||
|
||||
await _orderService.UpdateOrderAsync(order);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -345,6 +345,14 @@
|
|||
Width = "80"
|
||||
}
|
||||
};
|
||||
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModelExtended.IsMeasurable))
|
||||
{
|
||||
Title = T("Admin.Orders.Fields.IsMeasurable").Text,
|
||||
Width = "100",
|
||||
Render = new RenderCustom("renderColumnIsMeasurable"),
|
||||
ClassName = NopColumnClassDefaults.CenterAll
|
||||
});
|
||||
|
||||
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(OrderModelExtended.IsMeasured))
|
||||
{
|
||||
Title = T("Admin.Orders.Fields.IsMeasured").Text,
|
||||
|
|
@ -352,6 +360,7 @@
|
|||
Render = new RenderCustom("renderColumnIsMeasurable"),
|
||||
ClassName = NopColumnClassDefaults.CenterAll
|
||||
});
|
||||
|
||||
gridModel.ColumnCollection.Add(new ColumnProperty(nameof(IOrderDto.DateOfReceipt))
|
||||
{
|
||||
Title = T("Admin.Orders.Fields.PickupDate").Text,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||
using Nop.Core;
|
||||
using Nop.Core.Domain.Catalog;
|
||||
using Nop.Core.Domain.Orders;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||
using Nop.Services.Common;
|
||||
|
|
@ -20,12 +21,15 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components
|
|||
private readonly FruitBankAttributeService _fruitBankAttributeService;
|
||||
private readonly IWorkContext _workContext;
|
||||
private readonly IStoreContext _storeContext;
|
||||
private FruitBankDbContext _dbContext;
|
||||
|
||||
public OrderAttributesViewComponent(FruitBankAttributeService fruitBankAttributeService, IWorkContext workContext, IStoreContext storeContext)
|
||||
public OrderAttributesViewComponent(FruitBankDbContext dbContext, FruitBankAttributeService fruitBankAttributeService, IWorkContext workContext, IStoreContext storeContext)
|
||||
{
|
||||
_workContext = workContext;
|
||||
_storeContext = storeContext;
|
||||
_fruitBankAttributeService = fruitBankAttributeService;
|
||||
|
||||
_dbContext= dbContext;
|
||||
}
|
||||
|
||||
public async Task<IViewComponentResult> InvokeAsync(string widgetZone, object additionalData)
|
||||
|
|
@ -36,19 +40,23 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components
|
|||
|
||||
if (model.OrderId > 0)
|
||||
{
|
||||
var orderPickupAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, DateTime?>(model.OrderId, nameof(IOrderDto.DateOfReceipt));
|
||||
var orderMeasurableAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, bool>(model.OrderId, nameof(IMeasurable.IsMeasurable));
|
||||
var orderDto = await _dbContext.OrderDtos.GetByIdAsync(model.OrderId, true);
|
||||
|
||||
model.IsMeasurable = orderMeasurableAttributeValue;
|
||||
if(orderPickupAttributeValue.HasValue && orderPickupAttributeValue.Value != DateTime.MinValue)
|
||||
{
|
||||
model.DateOfReceipt = orderPickupAttributeValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
model.DateOfReceipt = null;
|
||||
}
|
||||
model.IsMeasurable = orderDto.IsMeasurable;
|
||||
model.DateOfReceipt = orderDto.DateOfReceipt;
|
||||
|
||||
//var orderPickupAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, DateTime?>(model.OrderId, nameof(IOrderDto.DateOfReceipt));
|
||||
|
||||
//if (orderPickupAttributeValue.HasValue && orderPickupAttributeValue.Value != DateTime.MinValue)
|
||||
//{
|
||||
// model.DateOfReceipt = orderPickupAttributeValue;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// model.DateOfReceipt = null;
|
||||
//}
|
||||
}
|
||||
|
||||
return View("~/Plugins/Misc.FruitBankPlugin/Views/OrderAttributes.cshtml", model);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -433,6 +433,9 @@ public class FruitBankDbContext : MgDbContextBase,
|
|||
|
||||
if (!orderItemDto.IsMeasurable) continue;
|
||||
|
||||
var finalPriceInclTax = decimal.Round(orderItemDto.UnitPriceInclTax * orderItemDto.Quantity, 0);
|
||||
var finalPriceExclTax = decimal.Round(orderItemDto.UnitPriceExclTax * orderItemDto.Quantity, 0);
|
||||
|
||||
var gaNetWeight = CommonHelper.To<double>(orderItemDto.GenericAttributes.FirstOrDefault(x => x.Key == nameof(IMeasuringNetWeight.NetWeight))?.Value ?? "0");
|
||||
|
||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<OrderItem, double>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public class OrderDtoDbTable : MgDtoDbTableBase<OrderDto, Order>
|
|||
=> GetAll(loadRelations).Where(o => o.OrderStatusId == (int)orderStatus);
|
||||
|
||||
public IQueryable<OrderDto> GetAllForMeasuring(bool loadRelations = true)
|
||||
=> GetAllByOrderStatus(OrderStatus.Pending, loadRelations).Where(o => o.DateOfReceipt != null);
|
||||
=> GetAllByOrderStatus(OrderStatus.Pending, loadRelations).Where(o => o.GenericAttributes.Any(ga => ga.Key == nameof(OrderDto.DateOfReceipt)));
|
||||
|
||||
public IQueryable<OrderDto> GetAllByIds(IEnumerable<int> orderIds, bool loadRelations = true) => GetAll(loadRelations).Where(o => orderIds.Contains(o.Id));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,18 +11,19 @@ using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
|||
using Nop.Services.Events;
|
||||
using Mango.Nop.Core.Extensions;
|
||||
using Nop.Core.Domain.Orders;
|
||||
using Nop.Services.Catalog;
|
||||
|
||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.EventConsumers;
|
||||
|
||||
public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBankDbContext ctx, FruitBankAttributeService fruitBankAttributeService, IEnumerable<IAcLogWriterBase> logWriters) :
|
||||
MgEventConsumerBase(ctx, httpContextAcc, logWriters),
|
||||
public class FruitBankEventConsumer :
|
||||
MgEventConsumerBase,
|
||||
IConsumer<EntityDeletedEvent<Shipping>>,
|
||||
IConsumer<EntityInsertedEvent<ShippingItem>>,
|
||||
IConsumer<EntityUpdatedEvent<ShippingItem>>,
|
||||
IConsumer<EntityInsertedEvent<ShippingItem>>,
|
||||
IConsumer<EntityUpdatedEvent<ShippingItem>>,
|
||||
IConsumer<EntityDeletedEvent<ShippingItem>>,
|
||||
IConsumer<EntityInsertedEvent<ShippingDocument>>,
|
||||
IConsumer<EntityUpdatedEvent<ShippingDocument>>,
|
||||
IConsumer<EntityDeletedEvent<ShippingDocument>>,
|
||||
IConsumer<EntityInsertedEvent<ShippingDocument>>,
|
||||
IConsumer<EntityUpdatedEvent<ShippingDocument>>,
|
||||
IConsumer<EntityDeletedEvent<ShippingDocument>>,
|
||||
IConsumer<EntityInsertedEvent<ShippingItemPallet>>,
|
||||
IConsumer<EntityUpdatedEvent<ShippingItemPallet>>,
|
||||
IConsumer<EntityDeletedEvent<ShippingItemPallet>>,
|
||||
|
|
@ -30,6 +31,20 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
IConsumer<EntityInsertedEvent<OrderItem>>,
|
||||
IConsumer<EntityUpdatedEvent<OrderItem>>
|
||||
{
|
||||
private CustomPriceCalculationService _customPriceCalculationService;
|
||||
|
||||
private readonly FruitBankDbContext _ctx;
|
||||
private readonly FruitBankAttributeService _fruitBankAttributeService;
|
||||
|
||||
public FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, IPriceCalculationService customPriceCalculationService, FruitBankDbContext ctx, FruitBankAttributeService fruitBankAttributeService, IEnumerable<IAcLogWriterBase> logWriters) : base(ctx, httpContextAcc, logWriters)
|
||||
{
|
||||
_ctx = ctx;
|
||||
|
||||
_fruitBankAttributeService = fruitBankAttributeService;
|
||||
_customPriceCalculationService = customPriceCalculationService as CustomPriceCalculationService;
|
||||
}
|
||||
|
||||
|
||||
public override async Task HandleEventAsync(EntityUpdatedEvent<Product> eventMessage)
|
||||
{
|
||||
var product = await CheckAndUpdateProductManageInventoryMethodToManageStock(eventMessage.Entity);
|
||||
|
|
@ -40,14 +55,14 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
|
||||
if (saveProductCustomAttributesResult is { IsMeasurableChanged: true, IsMeasurable: not null })
|
||||
{
|
||||
var shippingItems = await ctx.ShippingItems.Table
|
||||
var shippingItems = await _ctx.ShippingItems.Table
|
||||
.Where(si => si.ProductId == product.Id && !si.IsMeasured && si.IsMeasurable != saveProductCustomAttributesResult.IsMeasurable.Value)
|
||||
.ToListAsync();
|
||||
|
||||
if (shippingItems.Count > 0)
|
||||
{
|
||||
foreach (var shippingItem in shippingItems) shippingItem.IsMeasurable = saveProductCustomAttributesResult.IsMeasurable.Value;
|
||||
await ctx.ShippingItems.UpdateAsync(shippingItems, false);
|
||||
await _ctx.ShippingItems.UpdateAsync(shippingItems, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +83,7 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
/// <param name="product"></param>
|
||||
/// <returns>IsMeasureable</returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
|
||||
|
||||
private async Task<(bool IsMeasurableChanged, bool? IsMeasurable)> SaveProductCustomAttributesAsync(Product product)
|
||||
{
|
||||
if (product == null) return (false, null);
|
||||
|
|
@ -85,7 +100,7 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
|
||||
try
|
||||
{
|
||||
var productDto = product.Id > 0 ? await ctx.ProductDtos.GetByIdAsync(product.Id, false) : null;
|
||||
var productDto = product.Id > 0 ? await _ctx.ProductDtos.GetByIdAsync(product.Id, false) : null;
|
||||
|
||||
//IsMeasurable
|
||||
isMeasurable = form[nameof(IMeasurable.IsMeasurable)].ToString().Contains("true");
|
||||
|
|
@ -93,7 +108,7 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
|
||||
if (productDtoIsMeasurable == null || productDtoIsMeasurable.Value != isMeasurable.Value)
|
||||
{
|
||||
await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, bool>(product.Id, nameof(IMeasurable.IsMeasurable), isMeasurable.Value);
|
||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, bool>(product.Id, nameof(IMeasurable.IsMeasurable), isMeasurable.Value);
|
||||
isMeasurableChanged = true;
|
||||
}
|
||||
|
||||
|
|
@ -102,21 +117,21 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
var productDtoNetWeight = productDto?.GenericAttributes.GetValueOrNull<double>(nameof(IMeasuringNetWeight.NetWeight));
|
||||
|
||||
if (productDtoNetWeight == null || double.Round(productDtoNetWeight.Value, 1) != netWeight)
|
||||
await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, double>(product.Id, nameof(IMeasuringNetWeight.NetWeight), netWeight);
|
||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, double>(product.Id, nameof(IMeasuringNetWeight.NetWeight), netWeight);
|
||||
|
||||
//Tára
|
||||
var tare = double.Round(CommonHelper.To<double>(form[nameof(ITare.Tare)].ToString()), 1);
|
||||
if (tare < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (tare < 0); productId: {product.Id}; tare: {tare}");
|
||||
|
||||
if (productDto == null || productDto.Tare != tare)
|
||||
await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, double>(product.Id, nameof(ITare.Tare), tare);
|
||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, double>(product.Id, nameof(ITare.Tare), tare);
|
||||
|
||||
//IncomingQuantity
|
||||
var incomingQuantity = CommonHelper.To<int>(form[nameof(IIncomingQuantity.IncomingQuantity)].ToString());
|
||||
if (incomingQuantity < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (incomingQuantity < 0); productId: {product.Id}; incomingQuantity: {incomingQuantity}");
|
||||
|
||||
if (productDto == null || productDto.IncomingQuantity != incomingQuantity)
|
||||
await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, int>(product.Id, nameof(IIncomingQuantity.IncomingQuantity), incomingQuantity);
|
||||
await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, int>(product.Id, nameof(IIncomingQuantity.IncomingQuantity), incomingQuantity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -151,8 +166,8 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
|
||||
private async Task UpdateShippingItemMeasuringValuesAsync(ShippingItemPallet shippingItemPallet)
|
||||
{
|
||||
var shippingItem = await ctx.ShippingItems.GetByIdAsync(shippingItemPallet.ShippingItemId, false);
|
||||
await ctx.UpdateShippingItemAsync(shippingItem);
|
||||
var shippingItem = await _ctx.ShippingItems.GetByIdAsync(shippingItemPallet.ShippingItemId, false);
|
||||
await _ctx.UpdateShippingItemAsync(shippingItem);
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityInsertedEvent<ShippingItem> eventMessage)
|
||||
|
|
@ -183,13 +198,13 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
private async Task UpdateShippingDocumentIsAllMeasuredAsync(ShippingItem shippingItem)
|
||||
{
|
||||
//TODO: where: && IsMeasurable!!!! - J.
|
||||
var isAllShippingItemMeasured = ctx.ShippingItems.GetAll(false).Where(si => si.ShippingDocumentId == shippingItem.ShippingDocumentId).All(si => si.IsMeasured);
|
||||
var shippingDocument = await ctx.ShippingDocuments.GetByIdAsync(shippingItem.ShippingDocumentId);
|
||||
var isAllShippingItemMeasured = _ctx.ShippingItems.GetAll(false).Where(si => si.ShippingDocumentId == shippingItem.ShippingDocumentId).All(si => si.IsMeasured);
|
||||
var shippingDocument = await _ctx.ShippingDocuments.GetByIdAsync(shippingItem.ShippingDocumentId);
|
||||
|
||||
if (shippingDocument != null && shippingDocument.IsAllMeasured != isAllShippingItemMeasured)
|
||||
{
|
||||
shippingDocument.IsAllMeasured = isAllShippingItemMeasured;
|
||||
await ctx.ShippingDocuments.UpdateAsync(shippingDocument);
|
||||
await _ctx.ShippingDocuments.UpdateAsync(shippingDocument);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,13 +224,13 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
|
||||
private async Task UpdateShippingIsAllMeasuredAsync(ShippingDocument shippingDocument)
|
||||
{
|
||||
var isAllShippingDocumentMeasured = ctx.ShippingDocuments.GetAll(false).Where(si => si.ShippingId == shippingDocument.ShippingId).All(si => si.IsAllMeasured);
|
||||
var shipping = await ctx.Shippings.GetByIdAsync(shippingDocument.ShippingId);
|
||||
var isAllShippingDocumentMeasured = _ctx.ShippingDocuments.GetAll(false).Where(si => si.ShippingId == shippingDocument.ShippingId).All(si => si.IsAllMeasured);
|
||||
var shipping = await _ctx.Shippings.GetByIdAsync(shippingDocument.ShippingId);
|
||||
|
||||
if (shipping != null && shipping.IsAllMeasured != isAllShippingDocumentMeasured)
|
||||
{
|
||||
shipping.IsAllMeasured = isAllShippingDocumentMeasured;
|
||||
await ctx.Shippings.UpdateAsync(shipping);
|
||||
await _ctx.Shippings.UpdateAsync(shipping);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,46 +242,43 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
|
|||
{
|
||||
Logger.Info($"HandleEventAsync->EntityDeletedEvent<Shipping>; id: {eventMessage.Entity.Id}");
|
||||
|
||||
await ctx.ShippingDocuments.DeleteAsync(sd => sd.ShippingId == eventMessage.Entity.Id, true);
|
||||
await _ctx.ShippingDocuments.DeleteAsync(sd => sd.ShippingId == eventMessage.Entity.Id, true);
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityDeletedEvent<ShippingDocument> eventMessage)
|
||||
{
|
||||
Logger.Info($"HandleEventAsync->EntityDeletedEvent<ShippingDocument>; id: {eventMessage.Entity.Id}");
|
||||
|
||||
await ctx.ShippingItems.DeleteAsync(si => si.ShippingDocumentId == eventMessage.Entity.Id, true);
|
||||
await _ctx.ShippingItems.DeleteAsync(si => si.ShippingDocumentId == eventMessage.Entity.Id, true);
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityDeletedEvent<ShippingItem> eventMessage)
|
||||
{
|
||||
Logger.Info($"HandleEventAsync->EntityDeletedEvent<ShippingItem>; id: {eventMessage.Entity.Id}");
|
||||
|
||||
await ctx.ShippingItemPallets.DeleteAsync(sp => sp.ShippingItemId == eventMessage.Entity.Id, false);
|
||||
await _ctx.ShippingItemPallets.DeleteAsync(sp => sp.ShippingItemId == eventMessage.Entity.Id, false);
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityUpdatedEvent<OrderItem> eventMessage) => await CheckAndUpdateOrderItemFinalPrices(eventMessage.Entity);
|
||||
|
||||
public async Task HandleEventAsync(EntityInsertedEvent<OrderItem> eventMessage) => await CheckAndUpdateOrderItemFinalPrices(eventMessage.Entity);
|
||||
|
||||
private async Task CheckAndUpdateOrderItemFinalPrices(OrderItem orderItem)
|
||||
public async Task HandleEventAsync(EntityUpdatedEvent<OrderItem> eventMessage)
|
||||
{
|
||||
Logger.Info($"HandleEventAsync->CheckAndUpdateOrderItemFinalPrices; orderItem.Id: {orderItem.Id}");
|
||||
|
||||
var finalPriceInclTax = decimal.Round(orderItem.UnitPriceInclTax * orderItem.Quantity, 0);
|
||||
var finalPriceExclTax = decimal.Round(orderItem.UnitPriceExclTax * orderItem.Quantity, 0);
|
||||
|
||||
if (orderItem.PriceInclTax != finalPriceInclTax || orderItem.PriceExclTax != finalPriceExclTax)
|
||||
//await _customPriceCalculationService.CheckAndUpdateOrderItemFinalPricesAsync(eventMessage.Entity);
|
||||
if (await _customPriceCalculationService.CheckAndUpdateOrderItemFinalPricesAsync(eventMessage.Entity))
|
||||
{
|
||||
Logger.Error($"HandleEventAsync->CheckAndUpdateOrderItemFinalPrices; " +
|
||||
$"orderItem.PriceInclTax({orderItem.PriceInclTax}) != finalPriceInclTax({finalPriceInclTax}) || " +
|
||||
$"orderItem.PriceExclTax({orderItem.PriceExclTax}) != finalPriceExclTax({finalPriceExclTax})");
|
||||
|
||||
orderItem.PriceInclTax = finalPriceInclTax;
|
||||
orderItem.PriceExclTax = finalPriceExclTax;
|
||||
|
||||
await ctx.OrderItems.UpdateAsync(orderItem, false);
|
||||
var order = await _ctx.Orders.GetByIdAsync(eventMessage.Entity.OrderId);
|
||||
await _customPriceCalculationService.CheckAndUpdateOrderTotalPrice(order);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Delete
|
||||
}
|
||||
|
||||
public async Task HandleEventAsync(EntityInsertedEvent<OrderItem> eventMessage)
|
||||
{
|
||||
//await _customPriceCalculationService.CheckAndUpdateOrderItemFinalPricesAsync(eventMessage.Entity);
|
||||
if (await _customPriceCalculationService.CheckAndUpdateOrderItemFinalPricesAsync(eventMessage.Entity))
|
||||
{
|
||||
var order = await _ctx.Orders.GetByIdAsync(eventMessage.Entity.OrderId);
|
||||
await _customPriceCalculationService.CheckAndUpdateOrderTotalPrice(order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Delete
|
||||
|
|
|
|||
|
|
@ -1,29 +1,35 @@
|
|||
using Nop.Core.Caching;
|
||||
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;
|
||||
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;
|
||||
using Nop.Services.Logging;
|
||||
using Nop.Core.Domain.Directory;
|
||||
using Nop.Services.Directory;
|
||||
using Nop.Core.Domain.Discounts;
|
||||
using Nop.Core.Domain.Stores;
|
||||
|
||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||
|
||||
public class CustomPriceCalculationService : PriceCalculationService
|
||||
{
|
||||
private readonly IRepository<Product> _productRepository;
|
||||
private FruitBankDbContext _dbContext;
|
||||
private readonly IProductAttributeService _productAttributeService;
|
||||
private readonly ISpecificationAttributeService _specificationAttributeService;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private ILogger _logger;
|
||||
|
||||
public CustomPriceCalculationService(
|
||||
IRepository<Product> productRepository,
|
||||
FruitBankDbContext dbContext,
|
||||
// inject all base deps
|
||||
CatalogSettings catalogSettings,
|
||||
CurrencySettings currencySettings,
|
||||
|
|
@ -40,41 +46,110 @@ public class CustomPriceCalculationService : PriceCalculationService
|
|||
ILocalizationService localizationService,
|
||||
IStaticCacheManager cacheManager,
|
||||
IWorkContext workContext,
|
||||
ILogger logger)
|
||||
IEnumerable<IAcLogWriterBase> logWriters)
|
||||
: base(catalogSettings, currencySettings, categoryService, currencyService, customerService, discountService, manufacturerService,
|
||||
productAttributeParser, productService,
|
||||
cacheManager)
|
||||
{
|
||||
_productRepository = productRepository;
|
||||
_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 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 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 productAttributeMappings = await _specificationAttributeService.GetProductSpecificationAttributesAsync(product.Id);
|
||||
//Product Attributes
|
||||
foreach (var pam in productAttributeMappings)
|
||||
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)
|
||||
{
|
||||
//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, []);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue