Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

ShipmentService.cs

using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Shipping;
using Nop.Data;
using Nop.Services.Shipping.Pickup;
using Nop.Services.Shipping.Tracking;

namespace Nop.Services.Shipping;

/// 
/// Shipment service
/// 
public partial class ShipmentService : IShipmentService
{
    #region Fields

    protected readonly IPickupPluginManager _pickupPluginManager;
    protected readonly IRepository
_addressRepository; protected readonly IRepository _orderRepository; protected readonly IRepository _orderItemRepository; protected readonly IRepository _productRepository; protected readonly IRepository _shipmentRepository; protected readonly IRepository _siRepository; protected readonly IShippingPluginManager _shippingPluginManager; #endregion #region Ctor public ShipmentService(IPickupPluginManager pickupPluginManager, IRepository
addressRepository, IRepository orderRepository, IRepository orderItemRepository, IRepository productRepository, IRepository shipmentRepository, IRepository siRepository, IShippingPluginManager shippingPluginManager) { _pickupPluginManager = pickupPluginManager; _addressRepository = addressRepository; _orderRepository = orderRepository; _orderItemRepository = orderItemRepository; _productRepository = productRepository; _shipmentRepository = shipmentRepository; _siRepository = siRepository; _shippingPluginManager = shippingPluginManager; } #endregion #region Methods /// /// Deletes a shipment /// /// Shipment /// A task that represents the asynchronous operation public virtual async Task DeleteShipmentAsync(Shipment shipment) { await _shipmentRepository.DeleteAsync(shipment); } /// /// Search shipments /// /// Vendor identifier; 0 to load all records /// Warehouse identifier, only shipments with products from a specified warehouse will be loaded; 0 to load all orders /// Shipping country identifier; 0 to load all records /// Shipping state identifier; 0 to load all records /// Shipping county; null to load all records /// Shipping city; null to load all records /// Search by tracking number /// A value indicating whether we should load only not shipped shipments /// A value indicating whether we should load only not ready for pickup shipments /// A value indicating whether we should load only not delivered shipments /// Order identifier; 0 to load all records /// Created date from (UTC); null to load all records /// Created date to (UTC); null to load all records /// Page index /// Page size /// /// A task that represents the asynchronous operation /// The task result contains the shipments /// public virtual async Task> GetAllShipmentsAsync(int vendorId = 0, int warehouseId = 0, int shippingCountryId = 0, int shippingStateId = 0, string shippingCounty = null, string shippingCity = null, string trackingNumber = null, bool loadNotShipped = false, bool loadNotReadyForPickup = false, bool loadNotDelivered = false, int orderId = 0, DateTime? createdFromUtc = null, DateTime? createdToUtc = null, int pageIndex = 0, int pageSize = int.MaxValue) { var shipments = await _shipmentRepository.GetAllPagedAsync(query => { if (orderId > 0) query = query.Where(o => o.OrderId == orderId); if (!string.IsNullOrEmpty(trackingNumber)) query = query.Where(s => s.TrackingNumber.Contains(trackingNumber)); if (shippingCountryId > 0) query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where _addressRepository.Table.Any(a => a.Id == (o.PickupInStore ? o.PickupAddressId : o.ShippingAddressId) && a.CountryId == shippingCountryId) select s; if (shippingStateId > 0) query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where _addressRepository.Table.Any(a => a.Id == (o.PickupInStore ? o.PickupAddressId : o.ShippingAddressId) && a.StateProvinceId == shippingStateId) select s; if (!string.IsNullOrWhiteSpace(shippingCounty)) query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where _addressRepository.Table.Any(a => a.Id == (o.PickupInStore ? o.PickupAddressId : o.ShippingAddressId) && a.County.Contains(shippingCounty)) select s; if (!string.IsNullOrWhiteSpace(shippingCity)) query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where _addressRepository.Table.Any(a => a.Id == (o.PickupInStore ? o.PickupAddressId : o.ShippingAddressId) && a.City.Contains(shippingCity)) select s; if (loadNotShipped) query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where !s.ShippedDateUtc.HasValue && !o.PickupInStore select s; if (loadNotReadyForPickup) query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where !s.ReadyForPickupDateUtc.HasValue && o.PickupInStore select s; if (loadNotDelivered) query = query.Where(s => !s.DeliveryDateUtc.HasValue); if (createdFromUtc.HasValue) query = query.Where(s => createdFromUtc.Value <= s.CreatedOnUtc); if (createdToUtc.HasValue) query = query.Where(s => createdToUtc.Value >= s.CreatedOnUtc); query = from s in query join o in _orderRepository.Table on s.OrderId equals o.Id where !o.Deleted select s; query = query.Distinct(); if (vendorId > 0) { var queryVendorOrderItems = from orderItem in _orderItemRepository.Table join p in _productRepository.Table on orderItem.ProductId equals p.Id where p.VendorId == vendorId select orderItem.Id; query = from s in query join si in _siRepository.Table on s.Id equals si.ShipmentId where queryVendorOrderItems.Contains(si.OrderItemId) select s; query = query.Distinct(); } if (warehouseId > 0) { query = from s in query join si in _siRepository.Table on s.Id equals si.ShipmentId where si.WarehouseId == warehouseId select s; query = query.Distinct(); } query = query.OrderByDescending(s => s.CreatedOnUtc); return query; }, pageIndex, pageSize); return shipments; } /// /// Get shipment by identifiers /// /// Shipment identifiers /// /// A task that represents the asynchronous operation /// The task result contains the shipments /// public virtual async Task> GetShipmentsByIdsAsync(int[] shipmentIds) { return await _shipmentRepository.GetByIdsAsync(shipmentIds); } /// /// Gets a shipment /// /// Shipment identifier /// /// A task that represents the asynchronous operation /// The task result contains the shipment /// public virtual async Task GetShipmentByIdAsync(int shipmentId) { return await _shipmentRepository.GetByIdAsync(shipmentId, cache => default, useShortTermCache: true); } /// /// Gets a list of order shipments /// /// Order identifier /// A value indicating whether to count only shipped or not shipped shipments; pass null to ignore /// A value indicating whether to load only ready for pickup shipments; pass null to ignore /// Vendor identifier; pass 0 to ignore /// /// A task that represents the asynchronous operation /// The task result contains the result /// public virtual async Task> GetShipmentsByOrderIdAsync(int orderId, bool? shipped = null, bool? readyForPickup = null, int vendorId = 0) { if (orderId == 0) return new List(); var shipments = _shipmentRepository.Table; if (shipped.HasValue) shipments = shipments.Where(s => s.ShippedDateUtc.HasValue == shipped); if (readyForPickup.HasValue) shipments = shipments.Where(s => s.ReadyForPickupDateUtc.HasValue == readyForPickup); return await shipments.Where(shipment => shipment.OrderId == orderId).ToListAsync(); } /// /// Inserts a shipment /// /// Shipment /// A task that represents the asynchronous operation public virtual async Task InsertShipmentAsync(Shipment shipment) { await _shipmentRepository.InsertAsync(shipment); } /// /// Updates the shipment /// /// Shipment /// A task that represents the asynchronous operation public virtual async Task UpdateShipmentAsync(Shipment shipment) { await _shipmentRepository.UpdateAsync(shipment); } /// /// Gets a shipment items of shipment /// /// Shipment identifier /// /// A task that represents the asynchronous operation /// The task result contains the shipment items /// public virtual async Task> GetShipmentItemsByShipmentIdAsync(int shipmentId) { if (shipmentId == 0) return null; return await _siRepository.Table.Where(si => si.ShipmentId == shipmentId).ToListAsync(); } /// /// Inserts a shipment item /// /// Shipment item /// A task that represents the asynchronous operation public virtual async Task InsertShipmentItemAsync(ShipmentItem shipmentItem) { await _siRepository.InsertAsync(shipmentItem); } /// /// Deletes a shipment item /// /// Shipment Item /// A task that represents the asynchronous operation public virtual async Task DeleteShipmentItemAsync(ShipmentItem shipmentItem) { await _siRepository.DeleteAsync(shipmentItem); } /// /// Updates a shipment item /// /// Shipment item /// A task that represents the asynchronous operation public virtual async Task UpdateShipmentItemAsync(ShipmentItem shipmentItem) { await _siRepository.UpdateAsync(shipmentItem); } /// /// Gets a shipment item /// /// Shipment item identifier /// /// A task that represents the asynchronous operation /// The task result contains the shipment item /// public virtual async Task GetShipmentItemByIdAsync(int shipmentItemId) { return await _siRepository.GetByIdAsync(shipmentItemId, cache => default, useShortTermCache: true); } /// /// Get quantity in shipments. For example, get planned quantity to be shipped /// /// Product /// Warehouse identifier /// Ignore already shipped shipments /// Ignore already delivered shipments /// /// A task that represents the asynchronous operation /// The task result contains the quantity /// public virtual async Task GetQuantityInShipmentsAsync(Product product, int warehouseId, bool ignoreShipped, bool ignoreDelivered) { ArgumentNullException.ThrowIfNull(product); //only products with "use multiple warehouses" are handled this way if (product.ManageInventoryMethod != ManageInventoryMethod.ManageStock) return 0; if (!product.UseMultipleWarehouses) return 0; const int cancelledOrderStatusId = (int)OrderStatus.Cancelled; var query = _siRepository.Table; query = from si in query join s in _shipmentRepository.Table on si.ShipmentId equals s.Id join o in _orderRepository.Table on s.OrderId equals o.Id where !o.Deleted && o.OrderStatusId != cancelledOrderStatusId select si; query = query.Distinct(); if (warehouseId > 0) query = query.Where(si => si.WarehouseId == warehouseId); if (ignoreShipped) { query = from si in query join s in _shipmentRepository.Table on si.ShipmentId equals s.Id where !s.ShippedDateUtc.HasValue select si; } if (ignoreDelivered) { query = from si in query join s in _shipmentRepository.Table on si.ShipmentId equals s.Id where !s.DeliveryDateUtc.HasValue select si; } var queryProductOrderItems = from orderItem in _orderItemRepository.Table where orderItem.ProductId == product.Id select orderItem.Id; query = from si in query where queryProductOrderItems.Any(orderItemId => orderItemId == si.OrderItemId) select si; //some null validation var result = Convert.ToInt32(await query.SumAsync(si => (int?)si.Quantity)); return result; } /// /// Get the tracker of the shipment /// /// Shipment /// /// A task that represents the asynchronous operation /// The task result contains the shipment tracker /// public virtual async Task GetShipmentTrackerAsync(Shipment shipment) { var order = await _orderRepository.GetByIdAsync(shipment.OrderId, cache => default, useShortTermCache: true); IShipmentTracker shipmentTracker = null; if (order.PickupInStore) { var pickupPointProvider = await _pickupPluginManager .LoadPluginBySystemNameAsync(order.ShippingRateComputationMethodSystemName); if (pickupPointProvider != null) shipmentTracker = await pickupPointProvider.GetShipmentTrackerAsync(); } else { var shippingRateComputationMethod = await _shippingPluginManager .LoadPluginBySystemNameAsync(order.ShippingRateComputationMethodSystemName); if (shippingRateComputationMethod != null) shipmentTracker = await shippingRateComputationMethod.GetShipmentTrackerAsync(); } return shipmentTracker; } #endregion }