logo
Welcome to our new AbleCommerce forums. As a guest, you may view the information here. To post to this forum, you must have a registered account with us, either as a new user evaluating AbleCommerce or an existing user of the application. For all questions related to the older version of Gold and earlier, please go to AbleCommerce Gold forum. Please use your AbleCommerce username and password to Login. New Registrations are disabled.

Notification

Icon
Error

Options
Go to last post Go to first unread
sweeperqb  
#1 Posted : Friday, May 27, 2022 2:35:56 AM(UTC)
sweeperqb

Rank: Advanced Member

Groups: Authorized User, Developers
Joined: 5/30/2020(UTC)
Posts: 125

Thanks: 14 times
Was thanked: 3 time(s) in 3 post(s)
Through tons of trial and error, I found out that OrderItems are not persisted through OrderItemRepository, but instead are cascaded through OrderRepository when order.Save() is called.

As a result of those findings, I created a Custom OrderRepository and override the BeforeSave and AfterSave events.

BeforeSave I load the original OrderItems for the order using a new Session so I don't mess up any change tracking using this code:

Code:
protected IList<OrderItem> GetOriginalOrderItems(int orderId)
{
    using (var session = AbleContext.Current.DatabaseFactory.SessionFactory.OpenSession())
    {
        var criteria = session.CreateCriteria<OrderItem>();
        criteria.Add(NH.Restrictions.Eq("Order.Id", orderId));
        return criteria.List<OrderItem>();
    }
}


I then compare that list to the current order.Items to generate a list of Create/Update/Delete changes for the items on the order. New items exist in order.Items, but not originalItems. Updated items have matching order item ids in both lists. Deleted items exist in originalItems, but not order.Items.

The problem I'm running into is AfterSave. Since the order has been saved, I would expect Order.Items to all be assigned an Order Item Id. However, new items that were created in the database still have an Id of 0. I'm not sure why that is? Can an AC dev explain what is going on here?

Edited by user Friday, May 27, 2022 4:38:01 AM(UTC)  | Reason: Even running [b]GetOriginalOrderItems[/b] again after saving, the Id value is 0.

Wanna join the discussion?! Login to your AbleCommerce Forums forum account. New Registrations are disabled.

sweeperqb  
#2 Posted : Friday, May 27, 2022 4:56:03 AM(UTC)
sweeperqb

Rank: Advanced Member

Groups: Authorized User, Developers
Joined: 5/30/2020(UTC)
Posts: 125

Thanks: 14 times
Was thanked: 3 time(s) in 3 post(s)
I figured out the issue. NHibernate does not save child collections until the session is committed. AfterSave fires after an order is saved, but before the session is committed, so all of the items are still dirty, and new items are still transient (Id = 0). It isn't optimal, but I had to add session.SaveOrUpdate(item) in my AfterSave function for any items that were transient.

Here is the sample code in case anyone is wondering:

Code:
public override void AfterSave(object entity)
{
     var order = (Order)entity;

     var session = AbleContext.Current.Database.GetSession();

     var current = new List<OrderItemDetailModel>();

     foreach(var item in order.Items)
     {
         if (item.IsTransient())
         {
             // Have to do this to get the id for inserted items. Cascades don't happen until the session is committed.
             session.SaveOrUpdate(item);
         }
         current.Add(new OrderItemDetailModel(item));
     }

     Logger.Warn("Current: " + Json.Encode(current));
}
thanks 1 user thanked sweeperqb for this useful post.
judy at Web2Market on 5/27/2022(UTC)
sweeperqb  
#3 Posted : Friday, May 27, 2022 7:30:42 PM(UTC)
sweeperqb

Rank: Advanced Member

Groups: Authorized User, Developers
Joined: 5/30/2020(UTC)
Posts: 125

Thanks: 14 times
Was thanked: 3 time(s) in 3 post(s)
I keep getting over one hurdle and running into another. I'm hooking into the CheckedOut event to reserve items in our custom inventory system. I created a custom OrderRepository and override the BeforeSave and AfterSave to detect order item Create/Update/Delete changes made through the Admin. That works well now that I figured out some NHibernate quirks.

However, that still doesn't cover all the scenarios of how OrderItems change in AbleCommerce. You can also Split or Merge shipments, which seem to persist changes through OrderShipmentRepository and/or OrderItemRepository. Are there other areas I need to look out for?

I am doing everything in my power to prevent modifying core code, but all of the different ways to modify OrderItems is driving me bonkers. I may end up having to create custom OrderRepository, OrderShipmentRepository, and OrderItemRepository implementations. Then I will have to set some sort of Web Request scoped variable so the repositories know the order items have already been processed.

I mentioned it about a year ago, and I will mention it again... It would be great if there were built in OrderItemAdded, OrderItemUpdated, and OrderItemDeleted events; or maybe OrderItemsChanging and OrderItemsChanged.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.