So I'll need to somehow automatically set the currency on each language, i.e. prices should be in DKK on the Danish site, EUR on the Dutch site and English site.
I figured I would do something like this
using System;
using Umbraco.Core.Composing;
using Umbraco.Web.Routing;
using Vendlet.Library.Extensions;
using Vendr.Core;
using Vendr.Core.Services;
using Vendr.Core.Session;
namespace Vendlet.Library.Composers
{
class PublishedRequestComposer : ComponentComposer<PublishedRequestComponent>
{
}
public class PublishedRequestComponent : IComponent
{
private readonly ISessionManager _sessionManager;
private readonly IUnitOfWorkProvider _uowProvider;
private readonly IOrderService _orderService;
public PublishedRequestComponent(ISessionManager sessionManager,
IUnitOfWorkProvider uowProvider,
IOrderService orderService)
{
_sessionManager = sessionManager;
_uowProvider = uowProvider;
_orderService = orderService;
}
public void Initialize()
{
PublishedRequest.Prepared += PublishedRequest_Prepared;
}
private void PublishedRequest_Prepared(object sender, EventArgs e)
{
var request = sender as PublishedRequest;
var content = request.PublishedContent;
//Use PublishedContentExtension to get store
var store = content.GetStore();
//Use PublishedContentExtension to get root node
var site = content.GetSite();
//Vendr Store EntityPicket set to Currency
var currency = site.Currency;
// applyToCurrentOrder does not seem to work, so we need to change it on the existing order first, or else we'll get an error
var currentOrder = _sessionManager.GetCurrentOrder(store.Id);
if (currentOrder != null)
{
using (var uow = _uowProvider.Create())
{
var order = currentOrder.AsWritable(uow).SetCurrency(currency);
_orderService.SaveOrder(order);
uow.Complete();
}
}
_sessionManager.SetDefaultCurrency(store.Id, currency.Id, applyToCurrentOrder: true);
}
public void Terminate()
{
//unsubscribe during shutdown
PublishedRequest.Prepared -= PublishedRequest_Prepared;
}
}
}
Which works.
I do wonder why the applyToCurrentOrder does not work, I don't know if I'm misunderstanding what it does?
I'm also not sure if there's a better way than to use PublishedRequest.Prepared?
I'm guessing it's caused by when using the SetDefault methods, they do not change the default currency/country if the current is not allowed.
But it must somehow do that when changing it on the current order 🤷♂️
But the code in my original post works fine, so I'll stick with that. I don't know what the overhead of those calls are, but I'm thinking instead of doing it at every page request, then maybe saving current culture in a cookie, and only set the currency if the culture changes.
Correction, I do have to use both SetDefaultCurrency and SetDefaultCurrency, or else the currency won't switch when having no current order.
So the full working code, for anyone else who might need something similar, is this:
using System;
using System.Web;
using Umbraco.Core.Composing;
using Umbraco.Web.Routing;
using Vendlet.Library.Extensions;
using Vendr.Core;
using Vendr.Core.Services;
using Vendr.Core.Session;
namespace Vendlet.Library.Composers
{
class PublishedRequestComposer : ComponentComposer<PublishedRequestComponent>
{
}
public class PublishedRequestComponent : IComponent
{
private readonly ISessionManager _sessionManager;
private readonly IUnitOfWorkProvider _uowProvider;
private readonly IOrderService _orderService;
private readonly HttpContextBase _httpContextBase;
public PublishedRequestComponent(ISessionManager sessionManager,
IUnitOfWorkProvider uowProvider,
IOrderService orderService,
HttpContextBase httpContextBase)
{
_sessionManager = sessionManager;
_uowProvider = uowProvider;
_orderService = orderService;
_httpContextBase = httpContextBase;
}
public void Initialize()
{
PublishedRequest.Prepared += PublishedRequest_Prepared;
}
private void PublishedRequest_Prepared(object sender, EventArgs e)
{
var request = sender as PublishedRequest;
HttpCookie language = _httpContextBase.Request.Cookies["language"];
var currentCulture = request.Culture.TwoLetterISOLanguageName;
//If the culture has been changed
if (language == null || language.Value != currentCulture)
{
var content = request.PublishedContent;
//Use PublishedContentExtension to get store
var store = content.GetStore();
//Use PublishedContentExtension to get root node
var site = content.GetSite();
//Vendr Store EntityPicket set to Currency
var currency = site.Currency;
//Vendr Store EntityPicket set to Country
var country = site.Country;
// applyToCurrentOrder does not seem to work, so we need to change currency on the current order, or else we get an error
var currentOrder = _sessionManager.GetCurrentOrder(store.Id);
if (currentOrder != null)
{
using (var uow = _uowProvider.Create())
{
var order = currentOrder.AsWritable(uow).SetCurrency(currency);
_orderService.SaveOrder(order);
uow.Complete();
}
}
//Set default, will be used when there is no current order
_sessionManager.SetDefaultPaymentCountry(store.Id, country.Id, applyToCurrentOrder: true);
_sessionManager.SetDefaultCurrency(store.Id, currency.Id, applyToCurrentOrder: true);
//Set cookie value to new language
language = new HttpCookie("language");
language.Value = currentCulture;
_httpContextBase.Response.SetCookie(language);
}
}
public void Terminate()
{
//unsubscribe during shutdown
PublishedRequest.Prepared -= PublishedRequest_Prepared;
}
}
}
Default currencies for multiple languages
I have a solution with 3 languages, Danish, Dutch and English, and need the currency to be different on these languages.
Unfortunately, as of now, the Store Picker cannot be varied by culture https://github.com/vendrhub/vendr/issues/276
So I'll need to somehow automatically set the currency on each language, i.e. prices should be in DKK on the Danish site, EUR on the Dutch site and English site.
I figured I would do something like this
Which works.
I do wonder why the
applyToCurrentOrder
does not work, I don't know if I'm misunderstanding what it does?I'm also not sure if there's a better way than to use
PublishedRequest.Prepared
?Any input would be welcome...
Hey Michael,
That's a really clever solution and I think hooking into the request pipeline is a great approach 👍
I'd be interested to know what error you are seeing when using
applyToCurrentOrder
?Internally, the SetDefaultCurrency method isn't too far different to what you have
Unless it's an issue with the default payment country check 🤔
Well using
alone, actually doesn't do anything, it does not switch the currency.
Using
works fine, and does switch the currency.
Until you put something in the cart on one language, and switches to the other, then I get an error saying
Can't set order country / region to one not allowed by the order Currency
https://prnt.sc/10dhzp2
I'm guessing it's caused by when using the SetDefault methods, they do not change the default currency/country if the current is not allowed. But it must somehow do that when changing it on the current order 🤷♂️
But the code in my original post works fine, so I'll stick with that. I don't know what the overhead of those calls are, but I'm thinking instead of doing it at every page request, then maybe saving current culture in a cookie, and only set the currency if the culture changes.
Correction, I do have to use both
SetDefaultCurrency
andSetDefaultCurrency
, or else the currency won't switch when having no current order.So the full working code, for anyone else who might need something similar, is this:
Interesting!
Thanks for sharing this, I'll defo look into why
applyToCurrentOrder
isn't doing what it should.Matt
PS I've raised this as an issue on our issue tracker, linking back to this forum post for us to keep track of this https://github.com/vendrhub/vendr/issues/278
Thanks again for the explanation.
is working on a reply...