Try your search with a different keyword or use * as a wildcard.
using Nop.Core;
using Nop.Core.Domain.Shipping;
using Nop.Plugin.Shipping.FixedByWeightByTotal.Domain;
using Nop.Plugin.Shipping.FixedByWeightByTotal.Services;
using Nop.Services.Configuration;
using Nop.Services.Localization;
using Nop.Services.Orders;
using Nop.Services.Plugins;
using Nop.Services.Shipping;
using Nop.Services.Shipping.Tracking;
namespace Nop.Plugin.Shipping.FixedByWeightByTotal;
///
/// Fixed rate or by weight shipping computation method
///
public class FixedByWeightByTotalComputationMethod : BasePlugin, IShippingRateComputationMethod
{
#region Fields
protected readonly FixedByWeightByTotalSettings _fixedByWeightByTotalSettings;
protected readonly ILocalizationService _localizationService;
protected readonly IShoppingCartService _shoppingCartService;
protected readonly ISettingService _settingService;
protected readonly IShippingByWeightByTotalService _shippingByWeightByTotalService;
protected readonly IShippingService _shippingService;
protected readonly IStoreContext _storeContext;
protected readonly IWebHelper _webHelper;
#endregion
#region Ctor
public FixedByWeightByTotalComputationMethod(FixedByWeightByTotalSettings fixedByWeightByTotalSettings,
ILocalizationService localizationService,
IShoppingCartService shoppingCartService,
ISettingService settingService,
IShippingByWeightByTotalService shippingByWeightByTotalService,
IShippingService shippingService,
IStoreContext storeContext,
IWebHelper webHelper)
{
_fixedByWeightByTotalSettings = fixedByWeightByTotalSettings;
_localizationService = localizationService;
_shoppingCartService = shoppingCartService;
_settingService = settingService;
_shippingByWeightByTotalService = shippingByWeightByTotalService;
_shippingService = shippingService;
_storeContext = storeContext;
_webHelper = webHelper;
}
#endregion
#region Utilities
///
/// Get fixed rate
///
/// Shipping method ID
///
/// A task that represents the asynchronous operation
/// The task result contains the rate
///
protected async Task GetRateAsync(int shippingMethodId)
{
return await _settingService.GetSettingByKeyAsync(string.Format(FixedByWeightByTotalDefaults.FIXED_RATE_SETTINGS_KEY, shippingMethodId));
}
///
/// Gets the transit days
///
/// Shipping method ID
///
/// A task that represents the asynchronous operation
/// The task result contains the ransit days
///
protected async Task GetTransitDaysAsync(int shippingMethodId)
{
return await _settingService.GetSettingByKeyAsync(string.Format(FixedByWeightByTotalDefaults.TRANSIT_DAYS_SETTINGS_KEY, shippingMethodId));
}
///
/// Get rate by weight and by total
///
/// Shipping by weight/by total record
/// Subtotal
/// Weight
/// Rate
protected decimal GetRate(ShippingByWeightByTotalRecord shippingByWeightByTotalRecord, decimal subTotal, decimal weight)
{
//additional fixed cost
var shippingTotal = shippingByWeightByTotalRecord.AdditionalFixedCost;
//charge amount per weight unit
if (shippingByWeightByTotalRecord.RatePerWeightUnit > decimal.Zero)
{
var weightRate = Math.Max(weight - shippingByWeightByTotalRecord.LowerWeightLimit, decimal.Zero);
shippingTotal += shippingByWeightByTotalRecord.RatePerWeightUnit * weightRate;
}
//percentage rate of subtotal
if (shippingByWeightByTotalRecord.PercentageRateOfSubtotal > decimal.Zero)
{
shippingTotal += Math.Round((decimal)((((float)subTotal) * ((float)shippingByWeightByTotalRecord.PercentageRateOfSubtotal)) / 100f), 2);
}
return Math.Max(shippingTotal, decimal.Zero);
}
#endregion
#region Methods
///
/// Gets available shipping options
///
/// A request for getting shipping options
///
/// A task that represents the asynchronous operation
/// The task result contains the represents a response of getting shipping rate options
///
public async Task GetShippingOptionsAsync(GetShippingOptionRequest getShippingOptionRequest)
{
ArgumentNullException.ThrowIfNull(getShippingOptionRequest);
var response = new GetShippingOptionResponse();
if (getShippingOptionRequest.Items == null || !getShippingOptionRequest.Items.Any())
{
response.AddError("No shipment items");
return response;
}
//choose the shipping rate calculation method
if (_fixedByWeightByTotalSettings.ShippingByWeightByTotalEnabled)
{
//shipping rate calculation by products weight
if (getShippingOptionRequest.ShippingAddress == null)
{
response.AddError("Shipping address is not set");
return response;
}
var store = await _storeContext.GetCurrentStoreAsync();
var storeId = getShippingOptionRequest.StoreId != 0 ? getShippingOptionRequest.StoreId : store.Id;
var countryId = getShippingOptionRequest.ShippingAddress.CountryId ?? 0;
var stateProvinceId = getShippingOptionRequest.ShippingAddress.StateProvinceId ?? 0;
var warehouseId = getShippingOptionRequest.WarehouseFrom?.Id ?? 0;
var zip = getShippingOptionRequest.ShippingAddress.ZipPostalCode;
//get subtotal of shipped items
var subTotal = decimal.Zero;
foreach (var packageItem in getShippingOptionRequest.Items)
{
if (await _shippingService.IsFreeShippingAsync(packageItem.ShoppingCartItem))
continue;
subTotal += (await _shoppingCartService.GetSubTotalAsync(packageItem.ShoppingCartItem, true)).subTotal;
}
//get weight of shipped items (excluding items with free shipping)
var weight = await _shippingService.GetTotalWeightAsync(getShippingOptionRequest, ignoreFreeShippedItems: true);
foreach (var shippingMethod in await _shippingService.GetAllShippingMethodsAsync(countryId))
{
int? transitDays = null;
var rate = decimal.Zero;
var shippingByWeightByTotalRecord = await _shippingByWeightByTotalService.FindRecordsAsync(
shippingMethod.Id, storeId, warehouseId, countryId, stateProvinceId, zip, weight, subTotal);
if (shippingByWeightByTotalRecord == null)
{
if (_fixedByWeightByTotalSettings.LimitMethodsToCreated)
continue;
}
else
{
rate = GetRate(shippingByWeightByTotalRecord, subTotal, weight);
transitDays = shippingByWeightByTotalRecord.TransitDays;
}
response.ShippingOptions.Add(new ShippingOption
{
Name = await _localizationService.GetLocalizedAsync(shippingMethod, x => x.Name),
Description = await _localizationService.GetLocalizedAsync(shippingMethod, x => x.Description),
Rate = rate,
TransitDays = transitDays
});
}
}
else
{
//shipping rate calculation by fixed rate
var restrictByCountryId = getShippingOptionRequest.ShippingAddress?.CountryId;
response.ShippingOptions = await (await _shippingService.GetAllShippingMethodsAsync(restrictByCountryId)).SelectAwait(async shippingMethod => new ShippingOption
{
Name = await _localizationService.GetLocalizedAsync(shippingMethod, x => x.Name),
Description = await _localizationService.GetLocalizedAsync(shippingMethod, x => x.Description),
Rate = await GetRateAsync(shippingMethod.Id),
TransitDays = await GetTransitDaysAsync(shippingMethod.Id)
}).ToListAsync();
}
return response;
}
///
/// Gets fixed shipping rate (if shipping rate computation method allows it and the rate can be calculated before checkout).
///
/// A request for getting shipping options
///
/// A task that represents the asynchronous operation
/// The task result contains the fixed shipping rate; or null in case there's no fixed shipping rate
///
public async Task GetFixedRateAsync(GetShippingOptionRequest getShippingOptionRequest)
{
ArgumentNullException.ThrowIfNull(getShippingOptionRequest);
//if the "shipping calculation by weight" method is selected, the fixed rate isn't calculated
if (_fixedByWeightByTotalSettings.ShippingByWeightByTotalEnabled)
return null;
var restrictByCountryId = getShippingOptionRequest.ShippingAddress?.CountryId;
var rates = await (await _shippingService.GetAllShippingMethodsAsync(restrictByCountryId))
.SelectAwait(async shippingMethod => await GetRateAsync(shippingMethod.Id)).Distinct().ToListAsync();
//return default rate if all of them equal
if (rates.Count == 1)
return rates.FirstOrDefault();
return null;
}
///
/// Get associated shipment tracker
///
///
/// A task that represents the asynchronous operation
/// The task result contains the shipment tracker
///
public Task GetShipmentTrackerAsync()
{
return Task.FromResult(null);
}
///
/// Gets a configuration page URL
///
public override string GetConfigurationPageUrl()
{
return $"{_webHelper.GetStoreLocation()}Admin/FixedByWeightByTotal/Configure";
}
///
/// Install plugin
///
/// A task that represents the asynchronous operation
public override async Task InstallAsync()
{
//settings
await _settingService.SaveSettingAsync(new FixedByWeightByTotalSettings
{
LoadAllRecord = true,
});
//locales
await _localizationService.AddOrUpdateLocaleResourceAsync(new Dictionary
{
["Plugins.Shipping.FixedByWeightByTotal.AddRecord"] = "Add record",
["Plugins.Shipping.FixedByWeightByTotal.Fields.AdditionalFixedCost"] = "Additional fixed cost",
["Plugins.Shipping.FixedByWeightByTotal.Fields.AdditionalFixedCost.Hint"] = "Specify an additional fixed cost per shopping cart for this option. Set to 0 if you don't want an additional fixed cost to be applied.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Country"] = "Country",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Country.Hint"] = "If an asterisk is selected, then this shipping rate will apply to all customers, regardless of the country.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.DataHtml"] = "Data",
["Plugins.Shipping.FixedByWeightByTotal.Fields.LimitMethodsToCreated"] = "Limit shipping methods to configured ones",
["Plugins.Shipping.FixedByWeightByTotal.Fields.LimitMethodsToCreated.Hint"] = "If you check this option, then your customers will be limited to shipping options configured here. Otherwise, they'll be able to choose any existing shipping options even they are not configured here (zero shipping fee in this case).",
["Plugins.Shipping.FixedByWeightByTotal.Fields.LowerWeightLimit"] = "Lower weight limit",
["Plugins.Shipping.FixedByWeightByTotal.Fields.LowerWeightLimit.Hint"] = "Lower weight limit. This field can be used for \"per extra weight unit\" scenarios.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.OrderSubtotalFrom"] = "Order subtotal from",
["Plugins.Shipping.FixedByWeightByTotal.Fields.OrderSubtotalFrom.Hint"] = "Order subtotal from.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.OrderSubtotalTo"] = "Order subtotal to",
["Plugins.Shipping.FixedByWeightByTotal.Fields.OrderSubtotalTo.Hint"] = "Order subtotal to.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.PercentageRateOfSubtotal"] = "Charge percentage (of subtotal)",
["Plugins.Shipping.FixedByWeightByTotal.Fields.PercentageRateOfSubtotal.Hint"] = "Charge percentage (of subtotal).",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Rate"] = "Rate",
["Plugins.Shipping.FixedByWeightByTotal.Fields.RatePerWeightUnit"] = "Rate per weight unit",
["Plugins.Shipping.FixedByWeightByTotal.Fields.RatePerWeightUnit.Hint"] = "Rate per weight unit.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.ShippingMethod"] = "Shipping method",
["Plugins.Shipping.FixedByWeightByTotal.Fields.ShippingMethod.Hint"] = "Choose shipping method.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.StateProvince"] = "State / province",
["Plugins.Shipping.FixedByWeightByTotal.Fields.StateProvince.Hint"] = "If an asterisk is selected, then this shipping rate will apply to all customers from the given country, regardless of the state.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Store"] = "Store",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Store.Hint"] = "If an asterisk is selected, then this shipping rate will apply to all stores.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.TransitDays"] = "Transit days",
["Plugins.Shipping.FixedByWeightByTotal.Fields.TransitDays.Hint"] = "The number of days of delivery of the goods.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Warehouse"] = "Warehouse",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Warehouse.Hint"] = "If an asterisk is selected, then this shipping rate will apply to all warehouses.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.WeightFrom"] = "Order weight from",
["Plugins.Shipping.FixedByWeightByTotal.Fields.WeightFrom.Hint"] = "Order weight from.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.WeightTo"] = "Order weight to",
["Plugins.Shipping.FixedByWeightByTotal.Fields.WeightTo.Hint"] = "Order weight to.",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Zip"] = "Zip",
["Plugins.Shipping.FixedByWeightByTotal.Fields.Zip.Hint"] = "Zip / postal code. If zip is empty, then this shipping rate will apply to all customers from the given country or state, regardless of the zip code.",
["Plugins.Shipping.FixedByWeightByTotal.Fixed"] = "Fixed Rate",
["Plugins.Shipping.FixedByWeightByTotal.Formula"] = "Formula to calculate rates",
["Plugins.Shipping.FixedByWeightByTotal.Formula.Value"] = "[additional fixed cost] + ([order total weight] - [lower weight limit]) * [rate per weight unit] + [order subtotal] * [charge percentage]",
["Plugins.Shipping.FixedByWeightByTotal.ShippingByWeight"] = "By Weight"
});
await base.InstallAsync();
}
///
/// Uninstall plugin
///
/// A task that represents the asynchronous operation
public override async Task UninstallAsync()
{
//settings
await _settingService.DeleteSettingAsync();
//fixed rates
var fixedRates = await (await _shippingService.GetAllShippingMethodsAsync())
.SelectAwait(async shippingMethod => await _settingService.GetSettingAsync(
string.Format(FixedByWeightByTotalDefaults.FIXED_RATE_SETTINGS_KEY, shippingMethod.Id)))
.Where(setting => setting != null).ToListAsync();
await _settingService.DeleteSettingsAsync(fixedRates);
//locales
await _localizationService.DeleteLocaleResourcesAsync("Plugins.Shipping.FixedByWeightByTotal");
await base.UninstallAsync();
}
#endregion
}