private static DiscountBase ConvertDiscountAndLineToDiscountBase(PeriodicDiscount discountAndLine) { DiscountBase discount = null; OfferDiscount offer = null; MixAndMatchDiscount mixAndMatch = null; MultipleBuyDiscount multipleBuy = null; ThresholdDiscount threshold = null; switch (discountAndLine.PeriodicDiscountType) { case PeriodicDiscountOfferType.Offer: offer = new OfferDiscount(discountAndLine.ValidationPeriod); discount = offer; break; case PeriodicDiscountOfferType.MixAndMatch: mixAndMatch = new MixAndMatchDiscount(discountAndLine.ValidationPeriod); mixAndMatch.DealPriceValue = discountAndLine.MixAndMatchDealPrice; mixAndMatch.DiscountAmountValue = discountAndLine.MixAndMatchDiscountAmount; mixAndMatch.DiscountPercentValue = discountAndLine.MixAndMatchDiscountPercent; mixAndMatch.NumberOfLeastExpensiveLines = discountAndLine.MixAndMatchNumberOfLeastExpensiveLines; mixAndMatch.NumberOfTimesApplicable = discountAndLine.MixAndMatchNumberOfTimeApplicable; mixAndMatch.LeastExpensiveMode = discountAndLine.LeastExpensiveMode; discount = mixAndMatch; break; case PeriodicDiscountOfferType.MultipleBuy: multipleBuy = new MultipleBuyDiscount(discountAndLine.ValidationPeriod); discount = multipleBuy; break; case PeriodicDiscountOfferType.Threshold: threshold = new ThresholdDiscount(discountAndLine.ValidationPeriod); threshold.ShouldCountNonDiscountItems = discountAndLine.ShouldCountNonDiscountItems != 0; discount = threshold; break; } if (discount != null) { discount.IsCategoryToProductOrVariantIdsMapSet = true; discount.OfferId = discountAndLine.OfferId; discount.OfferName = discountAndLine.Name; discount.PeriodicDiscountType = discountAndLine.PeriodicDiscountType; discount.IsDiscountCodeRequired = discountAndLine.IsDiscountCodeRequired; discount.ConcurrencyMode = discountAndLine.ConcurrencyMode; discount.PricingPriorityNumber = discountAndLine.PricingPriorityNumber; discount.CurrencyCode = discountAndLine.CurrencyCode; discount.DateValidationPeriodId = discountAndLine.ValidationPeriodId; discount.DateValidationType = (DateValidationType)discountAndLine.DateValidationType; discount.DiscountType = GetDiscountMethodType(discount.PeriodicDiscountType, discountAndLine.DiscountType); discount.ValidFrom = discountAndLine.ValidFromDate; discount.ValidTo = discountAndLine.ValidToDate; } return(discount); }
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); }
/// <summary> /// Converts retail discount data from database to discount object. /// </summary> /// <param name="retailDiscount">Retail discount data from database.</param> /// <returns>Discount object.</returns> /// <remarks>This is private. Exposed as internal for test.</remarks> internal static DiscountBase ConvertRetailDiscountToDiscountBase(RetailDiscount retailDiscount) { DiscountBase discount = null; OfferDiscount offer = null; MixAndMatchDiscount mixAndMatch = null; MultipleBuyDiscount multipleBuy = null; ThresholdDiscount threshold = null; switch (retailDiscount.PeriodicDiscountType) { case PeriodicDiscountOfferType.Offer: offer = new OfferDiscount(retailDiscount.ValidationPeriod); discount = offer; break; case PeriodicDiscountOfferType.MixAndMatch: mixAndMatch = new MixAndMatchDiscount(retailDiscount.ValidationPeriod); mixAndMatch.DealPriceValue = retailDiscount.MixAndMatchDealPrice; mixAndMatch.DiscountAmountValue = retailDiscount.MixAndMatchDiscountAmount; mixAndMatch.DiscountPercentValue = retailDiscount.MixAndMatchDiscountPercent; mixAndMatch.NumberOfLeastExpensiveLines = retailDiscount.MixAndMatchNumberOfLeastExpensiveLines; mixAndMatch.LeastExpensiveMode = retailDiscount.LeastExpensiveMode; mixAndMatch.NumberOfTimesApplicable = retailDiscount.MixAndMatchNumberOfTimeApplicable; foreach (RetailDiscountLine mixMatchLine in retailDiscount.DiscountLines) { if (!mixAndMatch.LineGroupToNumberOfItemsMap.ContainsKey(mixMatchLine.MixAndMatchLineGroup)) { mixAndMatch.LineGroupToNumberOfItemsMap.Add(mixMatchLine.MixAndMatchLineGroup, mixMatchLine.MixAndMatchLineNumberOfItemsNeeded); } } discount = mixAndMatch; break; case PeriodicDiscountOfferType.MultipleBuy: multipleBuy = new MultipleBuyDiscount(retailDiscount.ValidationPeriod); multipleBuy.QuantityDiscountLevels.AddRange(retailDiscount.MultibuyQuantityTiers); discount = multipleBuy; break; case PeriodicDiscountOfferType.Threshold: threshold = new ThresholdDiscount(retailDiscount.ValidationPeriod); threshold.ShouldCountNonDiscountItems = retailDiscount.ShouldCountNonDiscountItems != 0; threshold.ThresholdDiscountTiers.AddRange(retailDiscount.ThresholdDiscountTiers); discount = threshold; break; } if (discount != null) { discount.IsCategoryToProductOrVariantIdsMapSet = false; discount.OfferId = retailDiscount.OfferId; discount.OfferName = retailDiscount.Name; discount.PeriodicDiscountType = retailDiscount.PeriodicDiscountType; discount.IsDiscountCodeRequired = retailDiscount.IsDiscountCodeRequired; discount.ConcurrencyMode = retailDiscount.ConcurrencyMode; discount.PricingPriorityNumber = retailDiscount.PricingPriorityNumber; discount.CurrencyCode = retailDiscount.CurrencyCode; discount.DateValidationPeriodId = retailDiscount.ValidationPeriodId; discount.DateValidationType = (DateValidationType)retailDiscount.DateValidationType; discount.DiscountType = GetDiscountMethodType(discount.PeriodicDiscountType, retailDiscount.DiscountType); discount.ValidFrom = retailDiscount.ValidFromDate; discount.ValidTo = retailDiscount.ValidToDate; foreach (RetailDiscountLine discountLine in retailDiscount.DiscountLines) { discountLine.DiscountMethod = (int)GetLineDiscountOfferMethod(discount.PeriodicDiscountType, discount.DiscountType, discountLine.DiscountMethod, discountLine.MixAndMatchLineSpecificDiscountType); discount.DiscountLines.Add(discountLine.DiscountLineNumber, discountLine); } foreach (RetailDiscountPriceGroup priceGroup in retailDiscount.PriceGroups) { discount.PriceDiscountGroupIds.Add(priceGroup.PriceGroupId); } foreach (DiscountCode discountCode in retailDiscount.DiscountCodes) { discount.DiscountCodes.Add(discountCode.Code); discount.DiscountCodes.Add(discountCode.Barcode); } } return(discount); }