Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Michael Nielsen 153 posts 810 karma points
    Sep 22, 2021 @ 08:31
    Michael Nielsen
    0

    Error deleting orders where products no longer exist

    We've created a Dashboard, so our customer can delete all orders before a date that they select.

    It's both to comply with GDPR, but also to keep the DB somewhat tidy, as they get a lot of orders.

    It has worked fine previously, but not anymore, we've upgraded not too long ago, so I suspect that is probably why it stopped working.

    The error we get is this:

    System.ArgumentException: The product doesn't have a Store ID associated with it. Remember to add the Vendr store picker to your Umbraco content tree.
       at Vendr.Web.Adapters.UmbracoProductSnapshot.<>c__DisplayClass42_0.<.ctor>b__0()
       at System.Lazy`1.CreateValue()
       at System.Lazy`1.LazyInitValue()
       at System.Lazy`1.get_Value()
       at Vendr.Web.Adapters.UmbracoProductSnapshot.get_StoreId()
       at Vendr.Web.Services.UmbracoStockService.EnsureTargetProductReferences(String& productReference, String& productVariantReference)
       at Vendr.Web.Services.UmbracoStockService.IncreaseStock(String productReference, String productVariantReference, Decimal increaseBy)
       at Vendr.Core.Services.ProductService.IncreaseProductStock(String productReference, String productVariantReference, Decimal increaseBy)
       at Vendr.Core.Events.Domain.Handlers.Order.RevertOrderStockLevels.RevertOrderLineStockLevelsRecursive(OrderLineReadOnly orderLine, Decimal parentQuantity)
       at Vendr.Core.Events.Domain.Handlers.Order.RevertOrderStockLevels.Handle(OrderDeleted evt)
       at Vendr.Core.Events.Domain.DomainEventHandlerBase`1.Vendr.Core.Events.IEventHandler.Handle(IEvent evt)
       at Vendr.Core.Events.InProcEventDispatcher.Dispatch[T](IEnumerable`1 handlers, T evt)
       at Vendr.Core.Events.EventBus.Dispatch[T](T evt)
       at Vendr.Core.Services.ServiceBase.RaiseDomainEvents(IEnumerable`1 events)
       at Vendr.Core.Services.ServiceBase.RaiseDomainEvents(IDomainEvent[] events)
       at Vendr.Core.Services.ServiceBase.RaiseDomainEvent(IDomainEvent events)
       at Vendr.Core.Services.OrderService.DeleteOrder(Order entity, Boolean revertFinalized)
       at Vendr.Core.Services.OrderService.DeleteOrder(Guid id, Boolean revertFinalized)
       at Vendr.Core.Services.OrderService.DeleteOrder(Guid id)
       at FolkeuniversitetetKbh.Library.ApiControllers.Backoffice.MaintenanceController.DeleteOrders(Nullable`1 date)
       at lambda_method(Closure , Object , Object[] )
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_3.<GetExecutor>b__3(Object instance, Object[] methodParameters)
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
    

    It almost looks as if it's trying to update the stock levels of a product? And the error then comes, because the product does not does not exist anymore, but even if it did, it should definitely not update the stock!

    I even get the error, when trying to delete a single order through the backend https://prnt.sc/1t7fl5w

    So, the questions are now:

    • How do I delete orders?
    • How do I delete orders, when the products does not exists anymore?
    • How do I delete orders, without the stock being updated? (if that is really what it's doing)

    Umbraco 8.12.3, Vendr 1.7.2

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Sep 22, 2021 @ 08:41
    Matt Brailsford
    100

    Hi Michael,

    Hmm, yea, we currently have it setup that if you delete and order it attempts to revert the order stock level, but I guess this isn't actually what we want (or at least this should be configurable at point of delete).

    So I think if you upgrade to the Vendr 1.8.1 or later that logic was updated to use a TryIncreaseStock method which should now fail silently, but if you want to remove that handler completely, you can upgrade to 1.8.3 where we made a remove method available on our event handler collection builder and then in a composer call

    compostion.WithDomainEvent<OrderDeleted>()
        .Remove<RevertOrderStockLevels>();
    

    Hope this helps

    I may look at removing these completely in Vendr v2 as I think you are right that deleting and order doesn't automatically mean that everything connected to the order is reverting.

    PS While you are removing domain events, you might also want to remove RevertOrderDiscountCodeUsageCounts and RevertOrderGiftCardRemainingAmounts from the same collection builder.

  • Michael Nielsen 153 posts 810 karma points
    Sep 22, 2021 @ 11:45
    Michael Nielsen
    1

    Hey Matt

    Well reverting everything regarding could be useful for some clients, but yes perhaps only after some configuration, i.e. when an order is switched to "Cancelled", then it's reverted, not if it's just deleted. 🤷‍♂️🙂

    As to the specific issue, then upgrading to 1.8.6 made deleting orders possible again, even for orders where products no longer exists.

    Deleting orders where products do exist, does change the stock on those products, doing as you suggest, fixes that issue, though the method name is RemoveHandler, not just Remove 😊

    For anyone else needing to fix a similar issue, this is my class

    [ComposeAfter(typeof(VendrWebComposer))]
    public class StoreComposer : IUserComposer
    {
        public void Compose(Composition composition)
        {           
            composition.WithDomainEvent<OrderDeleted>().RemoveHandler<RevertOrderStockLevels>();
            composition.WithDomainEvent<OrderDeleted>().RemoveHandler<RevertOrderDiscountCodeUsageCounts>();
            composition.WithDomainEvent<OrderDeleted>().RemoveHandler<RevertOrderGiftCardRemainingAmounts>();
        }
    }
    
  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Sep 22, 2021 @ 12:37
    Matt Brailsford
    0

    Perfect! Glad it all worked.

    I do think going forward "reverting" an order should be opt in, so in the v2 code I have updated this so that reverting only occurs when you use the API and call _orderService.DeleteOrder(order, revertOrder:true)

    I'll review the UI at some point and maybe make a UI option too, but I think this is the safest default.

    Thanks for reporting this.

    Matt

Please Sign in or register to post replies

Write your reply to:

Draft