New Promotions - free gift item is missing "ParentCatalogEntryId"

Vote:
 

I created a custom EntryPromotion & EntryPromotionProcessorBase, to give a free gift item.

It seems to work, but when the free gift item is added to Cart, it is missing "ParentCatalogEntryId" (even though this data exists in DB for the free item).  My site has logic that depends on "ParentCatalogEntryId", so I need it to be populated..

...

Is this normal?  Or am I doing something wrong? Any advice on how to fix it?

#174711
Feb 02, 2017 16:36
Vote:
 

Hi,

In workflow source, we could get ParentCatalogEntryId in ValidateLineItemsActivity. So I think you could try adding ValidateLineItemsActivity after CalculateDiscountsVNextActivity.

And you're using workflow or no-workflow process?

/Son Do

#174746
Feb 03, 2017 5:05
Vote:
 

Hi Ken,

A workaround for the problem, if you are in hurry or can't locate the source of the problem is to inject your own GiftItemFactory as such:

public class CustomGiftItemFactory : GiftItemFactory
    {
        private readonly IContentLoader _contentLoader;

        public CustomGiftItemFactory(IContentLoader contentLoader, IPriceService priceService) : base(contentLoader, priceService)
        {
            _contentLoader = contentLoader;
        }

        protected override ILineItem CreateGiftLineItem(EntryContentBase entryContent, PromotionProcessorContext processorContext)
        {
            var lineItem = base.CreateGiftLineItem(entryContent, processorContext);
            var parentCode = _contentLoader.Get<EntryContentBase>(entryContent.ParentLink).Code;
            ((LineItem) lineItem).ParentCatalogEntryId = parentCode;
            return lineItem;
        }
    }

Regards,
Joel Yourstone

#174756
Feb 03, 2017 10:36
Vote:
 

Thank you both!

I am trying both solutions.

@ Joel - I couldn't quite get it to work that way... but I DID get it to work using code like this:

        protected override ILineItem CreateGiftLineItem(EntryContentBase entryContent, PromotionProcessorContext processorContext)
        {
            var lineItem = base.CreateGiftLineItem(entryContent, processorContext);
            
            // Set the ParentCatalogEntryId, because Epi hasn't done it for some reason:
            if (lineItem != null)
            {
                var variantEntry = _contentLoader.Get<EntryContentBase>(entryContent.ParentEntries.ContentLink);
                var relation = CatalogContext.Current.GetCatalogRelationDto(variantEntry.ContentLink.ID);
                var parentEntryId = relation?.CatalogEntryRelation?.FirstOrDefault()?.ParentEntryId;
                var parentEntry = CatalogContext.Current.GetCatalogEntry(parentEntryId.ToInt(), new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo));
                ((LineItem)lineItem).ParentCatalogEntryId = parentEntry?.ID;
            }
            
            return lineItem;
        }

That gives me the ParentCatalogEntryId I need.  Do you see any problems with that approach? (or, do you see an easier way?)

Thanks so much!

#174844
Feb 06, 2017 23:43
Vote:
 

It should be possible to solve without resorting to CatalogContext operations:

var parentRef = entrycontent.GetParentProducts().FirstOrDefault();
var parent =_contentLoader.Get<EntryContentBase>(parentRef);
((LineItem)lineItem).ParentCatalogEntryId = parent.Code;

Add the necessary null checks of course :)

Optionally the GetParentProducts extension method might need a repository as parameter, if it does just load it from structuremap in the constructor.

#174896
Feb 07, 2017 14:57
Vote:
 

Thank you, that worked well.  The code is simpler.

Just wondering, is CatalogContext considered to be slower/ less efficient?  Or is it just a more complicated solution?

#174914
Feb 07, 2017 17:37
Vote:
 

No above all it is more to be considered a legacy solution, epi still use it internally but it is being phased out.

I think most if not all of the functions are already available from other classes/interfaces that can be retrieved with dependency injection.

IContentLoader, ILinksRepository, IRelationRepository and so on.

As a rule of thumb anything that isn't retrieved through dependency injection are due to become obsolete and isn't really future proof.

#174929
Feb 08, 2017 10:00
Vote:
 

Ah good to know, thanks!

#174959
Feb 08, 2017 15:26
Vote:
 

In case anyone wants to see it, here is my final code for CustomGiftItemFactory:

    public class CustomGiftItemFactory : GiftItemFactory
    {
        private readonly IContentLoader _contentLoader;

        public CustomGiftItemFactory(IContentLoader contentLoader, IPriceService priceService)
            : base(contentLoader, priceService)
        {
            _contentLoader = contentLoader;
        }

        protected override ILineItem CreateGiftLineItem(EntryContentBase entryContent, PromotionProcessorContext processorContext)
        {
            var lineItem = base.CreateGiftLineItem(entryContent, processorContext);
            
            // Set the ParentCatalogEntryId, because Epi hasn't done it for some reason:
            if (lineItem != null)
            {
                var parentRef = entryContent.GetParentProducts().FirstOrDefault();
                if (parentRef != null)
                {
                    var parent = _contentLoader.Get<EntryContentBase>(parentRef);
                    ((LineItem)lineItem).ParentCatalogEntryId = parent?.Code;
                }
            }
            
            return lineItem;
        }
    }


And note that I also took Son Do's advice - I updated our ActivityFlows to use ValidateLineItemsActivity after CalculateDiscountsVNextActivity.

This combination seems to give me what I need.

#175847
Edited, Mar 03, 2017 23:01
Vote:
 

Great to hear that (y)

#175890
Mar 06, 2017 3:47
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.