Copied to clipboard

Flag this post as spam?

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


  • ianhoughton 281 posts 605 karma points c-trib
    Mar 10, 2023 @ 13:58
    ianhoughton
    0

    Clear basket after timeout

    What is the proper way to delete the current users basket after a set period of time? i.e we want the users cart/basket to only show for 6 hrs.

  • Huw Reddick 1728 posts 6067 karma points MVP c-trib
    Mar 10, 2023 @ 15:39
    Huw Reddick
    0

    I can't speak specifically for Vendr, but we use a scheduled job to check for open baskets that have been sat around for more than X hours.

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Mar 13, 2023 @ 09:17
    Matt Brailsford
    0

    Hey Ian,

    The simplest option could be to change the default cookie timeout (which is set for 1 year). If you set this to 360 it will mean the cart cookie expires after 6 hours of inactivity.

    enter image description here

    It would mean the order isn't removed though, it just looses it's link with the current session so a new one would be created.

    If you wanted more control over this, then Huw's suggestion would be an altrnative route, setting up a background task and checking to see how long an order has been inactive for and if it exeeds your time limit, remove all items from the cart.

  • ianhoughton 281 posts 605 karma points c-trib
    Mar 14, 2023 @ 11:33
    ianhoughton
    0

    Hi Matt, thanks for that.

    For the scheduled task, I was thinking of something like this:

    public class ClearBasketsTask : IClearBasketsTask
    {
        private readonly IVendrApi _vendrApi;
        private readonly ISessionManager _sessionManager;
        private readonly IConfiguration _configuration;
    
        public ClearBasketsTask(
            ISessionManager sessionManager,
            IVendrApi vendrApi,
            IConfiguration configuration)
        {
            _sessionManager = sessionManager;
            _vendrApi = vendrApi;
            _configuration = configuration;
        }
    
        public void ClearBaskets()
        {
            int vendrBasketExpiryTimeHours = _configuration.GetValue<int>("AppSettings:VendrBasketExpiryTimeHours");
            foreach (var store in _vendrApi.GetStores())
            {
                var order = _sessionManager.GetCurrentOrder(store.Id);
                if (order != null)
                {
                    if (order.CreateDate < DateTime.Now.AddHours(-vendrBasketExpiryTimeHours))
                    {
                        _sessionManager.ClearCurrentOrder(store.Id);
                    }
                }
            }
        }
    }
    

    does that look correct, have i used the correct session manager methods?

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Mar 14, 2023 @ 11:49
    Matt Brailsford
    0

    Hey Ian,

    Hmm, not exactly.

    A background task won't have the concept of a "current order" as these are user specific (stored in a cookie). You'd really want to perform a search for all orders that have not been updated within your expiry window and then empty all of them.

  • ianhoughton 281 posts 605 karma points c-trib
    Mar 14, 2023 @ 14:56
    ianhoughton
    0

    So something like this:

    public void ClearBaskets()
        {
            int vendrBasketExpiryTimeHours = _configuration.GetValue<int>("AppSettings:VendrBasketExpiryTimeHours");
            var orders = _vendrApi.SearchOrders(o => o.CreatedBefore(DateTime.Now.AddHours(-vendrBasketExpiryTimeHours)), 1, int.MaxValue);
            if (orders != null && orders.Items.Any())
            {
                foreach (var item in orders.Items.Where(i => !i.IsFinalized))
                {
                    _unitOfWorkProvider.Execute(uow =>
                    {
                        // Convert the order into it's Writable form
                        var order = item.AsWritable(uow);
    
                        // Peform our write operation
                        foreach (var orderLine in order.OrderLines)
                        {
                            order.WithOrderLine(orderLine.Id).SetQuantity(0);
                        }
    
                        // Persist the changes to the database
                        _orderService.SaveOrder(order);
    
                        //_orderService.DeleteOrder(order);
    
                        // Close our transaction
                        uow.Complete();
                    });
                }
            }
        }
    

    should I reset the quantity to 0 for each orderline, or just delete the entire order?

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Mar 14, 2023 @ 15:04
    Matt Brailsford
    100

    I would put the finalized check as part of the search statement as you don't want to load ALL orders and then exclude the finalized, you might as well make it part of the same statement and just get back the results you want to loop over.

    In terms of clearing the order lines, or deleting the order, it's up to you and whether you want to keep any customer data that may already be stored on the order.

    I'd probably get all the order line ID's, then loop over them and call RemoveOrderLine(id) to remove them all (we could probably do with a method to remove all order lines)

Please Sign in or register to post replies

Write your reply to:

Draft