using AyCode.Core.Extensions; using AyCode.Core.Loggers; using AyCode.Services.Server.SignalRs; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.Interfaces; using FruitBank.Common.Server.Services.SignalRs; using FruitBank.Common.Services; using Mango.Nop.Core.Extensions; using Mango.Nop.Core.Loggers; using Microsoft.CodeAnalysis.Operations; using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Common; using Nop.Core.Domain.Orders; using Nop.Core.Events; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; using Nop.Services.Catalog; using Nop.Services.Events; namespace Nop.Plugin.Misc.FruitBankPlugin.Services; #nullable enable public class MeasurementService : MeasurementServiceBase, IMeasurementService { private readonly FruitBankDbContext _dbContext; private readonly IEventPublisher _eventPublisher; private readonly FruitBankAttributeService _fruitBankAttributeService; private readonly SignalRSendToClientService _signalRSendToClientService; private readonly CustomPriceCalculationService _customPriceCalculationService; public MeasurementService(FruitBankDbContext dbContext, SignalRSendToClientService signalRSendToClientService, FruitBankAttributeService fruitBankAttributeService, IPriceCalculationService customPriceCalculationService, IEventPublisher eventPublisher, IEnumerable logWriters) : base(new Logger(logWriters.ToArray())) { _dbContext = dbContext; _eventPublisher = eventPublisher; _fruitBankAttributeService = fruitBankAttributeService; _signalRSendToClientService = signalRSendToClientService; _customPriceCalculationService = (CustomPriceCalculationService)customPriceCalculationService; } public async Task DeleteOrderItemConstraintsAsync(int orderItemId) => await DeleteOrderItemConstraintsAsync(await _dbContext.OrderItems.GetByIdAsync(orderItemId)); public async Task DeleteOrderItemConstraintsAsync(OrderItem orderItem) { Logger.Info($"MeasurementService->DeleteOrderItemConstraintsAsync() invoked; orderItem.Id: {orderItem?.Id}"); if (orderItem == null) return; await _dbContext.DeleteOrderItemConstraintsSafeAsync(orderItem); await _signalRSendToClientService.SendOrderItemDeleted(orderItem); var order = await _dbContext.Orders.GetByIdAsync(orderItem.OrderId); await _customPriceCalculationService.CheckAndUpdateOrderTotalPrice(order); } public async Task OrderItemInsertedOrUpdatedPostProcess(OrderItem orderItem) { var orderItemDto = await _dbContext.OrderItemDtos.GetByIdAsync(orderItem.Id, true); await CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDto); await _signalRSendToClientService.SendOrderItemChanged(orderItemDto); } public async Task CheckAndUpdateOrderItemFinalPricesAsync(OrderItem orderItem, OrderItemDto? orderItemDtoHelper = null) { if (await _customPriceCalculationService.CheckAndUpdateOrderItemFinalPricesAsync(orderItem, orderItemDtoHelper)) { var order = await _dbContext.Orders.GetByIdAsync(orderItem.OrderId); await _customPriceCalculationService.CheckAndUpdateOrderTotalPrice(order); } } public async Task OrderItemMeasuringReset(int orderItemId) => await OrderItemMeasuringReset(await _dbContext.OrderItems.GetByIdAsync(orderItemId)); public async Task OrderItemMeasuringReset(OrderItem orderItem) { var order = await _dbContext.Orders.GetByIdAsync(orderItem.OrderId); var orderItemPallets = await _dbContext.OrderItemPallets.GetAllByOrderItemId(orderItem.Id, false).ToListAsync(); var result = await _dbContext.TransactionSafeAsync(async _ => { await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(order.Id, nameof(IOrderDto.RevisorId), 0); foreach (var orderItemPallet in orderItemPallets) { orderItemPallet.RevisorId = 0; orderItemPallet.IsMeasured = false; await _dbContext.OrderItemPallets.UpdateAsync(orderItemPallet); } if (order.OrderStatus == OrderStatus.Complete) await _dbContext.SetOrderStatusToPendingAsync(order); return true; }); if (!result) return result; foreach (var orderItemPallet in orderItemPallets) await _signalRSendToClientService.SendOrderItemPalletChanged(orderItemPallet); await _signalRSendToClientService.SendOrderChanged(await _dbContext.OrderDtos.GetByIdAsync(orderItem.OrderId, true)); return result; } public async Task?> ProcessAndSaveFullShippingJson(string fullShippingJson, int customerId) { var partners = fullShippingJson.JsonTo>(); if (partners == null || partners.Count == 0) return partners; var a = partners.SelectMany(x => x.ShippingDocuments?.SelectMany(sd => sd.ShippingItems?.Where(si => si.ProductId.GetValueOrDefault(0) > 0).Select(si => si.ProductId!.Value) ?? []) ?? []).ToHashSet(); var productDtosById = await _dbContext.ProductDtos.GetAllByIds(a, false, false).ToDictionaryAsync(k => k.Id, v => v); var result = await _dbContext.TransactionSafeAsync(async _ => { foreach (var partner in partners) { //await _dbContext.Partners.InsertAsync(partner, false); if (partner.ShippingDocuments == null) continue; foreach (var shippingDocument in partner.ShippingDocuments) { //shippingDocument.PartnerId = 0; await _dbContext.ShippingDocuments.InsertAsync(shippingDocument, false); if (shippingDocument.ShippingItems == null) continue; foreach (var shippingItem in shippingDocument.ShippingItems) { shippingItem.NameOnDocument = shippingItem.Name; if (shippingItem.ProductId != null && productDtosById.TryGetValue(shippingItem.ProductId.Value, out var productDto)) { shippingItem.Name = productDto.Name; shippingItem.IsMeasurable = productDto.IsMeasurable; //TODO: Update Product Incoming attribute! - J. } else shippingItem.ProductId = null; shippingItem.ShippingDocumentId = shippingDocument.Id; await _dbContext.ShippingItems.InsertAsync(shippingItem, false); } } } return true; }); return result ? partners : null; } }