Lineitemids change when filtering occurs in the Promotion Engine.

Vote:
 

Hello world.

We have an issue that is causing havoc in our integrations to other systems at the moment. Our line item ids change on our PurchaseOrders in certain processes!

In our solution we use the LineItemId as an identifier that we send to other systems. If any of us update a line item for some reason we use a LineItemId to reference the specific one that should get the updates on the other end of the integration. So it's pretty bad if the LineItemIds keep changing on us.

After noticing this issue I've narrowed it down to the way that the promotion engine filters out items that shouldn't be considered for promotions for whatever reason we specify in our filtering.

I've writtein up some code to replicate the issue. The IEntryFilter that the IoC uses can look like this:

    public class MyEntryFilter : IEntryFilter
    {
        public IEnumerable Filter(IEnumerable entryCodes)
        {
            return Enumerable.Empty();
        }
    }

(Basicly filter out everything)

We can then run this code to test the filter:

    public void TestPromotionEngineFilter(int orderGroupId)
    {
        var orderRepo = ServiceLocator.Current.GetInstance();
        var entryFilter = ServiceLocator.Current.GetInstance();
        var order = orderRepo.Load(orderGroupId);
            
            
        var filterHandler = new EntryFilterHandler(entryFilter, order.Forms.First());

        filterHandler.ExcludeItems();
        filterHandler.RestoreItems();

        orderRepo.Save(order);
    }

After running this the lineitemIds will have changed on all items on that order.

This seems to have to do with the way that EntryFilterHandler deals with filtering. It first removes the items from the Shipment in ExcludeItems() (this also triggers code that removes it from the OrderForm), then when the promotion engine has finished running it adds them back to the Shipment with RestoreItems().

So to my question:

Has anyone else encountered this issue? Is there a quick (and dirty is acceptable too at the moment) solution out there already maybe? (beyond removing our code that filters out items we don't want to be considered for promotions, I'm already considering the implications of doing that.)

Version:

10.6.0

(But the latest version handles the filtering in the same manner)

#192175
Edited, May 09, 2018 10:16
Vote:
 

Hi Jafet,

I got your point and now looking for solutions.

/Viet Anh

#192177
May 09, 2018 10:38
Vote:
 

Not really helping you with the behaviour, but I running promotions on a purchase order is always a bit quirky. I.e. promotions that has changed since it was converted to a PurchaseOrder Will be reevaluated, which is not always great. And for example gift promotions will always get a new Id whenever the promotion engine is run, it will remove it and then re add it if it is still a reward.

Maybe a solution could be not to use the lineitemid but rather an own custom meta field? Seems quite weird and don't know how it will work with gift items etc. But I have a hard way of seeing how we can escape lineitemids changing, if we want to rum promotions om POs. 

#192178
May 09, 2018 10:40
Vote:
 

My phone knows me better than I type, apparently I want rum promotions! 

#192179
May 09, 2018 10:41
Vote:
 

I might be missing something but ... why would you want to care about LineItem Ids, they are pretty much "internal", i.e. only the system cares about it - you can always use the code to handle the, no?

#192180
May 09, 2018 10:50
Vote:
 

You could have two line items with the same code, though!

#192181
May 09, 2018 10:51
Vote:
 

But they should be in different shipments. Or one of them is gift :)

#192182
May 09, 2018 11:07
Vote:
 

We've needed to go with the approach of doing one lineitem per 1 quantity.

So line item with code "12345" can exist twice on an orderform/shipment, the way of uniquely identifying would instead be with the LineItemId. We've ironed out most of the kinks, including handling for gift items etc (making sure they get their own lineitems, but need to investigate further regarding the lineitemid handling). But this one is a bit more tricky since application of new lineitemids (even if the reapplied lineitem already has a lineitemId) happens internally.

Yes, this is one of the things I'm considering doing, but would require reworks of our integrations that have been running for more than a year and additional legacy order handling (for the orders that don't have the field populated). This will probably have to be the long term solution if we can't find one that stops the filtering from changing ids on things that already have an id.

#192186
Edited, May 09, 2018 11:40
Vote:
 

Hm... so you ironed to 1 line item per quantity, then the code can be duplicate. And we can't add meta fields because you have legacy data...

#192192
May 09, 2018 15:14
Vote:
 

We can add meta fields, it'd just be complicated. :) I'm currently weighing the options and we'll see which one ends up being the least complicated. :P

In any case, another good question is... why does the LineItemId need to change in a case like this (filtering products)? Isn't there a solution for keeping the identifier the same when we already have an identifier for that lineitem?

The object we change the identifier for hasn't really changed so what's the purpose of changing it's identifier?

In this case it's literally only the ones that cannot be changed by the process that get their identifiers changed. Which seems pretty odd to me. :D

#192193
Edited, May 09, 2018 15:23
Vote:
 

We bit the bullet and went with the approach of saving LineItemIds that we send in our integrations to a metafield and using that field instead where relevant.

Thanks for the response Viet, Quan and Joel. :)

But since I didn't know that LineItemIds were considered to be internal only, this begs the question. Are any other Ids intended to be for internal use only and not be used to identify specific OrderGroups, Shipments, OrderForms, OrderAdresses etc etc?

Could be good to know for future designs. :D

#194242
Edited, Jun 17, 2018 18:03
Vote:
 

It's not strictly internal - more of a grey area. There are APIs that work with OrderGroupId, but in most of the case you don't start with it. You start with username/ordergroup name, or tracking number. I can't really say to stay away from it, but I think it makes senses to avoid using them as much as possible 

#194246
Jun 17, 2018 21:20
Vote:
 

Hi All.

There is one more issue.

After filtering ExcludeItems+RestoreItems, some of data from line items are lost.
It's properties of class LineItem, which are not declared in interface ILineItem.
Line items for filtering are gotten from Shipments. Line items are stored in Shipment as InMemoryLineItem.

Class LineItem has more properties (e.g. ParentCatalogEntryId).

#200438
Edited, Jan 11, 2019 17:53