internal static Dictionary <long, List <DiscountBase> > GetProductOrVarintToDiscountMapFromCache( IPricingDataAccessor pricingDataManager, PriceContext priceContext, SalesTransaction transaction) { ISet <long> productVariantMasterIdsInTransaction = GetProductVariantMasterIdsForTransaction(transaction); Dictionary <long, IList <RetailCategoryMember> > categorytoProductOrVariantIdsMap = GetCategoryToProductOrVariantIdsMapForTransaction(pricingDataManager, productVariantMasterIdsInTransaction); IEnumerable <RetailDiscount> allDiscounts = pricingDataManager.GetAllRetailDiscounts() as IEnumerable <RetailDiscount>; Dictionary <long, List <DiscountBase> > allApplicableDiscounts = new Dictionary <long, List <DiscountBase> >(); foreach (RetailDiscount retailDiscount in allDiscounts) { if (!PriceContextHelper.MatchCalculationMode(priceContext, retailDiscount.PeriodicDiscountType)) { continue; } DiscountBase discount = ConvertRetailDiscountToDiscountBase(retailDiscount, priceContext); discount.ProductOrVariantIdsInTransaction = productVariantMasterIdsInTransaction; // Product or variant id to categories map is needed to filter which discount lines are applicable for the transaction. See DiscountBase class. discount.CategoryToProductOrVariantIdsMap = categorytoProductOrVariantIdsMap; IDictionary <long, IList <RetailDiscountLine> > itemDiscounts = discount.GetProductOrVariantIdToRetailDiscountLinesMap(); foreach (long productOrVariantId in itemDiscounts.Keys) { if (allApplicableDiscounts.ContainsKey(productOrVariantId)) { allApplicableDiscounts[productOrVariantId].Add(discount); } else { allApplicableDiscounts.Add(productOrVariantId, new List <DiscountBase>() { discount }); } } } return(allApplicableDiscounts); }
internal static Dictionary <long, List <DiscountBase> > GetProductOrVariantToDiscountMapLive( SalesTransaction transaction, PriceContext priceContext, IPricingDataAccessor pricingDataManager) { List <ItemUnit> items = new List <ItemUnit>(); Dictionary <string, long> itemIdInventDimIdToProductOrVariantIdMap = new Dictionary <string, long>(StringComparer.OrdinalIgnoreCase); foreach (SalesLine salesLine in transaction.PriceCalculableSalesLines) { // The map is to look up product or variant id, but not master id if variant id is present. itemIdInventDimIdToProductOrVariantIdMap[GetItemIdInventDimIdKey(salesLine.ItemId, salesLine.InventoryDimensionId)] = salesLine.ProductId; items.Add(new ItemUnit() { ItemId = salesLine.ItemId, VariantInventoryDimensionId = salesLine.InventoryDimensionId, Product = salesLine.MasterProductId == 0 ? salesLine.ProductId : salesLine.MasterProductId, DistinctProductVariant = salesLine.Variant != null ? salesLine.Variant.DistinctProductVariantId : 0, UnitOfMeasure = Discount.GetUnitOfMeasure(salesLine) }); } ReadOnlyCollection <PeriodicDiscount> discountAndLines = GetRetailDiscountsAndLines(items, priceContext, pricingDataManager, QueryResultSettings.AllRecords); ISet <long> productVariantMasterIdsInTransaction = GetProductVariantMasterIdsForTransaction(transaction); Dictionary <long, List <DiscountBase> > productDiscountMap = new Dictionary <long, List <DiscountBase> >(); Dictionary <string, DiscountBase> offerIdToDiscountMap = new Dictionary <string, DiscountBase>(StringComparer.OrdinalIgnoreCase); foreach (PeriodicDiscount discountAndLine in discountAndLines) { if (!PriceContextHelper.MatchCalculationMode(priceContext, discountAndLine.PeriodicDiscountType)) { continue; } string key = GetItemIdInventDimIdKey(discountAndLine.ItemId, discountAndLine.InventoryDimensionId); long productOrVariantId = 0; if (itemIdInventDimIdToProductOrVariantIdMap.TryGetValue(key, out productOrVariantId)) { DiscountBase discount = null; if (offerIdToDiscountMap.TryGetValue(discountAndLine.OfferId, out discount)) { RetailDiscountLine discountLine = null; if (!discount.DiscountLines.TryGetValue(discountAndLine.DiscountLineNumber, out discountLine)) { discountLine = ConvertDiscountAndLineToDiscountLine(discountAndLine, discount); discount.DiscountLines.Add(discountLine.DiscountLineNumber, discountLine); } IList <RetailDiscountLine> discountLines = null; if (discount.ProductOfVariantToDiscountLinesMap.TryGetValue(productOrVariantId, out discountLines)) { discountLines.Add(discountLine); } else { discount.ProductOfVariantToDiscountLinesMap[productOrVariantId] = new List <RetailDiscountLine> { discountLine }; } } else { discount = ConvertDiscountAndLineToDiscountBase(discountAndLine); discount.ProductOrVariantIdsInTransaction = productVariantMasterIdsInTransaction; RetailDiscountLine discountLine = ConvertDiscountAndLineToDiscountLine(discountAndLine, discount); discount.DiscountLines.Add(discountLine.DiscountLineNumber, discountLine); offerIdToDiscountMap.Add(discount.OfferId, discount); discount.ProductOfVariantToDiscountLinesMap[productOrVariantId] = new List <RetailDiscountLine> { discountLine }; } List <DiscountBase> discounts; if (productDiscountMap.TryGetValue(productOrVariantId, out discounts)) { if (!discounts.Where(p => p.OfferId == discount.OfferId).Any()) { discounts.Add(discount); } } else { productDiscountMap[productOrVariantId] = new List <DiscountBase>() { discount }; } } } IEnumerable <string> offerIds = offerIdToDiscountMap.Select(p => p.Key); if (offerIds.Any()) { IEnumerable <DiscountCode> discountCodes = pricingDataManager.GetDiscountCodesByOfferIds(offerIds) as IEnumerable <DiscountCode>; foreach (DiscountCode discountCode in discountCodes) { DiscountBase discountBase; if (offerIdToDiscountMap.TryGetValue(discountCode.OfferId, out discountBase)) { // Accept both discount code and barcode in retail channel. discountBase.DiscountCodes.Add(discountCode.Code); discountBase.DiscountCodes.Add(discountCode.Barcode); } } IEnumerable <RetailDiscountPriceGroup> discountPriceGroups = pricingDataManager.GetRetailDiscountPriceGroups(new HashSet <string>(offerIds)) as IEnumerable <RetailDiscountPriceGroup>; foreach (RetailDiscountPriceGroup discountPriceGroup in discountPriceGroups) { offerIdToDiscountMap[discountPriceGroup.OfferId].PriceDiscountGroupIds.Add(discountPriceGroup.PriceGroupId); } SetEffectiveDiscountPriorityFromPriceGroups(offerIdToDiscountMap, priceContext); IEnumerable <string> quantityOfferIds = offerIdToDiscountMap.Where(p => p.Value.PeriodicDiscountType == PeriodicDiscountOfferType.MultipleBuy).Select(p => p.Key); if (quantityOfferIds.Any()) { IEnumerable <QuantityDiscountLevel> quantityLevels = pricingDataManager.GetMultipleBuyDiscountLinesByOfferIds(quantityOfferIds) as IEnumerable <QuantityDiscountLevel>; foreach (QuantityDiscountLevel quantityLevel in quantityLevels) { DiscountBase discountBase; if (offerIdToDiscountMap.TryGetValue(quantityLevel.OfferId, out discountBase)) { MultipleBuyDiscount multipleBuy = discountBase as MultipleBuyDiscount; if (multipleBuy != null) { multipleBuy.QuantityDiscountLevels.Add(quantityLevel); } } } } IEnumerable <string> mixMatchOfferIds = offerIdToDiscountMap.Where(p => p.Value.PeriodicDiscountType == PeriodicDiscountOfferType.MixAndMatch).Select(p => p.Key); if (mixMatchOfferIds.Any()) { IEnumerable <MixAndMatchLineGroup> mixMatchLineGroups = pricingDataManager.GetMixAndMatchLineGroupsByOfferIds(mixMatchOfferIds) as IEnumerable <MixAndMatchLineGroup>; foreach (MixAndMatchLineGroup lineGroup in mixMatchLineGroups) { DiscountBase discountBase; if (offerIdToDiscountMap.TryGetValue(lineGroup.OfferId, out discountBase)) { MixAndMatchDiscount mixMatch = discountBase as MixAndMatchDiscount; if (mixMatch != null) { mixMatch.LineGroupToNumberOfItemsMap.Add(lineGroup.LineGroup, lineGroup.NumberOfItemsNeeded); } } } } IEnumerable <string> thresholdOfferIds = offerIdToDiscountMap.Where(p => p.Value.PeriodicDiscountType == PeriodicDiscountOfferType.Threshold).Select(p => p.Key); if (thresholdOfferIds.Any()) { IEnumerable <ThresholdDiscountTier> thresholdTiers = pricingDataManager.GetThresholdTiersByOfferIds(thresholdOfferIds) as IEnumerable <ThresholdDiscountTier>; foreach (ThresholdDiscountTier tier in thresholdTiers) { DiscountBase discountBase; if (offerIdToDiscountMap.TryGetValue(tier.OfferId, out discountBase)) { ThresholdDiscount threshold = discountBase as ThresholdDiscount; if (threshold != null) { threshold.ThresholdDiscountTiers.Add(tier); } } } } } return(productDiscountMap); }