I want to create my own ordernumber for the orders, and I am trying to implement/override the IOrderNumberGenerator. But for some reason my class doesn't get hit and it uses the default one.
This is what i currently have, but I also tried extending the DateHashOrderNumberGenerator, and override the methods, but I wasn't allowed to do so. I am currently running Vendr 2.3.4 :)
public class OrderNumberGenerator : IOrderNumberGenerator
{
private readonly UmbracoHelper _umbracoHelper;
private readonly DateHashOrderNumberGenerator _generator;
private readonly IContentService _contentService;
private readonly IPublishedContent _checkoutPage;
public OrderNumberGenerator(DateHashOrderNumberGenerator generator, UmbracoHelper umbracoHelper, IContentService contentService)
{
_generator = generator;
_contentService = contentService;
_umbracoHelper = umbracoHelper;
_checkoutPage = _umbracoHelper.ContentAtXPath($"//{VendrCheckoutCheckoutPage.ModelTypeAlias}")?.FirstOrDefault();
}
public string GenerateCartNumber(Guid storeId)
{
var cartNumber = _generator.GenerateCartNumber(storeId);
return cartNumber;
}
public string GenerateOrderNumber(Guid storeId)
{
int number = _checkoutPage.Value<int>("CurrentOrderNumber");
var contentPage = _contentService.GetById(_checkoutPage.Id);
contentPage.SetValue("CurrentOrderNumber", number + 1);
_contentService.SaveAndPublish(contentPage);
return number.ToString();
}
}
Ok, so you probably won't be able to inject the DateHashOrderNumberGenerator as it's not currently registered in the DI container as a concrete reference, it's only exposed as the default IOrderNumberGenerator so it's probably best to inherit from it if you don't want to replace how the cart numbers are generated.
What does your code look like to register this with the DI container?
By the way, storing the current order number on the checkout page is a REALLY bad idea.
Saving and publishing a node to store user generated data is not a recomended approach. Saving and publishing is an expensive task so you are using a lot of processes just to track the current order number. Under load I think you'd end up with a pretty serious bottleneck and potentially duplicate order numbers given your code isn't trasnactional either.
If you really want sequential order numbers I'd probably say to store them in a custom DB table.
Alright, I've changed my code to this (thanks for the headsup on custom DB table):
public class OrderNumberGenerator : DateHashOrderNumberGenerator
{
public OrderNumberGenerator(IStoreService storeService) : base(storeService)
{
}
public string GenerateOrderNumber(Guid storeId)
{
int number = 202200001;
//int number = _checkoutPage.Value<int>("CurrentOrderNumber");
//var contentPage = _contentService.GetById(_checkoutPage.Id);
//contentPage.SetValue("CurrentOrderNumber", number + 1);
//_contentService.SaveAndPublish(contentPage);
return number.ToString();
}
}
I actually forget registering it, but I still can't get it to work.
Have tried both:
[ComposeAfter(typeof(VendrComposer))]
public class StoreComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.AddNotificationHandler<UmbracoApplicationStartingNotification, TransformExamineValues>()
//.... bunch of other i register
builder.Services.AddUnique<IOrderNumberGenerator, OrderNumberGenerator>();
}
}
I am ordering a product, which will be paid by invoicing. I have the checkout package (which works great), and when I get to the confirmation page it shows the ordernumber based on the Order Number Template field in de Backoffice.
I have a breakpoint in my own method, which isn't being hit.
Yea, I think so long as you hi the review stage of the checkout, that is when the order number is assigned.
The usual thing people forget in the composer is the [ComposeAfter(typeof(VendrComposer))] but you have that so that should be fine. And everything else looks about right to me.
Just checked, but my composer is indeed being hit.
Just to be sure, let me post the code again which I currently have. Maybe I mixed something up during this convo :)
Composer:
[ComposeAfter(typeof(VendrComposer))]
public class StoreComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
// bunch of registers
builder.Services.AddUnique<IOrderNumberGenerator, OrderNumberGenerator>();
}
}
The actual generator:
public class OrderNumberGenerator : DateHashOrderNumberGenerator
{
public OrderNumberGenerator(IStoreService storeService) : base(storeService)
{
}
public string GenerateOrderNumber(Guid storeId)
{
int number = 202200001;
//int number = _checkoutPage.Value<int>("CurrentOrderNumber");
//var contentPage = _contentService.GetById(_checkoutPage.Id);
//contentPage.SetValue("CurrentOrderNumber", number + 1);
//_contentService.SaveAndPublish(contentPage);
return number.ToString();
}
}
Ahh, good point. Looks like I haven't made those virtual.
You could instead then not inherit from the DateHashOrderNumberGenerator but instead in your constructor instantiate an instance manually, it should just need an IStoreService dependency.
public class OrderNumberGenerator : IOrderNumberGenerator
{
private readonly IOrderNumberGenerator _defaultGenerator;
public OrderNumberGenerator(IStoreService storeService)
{
_defaultGenerator = new DateHashOrderNumberGenerator(storeService);
}
public string GenerateCartNumber(Guido storeId)
=> _defaultGenerator.GenerateCartNumber(storeId);
public string GenerateOrderNumber(Guid storeId)
{
int number = 202200001;
//int number = _checkoutPage.Value<int>("CurrentOrderNumber");
//var contentPage = _contentService.GetById(_checkoutPage.Id);
//contentPage.SetValue("CurrentOrderNumber", number + 1);
//_contentService.SaveAndPublish(contentPage);
return number.ToString();
}
}
I can't really see anything wrong with your setup otherwise
Override IOrderNumberGenerator
Hi Matt,
I want to create my own ordernumber for the orders, and I am trying to implement/override the IOrderNumberGenerator. But for some reason my class doesn't get hit and it uses the default one.
I can't figure out what I am doing wrong :)
Thanks!
Puck
Hey Puck,
Please can you share what you've tried?
Hey Matt,
Sure thing!
This is what i currently have, but I also tried extending the DateHashOrderNumberGenerator, and override the methods, but I wasn't allowed to do so. I am currently running Vendr 2.3.4 :)
Ok, so you probably won't be able to inject the
DateHashOrderNumberGenerator
as it's not currently registered in the DI container as a concrete reference, it's only exposed as the defaultIOrderNumberGenerator
so it's probably best to inherit from it if you don't want to replace how the cart numbers are generated.What does your code look like to register this with the DI container?
By the way, storing the current order number on the checkout page is a REALLY bad idea.
Saving and publishing a node to store user generated data is not a recomended approach. Saving and publishing is an expensive task so you are using a lot of processes just to track the current order number. Under load I think you'd end up with a pretty serious bottleneck and potentially duplicate order numbers given your code isn't trasnactional either.
If you really want sequential order numbers I'd probably say to store them in a custom DB table.
Lastly regarding sequential order numbers, I'd highly recommend reading this forum post https://our.umbraco.com/packages/website-utilities/vendr/vendr-support/102060-changing-order-number-format#comment-319300
Matt
Alright, I've changed my code to this (thanks for the headsup on custom DB table):
I actually forget registering it, but I still can't get it to work. Have tried both:
as well as
The latter is the correct registration code to use.
What version of Umbraco / Vendr is this?
Sorry, was on a lunch break :)
I am using Umbraco 10.1.0 and Vendr 2.3.4
Ok, are you registering your dependencies by calling AddVendr on the Umbraco builder? Or using a composer?
I am using a composer to register them
Hmmm, that should be working then 🤔
How are you testing whether your generator works?
hmmm..
I am ordering a product, which will be paid by invoicing. I have the checkout package (which works great), and when I get to the confirmation page it shows the ordernumber based on the Order Number Template field in de Backoffice.
I have a breakpoint in my own method, which isn't being hit.
Yea, I think so long as you hi the review stage of the checkout, that is when the order number is assigned.
The usual thing people forget in the composer is the
[ComposeAfter(typeof(VendrComposer))]
but you have that so that should be fine. And everything else looks about right to me.I take it your composer is getting hit?
Just checked, but my composer is indeed being hit.
Just to be sure, let me post the code again which I currently have. Maybe I mixed something up during this convo :)
Composer:
The actual generator:
Is it because I cannot override the base GenerateOrderNumber from the DateHashOrderNumberGenerator?
With the ShippingCalculator I override the original method, but with this one I can't.
Ahh, good point. Looks like I haven't made those virtual.
You could instead then not inherit from the
DateHashOrderNumberGenerator
but instead in your constructor instantiate an instance manually, it should just need anIStoreService
dependency.I can't really see anything wrong with your setup otherwise
Awesome! This works!
Thanks again Matt
Excellent! Glad we were able to get there 👍
is working on a reply...