Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
AI OnAI Off
Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
Hi Noel,
I am not sure why you are getting reference key error, could you please try below code.
public class CreateShippingMethod
{
private readonly IMarketService _marketService;
public CreateShippingMethod(IMarketService marketService)
{
_marketService = marketService ?? throw new ArgumentNullException(nameof(marketService));
}
public void ConfigureShippingMethods()
{
var enabledMarkets = _marketService.GetAllMarkets().Where(x => x.IsEnabled).ToList();
foreach (var language in enabledMarkets.SelectMany(x => x.Languages).Distinct())
{
var languageId = language.TwoLetterISOLanguageName;
var dto = ShippingManager.GetShippingMethods(languageId);
var workingDto = (ShippingMethodDto)dto.Copy();
this.DeleteShippingMethods(workingDto);
ShippingManager.SaveShipping(workingDto);
var marketsForCurrentLanguage = enabledMarkets.Where(x => x.Languages.Contains(language)).ToList();
var shippingSet = this.CreateShippingMethodsForLanguageAndCurrencies(workingDto, marketsForCurrentLanguage, languageId);
ShippingManager.SaveShipping(workingDto);
AssociateShippingMethodWithMarkets(workingDto, marketsForCurrentLanguage, shippingSet);
ShippingManager.SaveShipping(workingDto);
}
}
private void DeleteShippingMethods(ShippingMethodDto dto)
{
foreach (var method in dto.ShippingMethod)
{
method.Delete();
}
}
private IEnumerable<ShippingMethodDto.ShippingMethodRow> CreateShippingMethodsForLanguageAndCurrencies(ShippingMethodDto dto, IEnumerable<IMarket> markets, string languageId)
{
var shippingOption = dto.ShippingOption.First(x => x.Name == "Generic Gateway");
var shippingMethods = new List<ShippingMethodDto.ShippingMethodRow>();
var sortOrder = 1;
//TODO: Add wishing price and currency
var usdCostExpress = new Money(20, Currency.USD);
foreach (var currency in markets.SelectMany(m => m.Currencies).Distinct())
{
shippingMethods.Add(this.Create(dto, shippingOption, languageId, sortOrder++,
"Express-" + currency, $"Express {currency} (1 day)({languageId})", usdCostExpress, currency));
// TODO: Add more shipping methods.
}
return shippingMethods;
}
private ShippingMethodDto.ShippingMethodRow Create(ShippingMethodDto dto,
ShippingMethodDto.ShippingOptionRow shippingOption, string languageId, int sortOrder, string name,
string description, Money costInUsd, Currency currency)
{
Money shippingCost = CurrencyFormatter.ConvertCurrency(costInUsd, currency);
if (shippingCost.Currency != currency)
{
throw new InvalidOperationException("Cannot convert to currency " + currency + " Missing conversion data.");
}
return dto.ShippingMethod.AddShippingMethodRow(
Guid.NewGuid(),
shippingOption,
languageId,
true,
name,
"",
shippingCost.Amount,
shippingCost.Currency,
description,
false,
sortOrder,
DateTime.Now,
DateTime.Now);
}
private void AssociateShippingMethodWithMarkets(ShippingMethodDto dto, IEnumerable<IMarket> markets,
IEnumerable<ShippingMethodDto.ShippingMethodRow> shippingSet)
{
foreach (var shippingMethod in shippingSet)
{
foreach (var market in markets?.Where(m => m.Currencies.Contains(shippingMethod.Currency)))
{
dto.MarketShippingMethods.AddMarketShippingMethodsRow(market.MarketId.Value, shippingMethod);
}
}
}
}
Thank you Sanjay,
i actually found code very similar to that here and adapted it too only create a single shipping method with the string i give it (all my shipping methods are 'discovered' during import from another system)
using EPiServer.ServiceLocation;
using Mediachase.Commerce;
using Mediachase.Commerce.Markets;
using Mediachase.Commerce.Orders.Dto;
using Mediachase.Commerce.Orders.Managers;
using Mediachase.Commerce.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
public class ShippingMethodHelper
{
#region singleton
private static readonly Lazy<ShippingMethodHelper> lazy = new Lazy<ShippingMethodHelper>(() =>
{
return new ShippingMethodHelper();
});
public static ShippingMethodHelper Instance => lazy.Value;
#endregion
public void ConfigureShippingMethods(string methodName)
{
var marketService = ServiceLocator.Current.GetInstance<IMarketService>();
var enabledMarkets = marketService.GetAllMarkets().Where(x => x.IsEnabled).ToList();
foreach (var language in enabledMarkets.SelectMany(x => x.Languages).Distinct())
{
var languageId = language.TwoLetterISOLanguageName;
var dto = ShippingManager.GetShippingMethods(languageId);
var workingDto = (ShippingMethodDto)dto.Copy();
//DeleteShippingMethods(workingDto);
//ShippingManager.SaveShipping(workingDto);
var marketsForCurrentLanguage = enabledMarkets.Where(x => x.Languages.Contains(language)).ToList();
var shippingSet = CreateShippingMethodForLanguageAndCurrencies(workingDto, marketsForCurrentLanguage, languageId, methodName);
ShippingManager.SaveShipping(workingDto);
AssociateShippingMethodWithMarkets(workingDto, marketsForCurrentLanguage, shippingSet);
ShippingManager.SaveShipping(workingDto);
}
}
private IEnumerable<ShippingMethodDto.ShippingMethodRow> CreateShippingMethodForLanguageAndCurrencies(ShippingMethodDto dto, IEnumerable<IMarket> markets, string languageId, string methodName)
{
var shippingOption = dto.ShippingOption.First(x => x.Name == "Generic Gateway");
var shippingMethods = new List<ShippingMethodDto.ShippingMethodRow>();
var sortOrder = 1;
foreach (var currency in markets.SelectMany(m => m.Currencies).Distinct())
{
shippingMethods.Add(CreateShippingMethod(dto, shippingOption, languageId, 0, methodName, methodName, new Money(0, Currency.GBP), currency));
}
return shippingMethods;
}
private ShippingMethodDto.ShippingMethodRow CreateShippingMethod(ShippingMethodDto dto, ShippingMethodDto.ShippingOptionRow shippingOption, string languageId, int sortOrder, string name, string description, Money costInUsd, Currency currency)
{
Money shippingCost = CurrencyFormatter.ConvertCurrency(costInUsd, currency);
if (shippingCost.Currency != currency)
{
throw new InvalidOperationException("Cannot convert to currency " + currency + " Missing conversion data.");
}
return dto.ShippingMethod.AddShippingMethodRow(
Guid.NewGuid(),
shippingOption,
languageId,
true,
name,
"",
shippingCost.Amount,
shippingCost.Currency,
description,
false,
sortOrder,
DateTime.Now,
DateTime.Now);
}
private void AssociateShippingMethodWithMarkets(ShippingMethodDto dto, IEnumerable<IMarket> markets, IEnumerable<ShippingMethodDto.ShippingMethodRow> shippingSet)
{
foreach (var shippingMethod in shippingSet)
{
foreach (var market in markets.Where(m => m.Currencies.Contains(shippingMethod.Currency)))
{
dto.MarketShippingMethods.AddMarketShippingMethodsRow(market.MarketId.Value, shippingMethod);
}
}
}
I'm getting this error:
"ForeignKeyConstraint FK_ShippingOption_ShippingMethod requires the child key values (18ede71f-3df3-4d9e-a4cb-3d25881c1ec6) to exist in the parent table."
and here is my code:
private ShippingMethodDto.ShippingMethodRow CreateShippingMethod(string shippingMethodName, Guid shippingOptionID) { ShippingMethodDto shippingMethod = new ShippingMethodDto(); ShippingMethodDto.ShippingMethodRow shippingMethodRow = shippingMethod.ShippingMethod.NewShippingMethodRow(); shippingMethodRow[shippingMethod.ShippingMethod.ShippingMethodIdColumn] = Guid.NewGuid(); shippingMethodRow[shippingMethod.ShippingMethod.LanguageIdColumn] = LanguageId; shippingMethodRow[shippingMethod.ShippingMethod.NameColumn] = shippingMethodName; shippingMethodRow[shippingMethod.ShippingMethod.DisplayNameColumn] = shippingMethodName; shippingMethodRow[shippingMethod.ShippingMethod.DescriptionColumn] = ""; //shippingMethodRow[shippingMethod.ShippingMethod.CurrencyColumn] = shippingMethodInfo.Currency; shippingMethodRow[shippingMethod.ShippingMethod.BasePriceColumn] = 0m; shippingMethodRow[shippingMethod.ShippingMethod.ShippingOptionIdColumn]= shippingOptionID; shippingMethodRow[shippingMethod.ShippingMethod.IsActiveColumn] = true; shippingMethodRow[shippingMethod.ShippingMethod.IsDefaultColumn] = false; //shippingMethodRow[shippingMethod.ShippingMethod.OrderingColumn] = shippingMethodInfo.Ordering; shippingMethodRow[shippingMethod.ShippingMethod.CreatedColumn] = DateTime.UtcNow; //TODO shippingMethodRow[shippingMethod.ShippingMethod.ModifiedColumn] = DateTime.UtcNow; //TODO shippingMethod.ShippingMethod.Rows.Add(shippingMethodRow); ShippingManager.SaveShipping(shippingMethod); return shippingMethodRow; } // used like this: var methods = ShippingManager.GetShippingMethodsByMarket(currentMarket.GetCurrentMarket().MarketId.Value, true); shippingMethod = CreateShippingMethod("deliveryMethodName", methods.ShippingOption[0].ShippingOptionId);
it's essentially complaining about the shipping Option ID that i'm passing in, but that ID is being loaded via EPiServer libs anyway. What am i missing?