/// <summary>
            /// Get struct PriceResult from active trade agreement.
            /// Struct PriceResult contains India MaxRetailPrice. Currently there is a field �Max. retail price� in the form price/discount agreement journal
            /// (Navigation path: Main Menu > Sales and marketing > Journal > price/discount agreement journal).
            /// The field will be visible only when the logged on company is an India company. And it is optional.
            /// User can use this field to specify different MRP values on different sites and warehouses for the same item. And when the trade agreement applies to a transaction,
            /// the MRP value should flow to the MRP field of the transaction as the default value.
            /// So current change is when fetching the superset of trade agreements which could apply to all of these items and customer for the given date,
            /// also takes field MAXIMUMRETAILPRICE_IN through the stored procedures GETALLDISCOUNTTRADEAGREEMENTS/ GETALLTRADEAGREEMENTS/ GETTRADEAGREEMENTS.
            /// Then return the whole struct PriceResult  rather than PriceResult.Price.
            /// </summary>
            /// <param name="tradeAgreementRules">The trade agreement rules.</param>
            /// <param name="priceParameters">The price parameters.</param>
            /// <param name="currencyCode">The currency code.</param>
            /// <param name="itemId">The item Id.</param>
            /// <param name="defaultSalesUnit">The default sales unit.</param>
            /// <param name="salesUnit">The sales unit.</param>
            /// <param name="variantLine">The variant line.</param>
            /// <param name="unitOfMeasureConversion">The UnitOfMeasure Conversion.</param>
            /// <param name="quantity">The quantity.</param>
            /// <param name="customerId">The customer Id.</param>
            /// <param name="customerPriceGroup">The customer price group.</param>
            /// <param name="channelPriceGroupIds">The channel price group Ids.</param>
            /// <param name="salesLines">Optional sales lines.</param>
            /// <param name="priceContext">Price context.</param>
            /// <param name="activeDate">The active date.</param>
            /// <returns>The PriceResult of active trade agreement.</returns>
            internal static PriceResult GetPriceResultOfActiveTradeAgreement(
                IDictionary <string, IList <TradeAgreement> > tradeAgreementRules,
                DiscountParameters priceParameters,
                string currencyCode,
                string itemId,
                string defaultSalesUnit,
                string salesUnit,
                ProductVariant variantLine,
                UnitOfMeasureConversion unitOfMeasureConversion,
                decimal quantity,
                string customerId,
                string customerPriceGroup,
                IEnumerable <string> channelPriceGroupIds,
                IEnumerable <SalesLine> salesLines,
                PriceContext priceContext,
                DateTimeOffset activeDate)
            {
                PriceResult result;

                variantLine = variantLine ?? new ProductVariant();

                // Get basic arguments for Price evaluation
                RetailPriceArgs args = new RetailPriceArgs()
                {
                    Barcode      = string.Empty,
                    CurrencyCode = currencyCode,
                    CustomerId   = customerId,
                    Dimensions   = variantLine,
                    DefaultSalesUnitOfMeasure = defaultSalesUnit,
                    ItemId                  = itemId,
                    PriceGroups             = channelPriceGroupIds.AsReadOnly(),
                    Quantity                = quantity,
                    SalesUOM                = salesUnit,
                    UnitOfMeasureConversion = unitOfMeasureConversion,
                };

                // Get the active retail price - checks following prices brackets in order: Customer TAs, Store price group TAs, 'All' TAs.
                // First bracket to return a price 'wins'. Each bracket returns the lowest price it can find.
                result = FindPriceAgreement(tradeAgreementRules, priceParameters, args, salesLines, priceContext, activeDate);

                // Direct customer TA price would have been caught above.
                // Compare against customer price group TAs now and override if lower than previously found price (or if previously found price was 0).
                if (!string.IsNullOrEmpty(customerId) &&
                    !string.IsNullOrEmpty(customerPriceGroup) &&
                    !channelPriceGroupIds.Contains(customerPriceGroup))
                {
                    // Customer price group
                    args.PriceGroups = new ReadOnlyCollection <string>(new[] { customerPriceGroup });
                    PriceResult customerResult = FindPriceAgreement(tradeAgreementRules, priceParameters, args, salesLines, priceContext, activeDate);

                    // Pick the Customer price if either the Retail price is ZERO, or the Customer Price is non-zero AND lower
                    if ((result.Price == decimal.Zero) ||
                        ((customerResult.Price > decimal.Zero) && (customerResult.Price <= result.Price)))
                    {
                        result = customerResult;
                    }
                }

                return(result);
            }
Пример #2
0
 private static void SetEffectiveDiscounDiscountPriorityFromPriceGroups(
     DiscountBase discount,
     PriceContext priceContext)
 {
     if (discount.PricingPriorityNumber <= 0)
     {
         foreach (long priceGroupRecordId in discount.PriceDiscountGroupIds)
         {
             string priceGroupId = null;
             if (priceContext.RecordIdsToPriceGroupIdsDictionary.TryGetValue(priceGroupRecordId, out priceGroupId))
             {
                 int priority = 0;
                 if (priceContext.PriceGroupIdToPriorityDictionary.TryGetValue(priceGroupId, out priority))
                 {
                     if (priority > discount.PricingPriorityNumber)
                     {
                         // We could have a new property on DiscountBase that indicates effective priority number.
                         // This is much simpler, for now, without complications.
                         discount.PricingPriorityNumber = priority;
                     }
                 }
             }
         }
     }
 }
Пример #3
0
            /// <summary>
            /// Check whether the discount is allowed for the item.
            /// </summary>
            /// <param name="priceContext">Price context.</param>
            /// <param name="itemId">Item identifier.</param>
            /// <returns>True if  the discount is allowed for the item, otherwise false.</returns>
            public static bool IsDiscountAllowed(PriceContext priceContext, string itemId)
            {
                Item item = PriceContextHelper.GetItem(priceContext, itemId);
                bool isDiscountAllowed = item != null ? !item.NoDiscountAllowed : true;

                return(isDiscountAllowed);
            }
Пример #4
0
        protected void CleanupPriceContext()
        {
            var db = new PriceContext();

            db.Prices.RemoveRange(db.Prices.ToArray());
            db.SaveChanges();
        }
            private static PriceResult FindPriceAgreement(
                IDictionary <string, IList <TradeAgreement> > tradeAgreementRules,
                DiscountParameters priceParameters,
                RetailPriceArgs args,
                IEnumerable <SalesLine> salesLines,
                PriceContext priceContext,
                DateTimeOffset activeDate)
            {
                // First we get the price according to the base UOM
                PriceAgreementArgs p      = args.AgreementArgsForDefaultSales();
                PriceResult        result = ApplyPriceTradeAgreements(tradeAgreementRules, p, priceParameters, salesLines, priceContext, activeDate);

                // Is the current UOM something different than the base UOM?
                if (args.SalesUOM != args.DefaultSalesUnitOfMeasure)
                {
                    // Then let's see if we find some price agreement for that UOM
                    p = args.ArgreementArgsForSale();
                    PriceResult salesUOMResult = ApplyPriceTradeAgreements(tradeAgreementRules, p, priceParameters, salesLines, priceContext, activeDate);

                    // If there is a price found then we return that as the price
                    if (salesUOMResult.Price > decimal.Zero)
                    {
                        return(salesUOMResult);
                    }
                    else
                    {
                        return(new PriceResult(result.Price * args.UnitOfMeasureConversion.GetFactorForQuantity(args.Quantity), result.IncludesTax, custPriceGroup: result.CustPriceGroup));
                    }
                }

                // else we return baseUOM price mulitplied with the unit qty factor.
                return(result);
            }
Пример #6
0
            private static void InitializePriceContexOfAlgorithmMode(PriceContext priceContext, IPricingDataAccessor pricingDataManager)
            {
                ChannelPriceConfiguration channelPriceConfig = pricingDataManager.GetChannelPriceConfiguration();

                priceContext.DiscountAlgorithmMode         = channelPriceConfig.DiscountAlgorithmMode;
                priceContext.MaxBestDealAlgorithmStepCount = channelPriceConfig.MaxBestDealStepCount;
            }
Пример #7
0
            private static ISet <string> GetApplicablePriceGroups(PriceContext priceContext, ISet <string> allPriceGroupsExceptCatalogs, ISet <long> itemCatalogIds)
            {
                if (priceContext == null)
                {
                    throw new ArgumentNullException("priceContext");
                }

                HashSet <string> applicablePriceGroups = new HashSet <string>(allPriceGroupsExceptCatalogs);

                if (itemCatalogIds != null)
                {
                    foreach (var itemCatalogId in itemCatalogIds)
                    {
                        ISet <string> catalogPriceGroups = null;
                        if (priceContext.CatalogPriceGroups.TryGetValue(itemCatalogId, out catalogPriceGroups))
                        {
                            if (catalogPriceGroups != null)
                            {
                                applicablePriceGroups.UnionWith(catalogPriceGroups);
                            }
                        }
                    }
                }

                return(applicablePriceGroups);
            }
Пример #8
0
            /// <summary>
            /// Create a new instance of the <see cref="PriceContext"/> class.
            /// </summary>
            /// <param name="requestContext">Request context.</param>
            /// <param name="pricingDataManager">Pricing data manager.</param>
            /// <param name="priceParameters">Price parameters.</param>
            /// <param name="currencyAndRoundingHelper">Currency and rounding helper.</param>
            /// <param name="itemIds">Item Ids.</param>
            /// <param name="catalogIds">Catalog identifiers.</param>
            /// <param name="activeDate">Active date.</param>
            /// <param name="priceCalculationMode">Price calculation mode.</param>
            /// <param name="discountCalculationMode">Discount calculation mode.</param>
            /// <returns>A new instance of the <see cref="PriceContext"/> class.</returns>
            public static PriceContext CreatePriceContext(
                RequestContext requestContext,
                IPricingDataAccessor pricingDataManager,
                PriceParameters priceParameters,
                ICurrencyOperations currencyAndRoundingHelper,
                ISet <string> itemIds,
                ISet <long> catalogIds,
                DateTimeOffset activeDate,
                PricingCalculationMode priceCalculationMode,
                DiscountCalculationMode discountCalculationMode)
            {
                if (requestContext == null)
                {
                    throw new ArgumentNullException("requestContext");
                }

                PriceContext priceContext = new PriceContext
                {
                    CurrencyAndRoundingHelper = currencyAndRoundingHelper,
                    ActiveDate              = activeDate,
                    PriceParameters         = priceParameters,
                    PriceCalculationMode    = priceCalculationMode,
                    DiscountCalculationMode = discountCalculationMode,
                };

                PriceContextHelper.InitializePriceContextOfInferredProperties(priceContext, pricingDataManager, requestContext, itemIds, catalogIds, null);

                return(priceContext);
            }
Пример #9
0
            /// <summary>
            /// Gets the discount data.
            /// </summary>
            /// <param name="tradeAgreements">Trade agreement collection to calculate on.</param>
            /// <param name="relation">The relation (line, multiline, total).</param>
            /// <param name="itemRelation">The item relation.</param>
            /// <param name="accountRelation">The account relation.</param>
            /// <param name="itemCode">The item code (table, group, all).</param>
            /// <param name="accountCode">The account code (table, group, all).</param>
            /// <param name="quantityAmount">The quantity or amount that sets the minimum quantity or amount needed.</param>
            /// <param name="priceContext">The price context.</param>
            /// <param name="itemDimensions">The item dimensions.</param>
            /// <param name="includeDimensions">A value indicating whether to include item dimensions.</param>
            /// <returns>
            /// A collection of discount agreement arguments.
            /// </returns>
            internal static ReadOnlyCollection <TradeAgreement> GetPriceDiscData(
                List <TradeAgreement> tradeAgreements,
                PriceDiscountType relation,
                string itemRelation,
                string accountRelation,
                PriceDiscountItemCode itemCode,
                PriceDiscountAccountCode accountCode,
                decimal quantityAmount,
                PriceContext priceContext,
                ProductVariant itemDimensions,
                bool includeDimensions)
            {
                accountRelation = accountRelation ?? string.Empty;
                itemRelation    = itemRelation ?? string.Empty;
                string targetCurrencyCode = priceContext.CurrencyCode ?? string.Empty;
                string inventColorId      = (itemDimensions != null && itemDimensions.ColorId != null && includeDimensions) ? itemDimensions.ColorId : string.Empty;
                string inventSizeId       = (itemDimensions != null && itemDimensions.SizeId != null && includeDimensions) ? itemDimensions.SizeId : string.Empty;
                string inventStyleId      = (itemDimensions != null && itemDimensions.StyleId != null && includeDimensions) ? itemDimensions.StyleId : string.Empty;
                string inventConfigId     = (itemDimensions != null && itemDimensions.ConfigId != null && includeDimensions) ? itemDimensions.ConfigId : string.Empty;

                DateTime today  = priceContext.ActiveDate.DateTime;
                DateTime noDate = new DateTime(1900, 1, 1);

                ReadOnlyCollection <TradeAgreement> foundAgreements;

                foundAgreements = GetAgreementsFromCollection(tradeAgreements, relation, itemRelation, accountRelation, itemCode, accountCode, quantityAmount, targetCurrencyCode, inventColorId, inventSizeId, inventStyleId, inventConfigId, today, noDate);

                return(foundAgreements);
            }
Пример #10
0
            /// <summary>
            /// Create a new instance of the <see cref="PriceContext"/> class for price calculation.
            /// </summary>
            /// <param name="pricingDataManager">Pricing data manager.</param>
            /// <param name="currencyAndRoundingHelper">Currency and rounding helper.</param>
            /// <param name="priceCalculationMode">Price calculation mode.</param>
            /// <param name="discountCalculationMode">Discount calculation mode.</param>
            /// <param name="itemIds">Item Ids.</param>
            /// <param name="catalogIds">Catalog identifiers.</param>
            /// <param name="affiliationLoyaltyTiers">Affiliation or loyalty tier identifiers.</param>
            /// <param name="customerId">Customer Id.</param>
            /// <param name="customerPriceGroup">Customer price group.</param>
            /// <param name="priceIncludesTax">Price includes tax.</param>
            /// <param name="currencyCode">Currency code.</param>
            /// <param name="activeDate">Active date.</param>
            /// <returns>A new instance of the <see cref="PriceContext"/> class.</returns>
            public static PriceContext CreatePriceContext(
                IPricingDataAccessor pricingDataManager,
                ICurrencyOperations currencyAndRoundingHelper,
                PricingCalculationMode priceCalculationMode,
                DiscountCalculationMode discountCalculationMode,
                ISet <string> itemIds,
                ISet <long> catalogIds,
                IEnumerable <AffiliationLoyaltyTier> affiliationLoyaltyTiers,
                string customerId,
                string customerPriceGroup,
                bool priceIncludesTax,
                string currencyCode,
                DateTimeOffset activeDate)
            {
                PriceContext priceContext = CreatePriceContext(
                    pricingDataManager,
                    currencyAndRoundingHelper,
                    priceCalculationMode,
                    discountCalculationMode,
                    itemIds,
                    catalogIds,
                    affiliationLoyaltyTiers,
                    customerId,
                    customerPriceGroup,
                    string.Empty,
                    string.Empty,
                    string.Empty,
                    priceIncludesTax,
                    currencyCode,
                    activeDate);

                return(priceContext);
            }
Пример #11
0
            private static ReadOnlyCollection <PeriodicDiscount> GetRetailDiscounts(
                IEnumerable <SalesLine> salesLines,
                PriceContext priceContext,
                IPricingDataAccessor pricingDataManager,
                QueryResultSettings settings)
            {
                // don't do lookup if there aren't any price groups to search by
                HashSet <string> allPriceGroups = PriceContextHelper.GetAllPriceGroupsForDiscount(priceContext);

                if (allPriceGroups.Count == 0)
                {
                    return(new ReadOnlyCollection <PeriodicDiscount>(new PeriodicDiscount[0]));
                }

                var items = salesLines.Select(l => new ItemUnit
                {
                    ItemId = l.ItemId,
                    VariantInventoryDimensionId = l.InventoryDimensionId ?? string.Empty,
                    UnitOfMeasure = Discount.GetUnitOfMeasure(l),
                });

                ReadOnlyCollection <PeriodicDiscount> discounts =
                    pricingDataManager.ReadRetailDiscounts(items, allPriceGroups, priceContext.ActiveDate, priceContext.ActiveDate, priceContext.CurrencyCode, settings) as ReadOnlyCollection <PeriodicDiscount>;

                ReadOnlyCollection <PeriodicDiscount> validDiscounts =
                    discounts.Where(d => InternalValidationPeriod.ValidateDateAgainstValidationPeriod((DateValidationType)d.DateValidationType, d.ValidationPeriod, d.ValidFromDate, d.ValidToDate, priceContext.ActiveDate)).AsReadOnly();

                return(validDiscounts);
            }
Пример #12
0
 /// <summary>
 /// Generate discount lines for the applied discount application.
 /// </summary>
 /// <param name="appliedDiscountApplication">The applied discount application.</param>
 /// <param name="discountableItemGroups">The discountable item groups.</param>
 /// <param name="priceContext">The price context.</param>
 public override void GenerateDiscountLines(
     AppliedDiscountApplication appliedDiscountApplication,
     DiscountableItemGroup[] discountableItemGroups,
     PriceContext priceContext)
 {
     // Nothing here, already generated in GetAppliedDiscountApplication.
 }
Пример #13
0
 /// <summary>
 /// Initializes a new instance of the DiscountableItemGroup class with no SalesLine items included.
 /// </summary>
 /// <param name="priceContext">Price context.</param>
 private DiscountableItemGroup(PriceContext priceContext)
 {
     this.discountLineQuantitiesNonCompounded = new List <DiscountLineQuantity>();
     this.discountLineQuantitiesCompounded    = new List <DiscountLineQuantity>();
     this.salesLines   = new List <SalesLine>();
     this.Quantity     = 0M;
     this.priceContext = priceContext;
 }
Пример #14
0
        public void ZeroShouldNotMatchNullWhenSelectExisting()
        {
            using (var db = new PriceContext())
            {
                db.Prices.Add(new Price()
                {
                    Date = new DateTime(2019, 1, 1), Name = "ERICB", Value = 80
                });
                db.Prices.Add(new Price()
                {
                    Date = new DateTime(2019, 1, 2), Name = "ERICB", Value = 81
                });
                db.Prices.Add(new Price()
                {
                    Date = new DateTime(2019, 1, 3), Name = "ERICB", Value = 82
                });
                db.Prices.Add(new Price()
                {
                    Date = new DateTime(2019, 1, 4), Name = "ERICB", Value = 0
                });
                db.Prices.Add(new Price()
                {
                    Date = new DateTime(2019, 1, 5), Name = "ERICB", Value = 86
                });
                db.SaveChanges();

                var prices = new[]
                {
                    db.Prices.Add(new Price()
                    {
                        Date = new DateTime(2019, 1, 1), Name = "ERICB", Value = 80
                    }),
                    db.Prices.Add(new Price()
                    {
                        Date = new DateTime(2019, 1, 2), Name = "ERICB", Value = 81
                    }),
                    db.Prices.Add(new Price()
                    {
                        Date = new DateTime(2019, 1, 3), Name = "ERICB", Value = 82
                    }),
                    db.Prices.Add(new Price()
                    {
                        Date = new DateTime(2019, 1, 4), Name = "ERICB", Value = null
                    }),
                    db.Prices.Add(new Price()
                    {
                        Date = new DateTime(2019, 1, 5), Name = "ERICB", Value = 86
                    })
                };
                var existing = db.BulkSelectExisting <Price, Price>(
                    new BulkSelectRequest <Price>(new[] { "Date", "Name", "Value" }, prices));
                Assert.AreEqual(4, existing.Count);
                Assert.AreSame(prices[0], existing[0]);
                Assert.AreSame(prices[1], existing[1]);
                Assert.AreSame(prices[2], existing[2]);
                Assert.AreSame(prices[4], existing[3]);
            }
        }
Пример #15
0
            /// <summary>
            /// Get all applicable price price groups from price context.
            /// </summary>
            /// <param name="priceContext">Price context.</param>
            /// <param name="itemCatalogIds">Item catalog identifiers.</param>
            /// <returns>All applicable price price groups.</returns>
            /// <remarks>We could have made it an C# extension. Leave it here for all price context logic.</remarks>
            public static ISet <string> GetApplicablePriceGroupsForPrice(PriceContext priceContext, ISet <long> itemCatalogIds)
            {
                if (priceContext == null)
                {
                    throw new ArgumentNullException("priceContext");
                }

                return(GetApplicablePriceGroups(priceContext, GetAllPriceGroupsExceptCatalogsForPrice(priceContext), itemCatalogIds));
            }
Пример #16
0
 /// <summary>
 /// Add channel price groups.
 /// </summary>
 /// <param name="priceContext">Price context.</param>
 /// <param name="priceGroups">Price groups.</param>
 /// <remarks>This is private. Exposed as internal for test.</remarks>
 internal static void AddChannelPriceGroups(PriceContext priceContext, IEnumerable <PriceGroup> priceGroups)
 {
     AddPriceGroupsToCollections(
         priceGroups,
         priceContext.ChannelPriceGroups,
         priceContext.PriceGroupIdsToRecordIdsDictionary,
         priceContext.RecordIdsToPriceGroupIdsDictionary,
         priceContext.PriceGroupIdToPriorityDictionary);
 }
 public Form1(Pubulish pubulish, string keyWord)
 {
     InitializeComponent();
     pubulish.ButtonClick += Pubulish_ButtonClick;
     context                 = new PriceContext();
     listView1.GridLines     = true;
     listView1.FullRowSelect = true;
     this.keyWord            = keyWord;
 }
Пример #18
0
            /// <summary>
            /// Check whether it is applicable for price.
            /// </summary>
            /// <param name="priceContext">Price context.</param>
            /// <param name="pricePriceGroups">Price price groups.</param>
            /// <param name="itemCatalogIds">Item catalog identifiers.</param>
            /// <returns>True if it is applicable.</returns>
            public static bool IsApplicableForPrice(PriceContext priceContext, ISet <string> pricePriceGroups, ISet <long> itemCatalogIds)
            {
                if (priceContext == null)
                {
                    throw new ArgumentNullException("priceContext");
                }

                return(IsApplicable(pricePriceGroups, GetApplicablePriceGroupsForPrice(priceContext, itemCatalogIds)));
            }
Пример #19
0
            /// <summary>
            /// Get all price groups for price from price context.
            /// </summary>
            /// <param name="priceContext">Price context.</param>
            /// <returns>All price groups for price.</returns>
            /// <remarks>We could have made it an C# extension. Leave it here for all price context logic.</remarks>
            public static ISet <string> GetAllPriceGroupsForPrice(PriceContext priceContext)
            {
                if (priceContext == null)
                {
                    throw new ArgumentNullException("priceContext");
                }

                return(GetAllPriceGroups(priceContext, GetAllPriceGroupsExceptCatalogsForPrice(priceContext)));
            }
Пример #20
0
            /// <summary>
            /// This method will calculate the prices for the whole sales transaction.
            /// </summary>
            /// <param name="salesTransaction">Sales transaction.</param>
            /// <param name="pricingDataManager">Provides access to the pricing data to the pricing calculation.</param>
            /// <param name="currencyAndRoundingHelper">Currency and rounding helper.</param>
            /// <param name="customerPriceGroup">Customer price group.</param>
            /// <param name="currencyCode">Current code.</param>
            /// <param name="activeDate">Active date time offset for price.</param>
            /// <remarks>Parallel processing has been disabled, but we leave parameter here for backward compatibility.</remarks>
            public static void CalculatePricesForTransaction(
                SalesTransaction salesTransaction,
                IPricingDataAccessor pricingDataManager,
                ICurrencyOperations currencyAndRoundingHelper,
                string customerPriceGroup,
                string currencyCode,
                DateTimeOffset activeDate)
            {
                if (salesTransaction == null)
                {
                    throw new ArgumentNullException("salesTransaction");
                }

                if (pricingDataManager == null)
                {
                    throw new ArgumentNullException("pricingDataManager");
                }

                if (currencyAndRoundingHelper == null)
                {
                    throw new ArgumentNullException("currencyAndRoundingHelper");
                }

                ISet <long> catalogIds = PriceContextHelper.GetCatalogIds(salesTransaction);
                IEnumerable <AffiliationLoyaltyTier> affiliationLoyaltyTiers = PriceContextHelper.GetAffiliationLoyalTierIds(salesTransaction);

                ISet <string> itemIds      = PriceContextHelper.GetItemIds(salesTransaction);
                PriceContext  priceContext = PriceContextHelper.CreatePriceContext(
                    pricingDataManager,
                    currencyAndRoundingHelper,
                    PricingCalculationMode.Transaction,
                    DiscountCalculationMode.None,
                    itemIds,
                    catalogIds,
                    affiliationLoyaltyTiers,
                    salesTransaction.CustomerId,
                    customerPriceGroup,
                    salesTransaction.IsTaxIncludedInPrice,
                    currencyCode,
                    activeDate);

                bool isDiagnosticsCollected = GetCollectDiagnostics(salesTransaction);

                if (isDiagnosticsCollected)
                {
                    priceContext.IsDiagnosticsCollected         = true;
                    priceContext.PricingEngineDiagnosticsObject = new PricingEngineDiagnosticsObject();
                }

                PricingEngine.CalculatePricesForSalesLines(salesTransaction.PriceCalculableSalesLines, priceContext, pricingDataManager);

                if (isDiagnosticsCollected)
                {
                    SetPricingEngineDiagnosticsObject(salesTransaction, priceContext.PricingEngineDiagnosticsObject);
                }
            }
Пример #21
0
 private static void SetEffectiveDiscountPriorityFromPriceGroups(
     Dictionary <string, DiscountBase> discountsLookup,
     PriceContext priceContext)
 {
     foreach (KeyValuePair <string, DiscountBase> pair in discountsLookup)
     {
         DiscountBase discount = pair.Value;
         SetEffectiveDiscounDiscountPriorityFromPriceGroups(discount, priceContext);
     }
 }
Пример #22
0
            private static HashSet <string> GetAllPriceGroups(PriceContext priceContext, HashSet <string> allPriceGroupsExceptCatalogs)
            {
                HashSet <string> allPriceGroups = new HashSet <string>(allPriceGroupsExceptCatalogs);

                foreach (KeyValuePair <long, ISet <string> > priceGroups in priceContext.CatalogPriceGroups)
                {
                    allPriceGroups.UnionWith(priceGroups.Value);
                }

                return(allPriceGroups);
            }
Пример #23
0
            private static HashSet <string> GetAllPriceGroupsExceptCatalogsForPrice(PriceContext priceContext)
            {
                HashSet <string> allPriceGroupsExceptCatalogsForPrice = GetAllPriceGroupsExceptCatalogsForDiscount(priceContext);

                if (!string.IsNullOrWhiteSpace(priceContext.CustomerPriceGroup))
                {
                    allPriceGroupsExceptCatalogsForPrice.Add(priceContext.CustomerPriceGroup);
                }

                return(allPriceGroupsExceptCatalogsForPrice);
            }
Пример #24
0
            /// <summary>
            /// Get all price group identifiers from price context.
            /// </summary>
            /// <param name="priceContext">Price context.</param>
            /// <returns>All price groups.</returns>
            public static IEnumerable <long> GetAllPriceGroupIdsForDiscount(PriceContext priceContext)
            {
                if (priceContext == null)
                {
                    throw new ArgumentNullException("priceContext");
                }

                HashSet <string> groups = GetAllPriceGroupsForDiscount(priceContext);

                return(priceContext.PriceGroupIdsToRecordIdsDictionary.Where(p => groups.Contains(p.Key)).Select(p => p.Value));
            }
Пример #25
0
 /// <summary>
 /// Apply the discount applications, taking into account previously applied discounts.
 /// </summary>
 /// <param name="discountableItemGroups">The line items in the transaction.</param>
 /// <param name="remainingQuantities">The quantities remaining for each item.</param>
 /// <param name="appliedDiscounts">The previously applied discounts.</param>
 /// <param name="priceContext">The pricing context to use.</param>
 /// <returns>The value of this application of the discount.</returns>
 public AppliedDiscountApplication Apply(
     DiscountableItemGroup[] discountableItemGroups,
     decimal[] remainingQuantities,
     IEnumerable <AppliedDiscountApplication> appliedDiscounts,
     PriceContext priceContext)
 {
     return(this.Discount.GetAppliedDiscountApplication(
                discountableItemGroups,
                remainingQuantities,
                appliedDiscounts,
                this,
                priceContext));
 }
Пример #26
0
 public static void SeedPrice(PriceContext context)
 {
     if (!context.Price.Any())
     {
         var priceData = System.IO.File.ReadAllText("../SeedData/Data/PriceSeedJson.json");
         var price     = JsonConvert.DeserializeObject <List <Prica> >(priceData);
         foreach (var prica in price)
         {
             context.Price.Add(prica);
         }
         context.SaveChanges();
     }
 }
Пример #27
0
 public static void SeedQuestions(PriceContext context)
 {
     if (!context.Pitanja.Any())
     {
         var pitanjaData = System.IO.File.ReadAllText("../SeedData/Data/PitanjaSeedJson.json");
         var pitanja     = JsonConvert.DeserializeObject <List <Pitanje> >(pitanjaData);
         foreach (var prica in pitanja)
         {
             context.Pitanja.Add(prica);
         }
         context.SaveChanges();
     }
 }
Пример #28
0
            /// <summary>
            /// Get item by item identifier.
            /// </summary>
            /// <param name="priceContext">Price context.</param>
            /// <param name="itemId">Item identifier.</param>
            /// <returns>The item.</returns>
            public static Item GetItem(PriceContext priceContext, string itemId)
            {
                if (priceContext == null)
                {
                    throw new ArgumentNullException("priceContext");
                }

                Item item = null;

                priceContext.ItemCache.TryGetValue(itemId, out item);

                return(item);
            }
            /// <summary>
            /// Implements the IPricingCalculator interface to calculate item price trade agreement prices.
            /// </summary>
            /// <param name="salesLines">The item lines which need prices.</param>
            /// <param name="priceContext">The configuration of the overall pricing context for the calculation.</param>
            /// <param name="pricingDataManager">Instance of pricing data manager to access pricing data.</param>
            /// <returns>Sets of possible price lines keyed by item line Id.</returns>
            public Dictionary <string, IEnumerable <PriceLine> > CalculatePriceLines(
                IEnumerable <SalesLine> salesLines,
                PriceContext priceContext,
                IPricingDataAccessor pricingDataManager)
            {
                Tuple <DateTimeOffset, DateTimeOffset> dateRange = PricingEngine.GetMinAndMaxActiveDates(salesLines, priceContext.ActiveDate);

                // look up all trade agreements for given items and context
                HashSet <string> itemIds = new HashSet <string>(salesLines.Select(s => s.ItemId).Distinct(), StringComparer.OrdinalIgnoreCase);
                ReadOnlyCollection <TradeAgreement> tradeAgreements = pricingDataManager.ReadPriceTradeAgreements(
                    itemIds,
                    PriceContextHelper.GetAllPriceGroupsForPrice(priceContext),
                    priceContext.CustomerAccount,
                    dateRange.Item1,
                    dateRange.Item2,
                    priceContext.CurrencyCode,
                    QueryResultSettings.AllRecords) as ReadOnlyCollection <TradeAgreement>;

                if (priceContext.IsDiagnosticsCollected && tradeAgreements.Any())
                {
                    priceContext.PricingEngineDiagnosticsObject.AddTradeAgreementsConsidered(tradeAgreements.ToList());
                }

                var agreementsByItemId = IndexAgreementsByItemId(tradeAgreements);

                var discountParameters = DiscountParameters.CreateAndInitialize(priceContext.PriceParameters);

                Dictionary <string, IEnumerable <PriceLine> > itemPriceLines;
                Dictionary <string, decimal> itemQuantites = null;

                if (priceContext.PriceCalculationMode == PricingCalculationMode.Transaction)
                {
                    itemQuantites = GetItemQuantities(salesLines);
                }

                itemPriceLines = new Dictionary <string, IEnumerable <PriceLine> >(StringComparer.OrdinalIgnoreCase);

                foreach (SalesLine salesLine in salesLines)
                {
                    Tuple <decimal, string> priceCustPriceGroup = CalculateAgreementPriceLine(salesLines, salesLine, priceContext, agreementsByItemId, discountParameters, itemQuantites);
                    if (priceCustPriceGroup.Item1 != decimal.Zero)
                    {
                        itemPriceLines.Add(salesLine.LineId, new List <PriceLine>(1)
                        {
                            ConstructTradeAgreementPriceLine(priceCustPriceGroup)
                        });
                    }
                }

                return(itemPriceLines);
            }
Пример #30
0
 private static void InitializeItemCache(
     PriceContext priceContext,
     IPricingDataAccessor pricingDataManager,
     ISet <string> itemIds)
 {
     if (itemIds != null && itemIds.Count > 0)
     {
         ReadOnlyCollection <Item> items = pricingDataManager.GetItems(itemIds) as ReadOnlyCollection <Item>;
         foreach (Item item in items)
         {
             priceContext.ItemCache.Add(item.ItemId, item);
         }
     }
 }