Webiant Logo Webiant Logo
  1. No results found.

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

ShippingModelFactory.cs

using Nop.Core.Domain.Shipping;
using Nop.Services.Common;
using Nop.Services.Directory;
using Nop.Services.Localization;
using Nop.Services.Shipping;
using Nop.Services.Shipping.Date;
using Nop.Services.Shipping.Pickup;
using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions;
using Nop.Web.Areas.Admin.Models.Directory;
using Nop.Web.Areas.Admin.Models.Shipping;
using Nop.Web.Framework.Factories;
using Nop.Web.Framework.Models.Extensions;

namespace Nop.Web.Areas.Admin.Factories;

/// 
/// Represents the shipping model factory implementation
/// 
public partial class ShippingModelFactory : IShippingModelFactory
{
    #region Fields

    protected readonly IAddressModelFactory _addressModelFactory;
    protected readonly IAddressService _addressService;
    protected readonly ICountryService _countryService;
    protected readonly IDateRangeService _dateRangeService;
    protected readonly ILocalizationService _localizationService;
    protected readonly ILocalizedModelFactory _localizedModelFactory;
    protected readonly IPickupPluginManager _pickupPluginManager;
    protected readonly IShippingPluginManager _shippingPluginManager;
    protected readonly IShippingService _shippingService;
    protected readonly IStateProvinceService _stateProvinceService;

    #endregion

    #region Ctor

    public ShippingModelFactory(IAddressModelFactory addressModelFactory,
        IAddressService addressService,
        ICountryService countryService,
        IDateRangeService dateRangeService,
        ILocalizationService localizationService,
        ILocalizedModelFactory localizedModelFactory,
        IPickupPluginManager pickupPluginManager,
        IShippingPluginManager shippingPluginManager,
        IShippingService shippingService,
        IStateProvinceService stateProvinceService)
    {
        _addressModelFactory = addressModelFactory;
        _addressService = addressService;
        _countryService = countryService;
        _dateRangeService = dateRangeService;
        _localizationService = localizationService;
        _localizedModelFactory = localizedModelFactory;
        _pickupPluginManager = pickupPluginManager;
        _shippingPluginManager = shippingPluginManager;
        _shippingService = shippingService;
        _stateProvinceService = stateProvinceService;
    }

    #endregion

    #region Utilities

    /// 
    /// Prepare delivery date search model
    /// 
    /// Delivery date search model
    /// Delivery date search model
    protected virtual DeliveryDateSearchModel PrepareDeliveryDateSearchModel(DeliveryDateSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare page parameters
        searchModel.SetGridPageSize();

        return searchModel;
    }

    /// 
    /// Prepare product availability range search model
    /// 
    /// Product availability range search model
    /// Product availability range search model
    protected virtual ProductAvailabilityRangeSearchModel PrepareProductAvailabilityRangeSearchModel(ProductAvailabilityRangeSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare page parameters
        searchModel.SetGridPageSize();

        return searchModel;
    }

    #endregion

    #region Methods

    /// 
    /// Prepare shipping provider search model
    /// 
    /// Shipping provider search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the shipping provider search model
    /// 
    public virtual Task PrepareShippingProviderSearchModelAsync(ShippingProviderSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare page parameters
        searchModel.SetGridPageSize();

        return Task.FromResult(searchModel);
    }

    /// 
    /// Prepare paged shipping provider list model
    /// 
    /// Shipping provider search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the shipping provider list model
    /// 
    public virtual async Task PrepareShippingProviderListModelAsync(ShippingProviderSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //get shipping providers
        var shippingProviders = (await _shippingPluginManager.LoadAllPluginsAsync()).ToPagedList(searchModel);

        //prepare grid model
        var model = await new ShippingProviderListModel().PrepareToGridAsync(searchModel, shippingProviders, () =>
        {
            return shippingProviders.SelectAwait(async provider =>
            {
                //fill in model values from the entity
                var shippingProviderModel = provider.ToPluginModel();

                //fill in additional values (not existing in the entity)
                shippingProviderModel.IsActive = _shippingPluginManager.IsPluginActive(provider);
                shippingProviderModel.ConfigurationUrl = provider.GetConfigurationPageUrl();

                shippingProviderModel.LogoUrl = await _shippingPluginManager.GetPluginLogoUrlAsync(provider);

                return shippingProviderModel;
            });
        });

        return model;
    }

    /// 
    /// Prepare pickup point provider search model
    /// 
    /// Pickup point provider search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the pickup point provider search model
    /// 
    public virtual Task PreparePickupPointProviderSearchModelAsync(PickupPointProviderSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare page parameters
        searchModel.SetGridPageSize();

        return Task.FromResult(searchModel);
    }

    /// 
    /// Prepare paged pickup point provider list model
    /// 
    /// Pickup point provider search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the pickup point provider list model
    /// 
    public virtual async Task PreparePickupPointProviderListModelAsync(PickupPointProviderSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //get pickup point providers
        var pickupPointProviders = (await _pickupPluginManager.LoadAllPluginsAsync()).ToPagedList(searchModel);

        //prepare grid model
        var model = await new PickupPointProviderListModel().PrepareToGridAsync(searchModel, pickupPointProviders, () =>
        {
            return pickupPointProviders.SelectAwait(async provider =>
            {
                //fill in model values from the entity
                var pickupPointProviderModel = provider.ToPluginModel();

                //fill in additional values (not existing in the entity)
                pickupPointProviderModel.IsActive = _pickupPluginManager.IsPluginActive(provider);
                pickupPointProviderModel.ConfigurationUrl = provider.GetConfigurationPageUrl();

                pickupPointProviderModel.LogoUrl = await _pickupPluginManager.GetPluginLogoUrlAsync(provider);

                return pickupPointProviderModel;
            });
        });

        return model;
    }

    /// 
    /// Prepare shipping method search model
    /// 
    /// Shipping method search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the shipping method search model
    /// 
    public virtual Task PrepareShippingMethodSearchModelAsync(ShippingMethodSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare page parameters
        searchModel.SetGridPageSize();

        return Task.FromResult(searchModel);
    }

    /// 
    /// Prepare paged shipping method list model
    /// 
    /// Shipping method search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the shipping method list model
    /// 
    public virtual async Task PrepareShippingMethodListModelAsync(ShippingMethodSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //get shipping methods
        var shippingMethods = (await _shippingService.GetAllShippingMethodsAsync()).ToPagedList(searchModel);

        //prepare grid model
        var model = new ShippingMethodListModel().PrepareToGrid(searchModel, shippingMethods, () =>
        {
            return shippingMethods.Select(method => method.ToModel());
        });

        return model;
    }

    /// 
    /// Prepare shipping method model
    /// 
    /// Shipping method model
    /// Shipping method
    /// Whether to exclude populating of some properties of model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the shipping method model
    /// 
    public virtual async Task PrepareShippingMethodModelAsync(ShippingMethodModel model,
        ShippingMethod shippingMethod, bool excludeProperties = false)
    {
        Func localizedModelConfiguration = null;

        if (shippingMethod != null)
        {
            //fill in model values from the entity
            model ??= shippingMethod.ToModel();

            //define localized model configuration action
            localizedModelConfiguration = async (locale, languageId) =>
            {
                locale.Name = await _localizationService.GetLocalizedAsync(shippingMethod, entity => entity.Name, languageId, false, false);
                locale.Description = await _localizationService.GetLocalizedAsync(shippingMethod, entity => entity.Description, languageId, false, false);
            };
        }

        //prepare localized models
        if (!excludeProperties)
            model.Locales = await _localizedModelFactory.PrepareLocalizedModelsAsync(localizedModelConfiguration);

        return model;
    }

    /// 
    /// Prepare dates and ranges search model
    /// 
    /// Dates and ranges search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the dates and ranges search model
    /// 
    public virtual Task PrepareDatesRangesSearchModelAsync(DatesRangesSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare nested search models
        PrepareDeliveryDateSearchModel(searchModel.DeliveryDateSearchModel);
        PrepareProductAvailabilityRangeSearchModel(searchModel.ProductAvailabilityRangeSearchModel);

        return Task.FromResult(searchModel);
    }

    /// 
    /// Prepare paged delivery date list model
    /// 
    /// Delivery date search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the delivery date list model
    /// 
    public virtual async Task PrepareDeliveryDateListModelAsync(DeliveryDateSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //get delivery dates
        var deliveryDates = (await _dateRangeService.GetAllDeliveryDatesAsync()).ToPagedList(searchModel);

        //prepare grid model
        var model = new DeliveryDateListModel().PrepareToGrid(searchModel, deliveryDates, () =>
        {
            //fill in model values from the entity
            return deliveryDates.Select(date => date.ToModel());
        });

        return model;
    }

    /// 
    /// Prepare delivery date model
    /// 
    /// Delivery date model
    /// Delivery date
    /// Whether to exclude populating of some properties of model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the delivery date model
    /// 
    public virtual async Task PrepareDeliveryDateModelAsync(DeliveryDateModel model, DeliveryDate deliveryDate, bool excludeProperties = false)
    {
        Func localizedModelConfiguration = null;

        if (deliveryDate != null)
        {
            //fill in model values from the entity
            model ??= deliveryDate.ToModel();

            //define localized model configuration action
            localizedModelConfiguration = async (locale, languageId) =>
            {
                locale.Name = await _localizationService.GetLocalizedAsync(deliveryDate, entity => entity.Name, languageId, false, false);
            };
        }

        //prepare localized models
        if (!excludeProperties)
            model.Locales = await _localizedModelFactory.PrepareLocalizedModelsAsync(localizedModelConfiguration);

        return model;
    }

    /// 
    /// Prepare paged product availability range list model
    /// 
    /// Product availability range search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product availability range list model
    /// 
    public virtual async Task PrepareProductAvailabilityRangeListModelAsync(ProductAvailabilityRangeSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //get product availability ranges
        var productAvailabilityRanges = (await _dateRangeService.GetAllProductAvailabilityRangesAsync()).ToPagedList(searchModel);

        //prepare grid model
        var model = new ProductAvailabilityRangeListModel().PrepareToGrid(searchModel, productAvailabilityRanges, () =>
        {
            //fill in model values from the entity
            return productAvailabilityRanges.Select(range => range.ToModel());
        });

        return model;
    }

    /// 
    /// Prepare product availability range model
    /// 
    /// Product availability range model
    /// Product availability range
    /// Whether to exclude populating of some properties of model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product availability range model
    /// 
    public virtual async Task PrepareProductAvailabilityRangeModelAsync(ProductAvailabilityRangeModel model,
        ProductAvailabilityRange productAvailabilityRange, bool excludeProperties = false)
    {
        Func localizedModelConfiguration = null;

        if (productAvailabilityRange != null)
        {
            //fill in model values from the entity
            model ??= productAvailabilityRange.ToModel();

            //define localized model configuration action
            localizedModelConfiguration = async (locale, languageId) =>
            {
                locale.Name = await _localizationService.GetLocalizedAsync(productAvailabilityRange, entity => entity.Name, languageId, false, false);
            };
        }

        //prepare localized models
        if (!excludeProperties)
            model.Locales = await _localizedModelFactory.PrepareLocalizedModelsAsync(localizedModelConfiguration);

        return model;
    }

    /// 
    /// Prepare warehouse search model
    /// 
    /// Warehouse search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the warehouse search model
    /// 
    public virtual Task PrepareWarehouseSearchModelAsync(WarehouseSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //prepare page parameters
        searchModel.SetGridPageSize();

        return Task.FromResult(searchModel);
    }

    /// 
    /// Prepare paged warehouse list model
    /// 
    /// Warehouse search model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the warehouse list model
    /// 
    public virtual async Task PrepareWarehouseListModelAsync(WarehouseSearchModel searchModel)
    {
        ArgumentNullException.ThrowIfNull(searchModel);

        //get warehouses
        var warehouses = (await _shippingService.GetAllWarehousesAsync(
                name: searchModel.SearchName))
            .ToPagedList(searchModel);

        //prepare list model
        var model = new WarehouseListModel().PrepareToGrid(searchModel, warehouses, () =>
        {
            //fill in model values from the entity
            return warehouses.Select(warehouse => warehouse.ToModel());
        });

        return model;
    }

    /// 
    /// Prepare warehouse model
    /// 
    /// Warehouse model
    /// Warehouse
    /// Whether to exclude populating of some properties of model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the warehouse model
    /// 
    public virtual async Task PrepareWarehouseModelAsync(WarehouseModel model, Warehouse warehouse, bool excludeProperties = false)
    {
        if (warehouse != null)
        {
            //fill in model values from the entity
            if (model == null)
            {
                model = warehouse.ToModel();
            }
        }

        //prepare address model
        var address = await _addressService.GetAddressByIdAsync(warehouse?.AddressId ?? 0);
        if (!excludeProperties && address != null)
            model.Address = address.ToModel(model.Address);
        await _addressModelFactory.PrepareAddressModelAsync(model.Address, address);
        model.Address.CountryRequired = true;
        model.Address.ZipPostalCodeRequired = true;

        return model;
    }

    /// 
    /// Prepare shipping method restriction model
    /// 
    /// Shipping method restriction model
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the shipping method restriction model
    /// 
    public virtual async Task PrepareShippingMethodRestrictionModelAsync(ShippingMethodRestrictionModel model)
    {
        ArgumentNullException.ThrowIfNull(model);

        var countries = await _countryService.GetAllCountriesAsync(showHidden: true);
        model.AvailableCountries = await countries.SelectAwait(async country =>
        {
            var countryModel = country.ToModel();
            countryModel.NumberOfStates = (await _stateProvinceService.GetStateProvincesByCountryIdAsync(country.Id))?.Count ?? 0;

            return countryModel;
        }).ToListAsync();

        foreach (var shippingMethod in await _shippingService.GetAllShippingMethodsAsync())
        {
            model.AvailableShippingMethods.Add(shippingMethod.ToModel());
            foreach (var country in countries)
            {
                if (!model.Restricted.ContainsKey(country.Id))
                    model.Restricted[country.Id] = new Dictionary();

                model.Restricted[country.Id][shippingMethod.Id] = await _shippingService.CountryRestrictionExistsAsync(shippingMethod, country.Id);
            }
        }

        return model;
    }

    #endregion
}