Esempio n. 1
0
            /// <summary>
            /// Gets maximum retail price from trade agreement.
            /// </summary>
            /// <param name="salesLine">The sales line.</param>
            /// <param name="context">The request context.</param>
            /// <returns>Maximum retail price from trade agreement.</returns>
            public decimal GetMaximumRetailPriceFromTradeAgreement(SalesLine salesLine, RequestContext context)
            {
                if (salesLine == null)
                {
                    throw new ArgumentNullException("salesLine");
                }

                decimal quantity = this.salesTransaction.ActiveSalesLines.Where(x => (x.ItemId == salesLine.ItemId) && (x.InventoryDimensionId == salesLine.InventoryDimensionId)).Sum(x => x.Quantity);

                if (quantity == decimal.Zero)
                {
                    quantity = 1;
                }

                if (!salesLine.BeginDateTime.IsValidAxDateTime())
                {
                    salesLine.BeginDateTime = context.GetNowInChannelTimeZone();
                }

                PriceResult priceResult = PricingEngine.GetActiveTradeAgreement(
                    this.pricingDataManager,
                    DiscountParameters.CreateAndInitialize(this.pricingDataManager),
                    this.channelConfiguration.Currency,
                    salesLine,
                    quantity,
                    this.customerId,
                    this.priceGroup,
                    salesLine.BeginDateTime);

                this.maxRetailPrice = priceResult.MaximumRetailPriceIndia;

                return(this.maxRetailPrice);
            }
Esempio n. 2
0
            /// <summary>
            /// Create a new DiscountParameters object and initialize from database if possible.
            /// </summary>
            /// <param name="pricingDataManager">Data manager to access pricing data.</param>
            /// <returns>Newly fetched and initialized DiscountParameters object.</returns>
            public static DiscountParameters CreateAndInitialize(IPricingDataAccessor pricingDataManager)
            {
                DiscountParameters parameters = new DiscountParameters();

                parameters.GetDiscountParameters(pricingDataManager);
                return(parameters);
            }
Esempio n. 3
0
            /// <summary>
            /// Create a new DiscountParameters object from the passed in data.
            /// </summary>
            /// <param name="priceParameters">Data model object representing price activation options.</param>
            /// <returns>Newly fetched and initialized DiscountParameters object.</returns>
            public static DiscountParameters CreateAndInitialize(PriceParameters priceParameters)
            {
                DiscountParameters parameters = new DiscountParameters();

                parameters.GetDiscountParameters(priceParameters);
                return(parameters);
            }
            /// <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);
            }
            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);
            }
            /// <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);
            }
            /// <summary>
            /// This function takes arguments (customer, item, currency, etc.) related to price (trade) agreement
            /// as well as the set of currently enabled trade agreement types. It returns the best trade agreement
            /// price for the given constraints.
            /// As in AX, the method searches for a price on the given item which has been given to a
            /// customer, price group, or anyone (in given precedence order). If a price is found and marked as
            /// SearchAgain=False, the search will terminate. Otherwise, search for lowest price will continue.
            /// To recap, the logic is that three searches are done for customer, price group, and all, each bracket
            /// will return the lowest price it has for the constraints. If it has SearchAgain=True, then the search
            /// for lowest price continues to the next bracket.
            /// </summary>
            /// <param name="tradeAgreementRules">Trade agreements applicable to each item, keyed by item relation (i.e. item Id).</param>
            /// <param name="args">Arguments for price agreement search.</param>
            /// <param name="priceParameters">Set of enabled price agreement types.</param>
            /// <param name="salesLines">Sales lines.</param>
            /// <param name="priceContext">Price context.</param>
            /// <param name="activeDate">Date to use for querying trade agreement rules.</param>
            /// <returns>
            /// Most applicable price for the given price agreement constraints.
            /// </returns>
            private static PriceResult ApplyPriceTradeAgreements(
                IDictionary <string, IList <TradeAgreement> > tradeAgreementRules,
                PriceAgreementArgs args,
                DiscountParameters priceParameters,
                IEnumerable <SalesLine> salesLines,
                PriceContext priceContext,
                DateTimeOffset activeDate)
            {
                PriceResult priceResult = new PriceResult(0M, PriceGroupIncludesTax.NotSpecified);

                var itemCodes    = new PriceDiscountItemCode[] { PriceDiscountItemCode.Item, PriceDiscountItemCode.ItemGroup, PriceDiscountItemCode.AllItems };
                var accountCodes = new PriceDiscountAccountCode[] { PriceDiscountAccountCode.Customer, PriceDiscountAccountCode.CustomerGroup, PriceDiscountAccountCode.AllCustomers };

                // Search through combinations of item/account codes from most to least specific.
                // This needs to match the behavior of AX code PriceDisc.findPriceAgreement().
                foreach (var accountCode in accountCodes)
                {
                    foreach (var itemCode in itemCodes)
                    {
                        if (priceParameters.Activation(PriceDiscountType.PriceSales, accountCode, itemCode))
                        {
                            IList <string> accountRelations = args.GetAccountRelations(accountCode);
                            string         itemRelation     = args.GetItemRelation(itemCode);

                            if (accountRelations.All(a => ValidRelation(accountCode, a)) &&
                                ValidRelation(itemCode, itemRelation))
                            {
                                bool searchAgain;
                                IEnumerable <TradeAgreement> tradeAgreements = FindPriceAgreements(tradeAgreementRules, args, itemCode, accountCode, salesLines, priceContext, activeDate);
                                PriceResult currentPriceResult = GetBestPriceAgreement(tradeAgreements, out searchAgain);

                                if (priceResult.Price == 0M ||
                                    (currentPriceResult.Price > 0M && currentPriceResult.Price < priceResult.Price))
                                {
                                    priceResult = currentPriceResult;
                                }

                                if (!searchAgain)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }

                return(priceResult);
            }
            private static Tuple <decimal, string> CalculateAgreementPriceLine(
                IEnumerable <SalesLine> salesLines,
                SalesLine salesLine,
                PriceContext priceContext,
                Dictionary <string, IList <TradeAgreement> > agreementsByItemId,
                DiscountParameters discountParameters,
                Dictionary <string, decimal> itemQuantites)
            {
                var quantity = salesLine.Quantity;

                // count all occurrences for this item if this is a transaction
                if (priceContext.PriceCalculationMode == PricingCalculationMode.Transaction)
                {
                    itemQuantites.TryGetValue(salesLine.ItemId, out quantity);

                    if (quantity == decimal.Zero)
                    {
                        quantity = 1m;
                    }
                }

                var activeDate = (salesLine.SalesDate != null) ? salesLine.SalesDate.Value : priceContext.ActiveDate;

                return(GetActiveTradeAgreementPriceAndGroup(
                           agreementsByItemId,
                           discountParameters,
                           priceContext.CurrencyCode,
                           salesLine.ItemId,
                           salesLine.OriginalSalesOrderUnitOfMeasure,
                           Discount.GetUnitOfMeasure(salesLine),
                           salesLine.Variant,
                           salesLine.UnitOfMeasureConversion,
                           quantity,
                           priceContext.CustomerAccount,
                           priceContext.CustomerPriceGroup,
                           PriceContextHelper.GetApplicablePriceGroupsForPrice(priceContext, salesLine.CatalogIds),
                           salesLines,
                           priceContext,
                           activeDate));
            }
            private static Tuple <decimal, string> GetActiveTradeAgreementPriceAndGroup(
                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 = GetPriceResultOfActiveTradeAgreement(
                    tradeAgreementRules,
                    priceParameters,
                    currencyCode,
                    itemId,
                    defaultSalesUnit,
                    salesUnit,
                    variantLine,
                    unitOfMeasureConversion,
                    quantity,
                    customerId,
                    customerPriceGroup,
                    channelPriceGroupIds,
                    salesLines,
                    priceContext,
                    activeDate);

                return(new Tuple <decimal, string>(result.Price, result.CustPriceGroup));
            }
 /// <summary>
 /// Initializes a new instance of the <see cref="MultilineDiscountCalculator"/> class with given configurations.
 /// </summary>
 /// <param name="discountParameters">Configuration dictating which trade agreement discount combinations are active.</param>
 /// <param name="priceContext">Price context.</param>
 public MultilineDiscountCalculator(DiscountParameters discountParameters, PriceContext priceContext)
 {
     this.discountParameters = discountParameters;
     this.priceContext       = priceContext;
 }
            /// <summary>
            /// Find and total all multiline discount trade agreements that match the given relations and quantity.
            /// </summary>
            /// <param name="tradeAgreements">Trade agreement collection to calculate on.</param>
            /// <param name="itemCode">The item code to search by (item group or all).</param>
            /// <param name="retailTransaction">The transaction context with Id and customer Id.</param>
            /// <param name="priceGroup">Multiline price group.</param>
            /// <param name="salesQuantity">Aggregated quantity for multiline price group.</param>
            /// <param name="percent1">Percentage one.</param>
            /// <param name="percent2">Percentage two.</param>
            /// <param name="discountAmount">Discount amount.</param>
            private void GetMultiLineDiscountLine(
                List <TradeAgreement> tradeAgreements,
                PriceDiscountItemCode itemCode,
                SalesTransaction retailTransaction,
                string priceGroup,
                decimal salesQuantity,
                out decimal percent1,
                out decimal percent2,
                out decimal discountAmount)
            {
                PriceDiscountType relation  = PriceDiscountType.MultilineDiscountSales; // Sales multiline discount - 6
                ProductVariant    dimension = new ProductVariant();

                percent1       = decimal.Zero;
                percent2       = decimal.Zero;
                discountAmount = decimal.Zero;

                bool searchAgain = true;
                var  codes       = new PriceDiscountAccountCode[] { PriceDiscountAccountCode.Customer, PriceDiscountAccountCode.CustomerGroup, PriceDiscountAccountCode.AllCustomers };

                foreach (var accountCode in codes)
                {
                    // skip to next configuration if this one isn't enabled
                    if (!this.discountParameters.Activation(relation, accountCode, itemCode))
                    {
                        continue;
                    }

                    // get item relation based on item code
                    string itemRelation = (itemCode == PriceDiscountItemCode.ItemGroup) ? priceGroup : string.Empty;
                    itemRelation = itemRelation ?? string.Empty;

                    // get customer relation based on account code
                    string accountRelation = string.Empty;
                    if (accountCode == PriceDiscountAccountCode.Customer)
                    {
                        accountRelation = retailTransaction.CustomerId;
                    }
                    else if (accountCode == PriceDiscountAccountCode.CustomerGroup)
                    {
                        accountRelation = this.priceContext.CustomerMultipleLinePriceGroup;
                    }

                    accountRelation = accountRelation ?? string.Empty;

                    // if both relations are valid for the given item and account codes, look for trade agreements matching these relations
                    if (DiscountParameters.ValidRelation(accountCode, accountRelation) &&
                        DiscountParameters.ValidRelation(itemCode, itemRelation))
                    {
                        // get any active multiline discount trade agreement matching relations and quantity
                        var priceDiscTable = Discount.GetPriceDiscData(tradeAgreements, relation, itemRelation, accountRelation, itemCode, accountCode, salesQuantity, this.priceContext, dimension, false);

                        // compute running sum of discount values found
                        foreach (TradeAgreement row in priceDiscTable)
                        {
                            percent1       += row.PercentOne;
                            percent2       += row.PercentTwo;
                            discountAmount += row.Amount;

                            // stop search when we find a trade agreement set to not find next trade agreement
                            if (!row.ShouldSearchAgain)
                            {
                                searchAgain = false;
                            }
                        }
                    }

                    // stop search if we found a discount without "find next" marked
                    if (!searchAgain)
                    {
                        break;
                    }
                }
            }
Esempio n. 12
0
 /// <summary>
 /// Initializes the specified runtime.
 /// </summary>
 /// <param name="pricingDataManager">Provides data access to the calculation.</param>
 public void Initialize(IPricingDataAccessor pricingDataManager)
 {
     this.DiscountParameters = DiscountParameters.CreateAndInitialize(pricingDataManager);
 }
Esempio n. 13
0
            private void GetLineDiscountLines(
                List <TradeAgreement> tradeAgreements,
                SalesLine saleItem,
                ref decimal absQty,
                ref decimal discountAmount,
                ref decimal percent1,
                ref decimal percent2,
                ref decimal minQty)
            {
                int idx = 0;

                while (idx < 9)
                {
                    PriceDiscountItemCode    itemCode    = (PriceDiscountItemCode)(idx % 3); // Mod divsion
                    PriceDiscountAccountCode accountCode = (PriceDiscountAccountCode)(idx / 3);

                    string accountRelation = string.Empty;
                    if (accountCode == PriceDiscountAccountCode.Customer)
                    {
                        accountRelation = this.priceContext.CustomerAccount;
                    }
                    else if (accountCode == PriceDiscountAccountCode.CustomerGroup)
                    {
                        accountRelation = this.priceContext.CustomerLinePriceGroup;
                    }

                    accountRelation = accountRelation ?? string.Empty;

                    string itemRelation;
                    if (itemCode == PriceDiscountItemCode.Item)
                    {
                        itemRelation = saleItem.ItemId;
                    }
                    else
                    {
                        Item item = PriceContextHelper.GetItem(this.priceContext, saleItem.ItemId);
                        itemRelation = item != null ? item.LineDiscountGroupId : string.Empty;
                    }

                    itemRelation = itemRelation ?? string.Empty;

                    PriceDiscountType relation = PriceDiscountType.LineDiscountSales; // Sales line discount - 5

                    if (this.discountParameters.Activation(relation, accountCode, itemCode))
                    {
                        if (DiscountParameters.ValidRelation(accountCode, accountRelation) &&
                            DiscountParameters.ValidRelation(itemCode, itemRelation))
                        {
                            bool dimensionDiscountFound = false;

                            if (saleItem.Variant != null && !string.IsNullOrEmpty(saleItem.Variant.VariantId))
                            {
                                var dimensionPriceDiscTable = Discount.GetPriceDiscData(tradeAgreements, relation, itemRelation, accountRelation, itemCode, accountCode, absQty, this.priceContext, saleItem.Variant, true);

                                foreach (TradeAgreement row in dimensionPriceDiscTable)
                                {
                                    bool unitsAreUndefinedOrEqual =
                                        string.IsNullOrEmpty(row.UnitOfMeasureSymbol) ||
                                        string.Equals(row.UnitOfMeasureSymbol, saleItem.SalesOrderUnitOfMeasure, StringComparison.OrdinalIgnoreCase);

                                    if (unitsAreUndefinedOrEqual)
                                    {
                                        percent1       += row.PercentOne;
                                        percent2       += row.PercentTwo;
                                        discountAmount += row.Amount;
                                        minQty         += row.QuantityAmountFrom;
                                    }

                                    if (percent1 > 0M || percent2 > 0M || discountAmount > 0M)
                                    {
                                        dimensionDiscountFound = true;
                                    }

                                    if (!row.ShouldSearchAgain)
                                    {
                                        idx = 9;
                                    }
                                }
                            }

                            if (!dimensionDiscountFound)
                            {
                                var priceDiscTable = Discount.GetPriceDiscData(tradeAgreements, relation, itemRelation, accountRelation, itemCode, accountCode, absQty, this.priceContext, saleItem.Variant, false);

                                foreach (TradeAgreement row in priceDiscTable)
                                {
                                    // Apply default if the unit of measure is not set from the cart.
                                    string unitOfMeasure = Discount.GetUnitOfMeasure(saleItem);

                                    bool unitsAreUndefinedOrEqual =
                                        string.IsNullOrEmpty(row.UnitOfMeasureSymbol) ||
                                        string.Equals(row.UnitOfMeasureSymbol, unitOfMeasure, StringComparison.OrdinalIgnoreCase);

                                    if (unitsAreUndefinedOrEqual)
                                    {
                                        percent1       += row.PercentOne;
                                        percent2       += row.PercentTwo;
                                        discountAmount += row.Amount;
                                        minQty         += row.QuantityAmountFrom;
                                    }

                                    if (!row.ShouldSearchAgain)
                                    {
                                        idx = 9;
                                    }
                                }
                            }
                        }
                    }

                    idx++;
                }
            }
Esempio n. 14
0
            internal static PriceResult GetActiveTradeAgreement(IPricingDataAccessor pricingDataManager, DiscountParameters priceParameters, string currencyCode, SalesLine saleItem, decimal quantity, string customerId, string customerPriceGroup, DateTimeOffset dateToCheck)
            {
                dateToCheck = saleItem.SalesDate ?? dateToCheck;

                IEnumerable <PriceGroup> priceGroups   = pricingDataManager.GetChannelPriceGroups() as IEnumerable <PriceGroup>;
                HashSet <string>         priceGroupIds = new HashSet <string>(priceGroups.Select(pg => pg.GroupId).Distinct(StringComparer.OrdinalIgnoreCase));

                PriceResult    result;
                ProductVariant variantLine = GetVariantFromLineOrDatabase(pricingDataManager, saleItem);

                variantLine = variantLine ?? new ProductVariant();

                Tuple <DateTimeOffset, DateTimeOffset> dateRange  = GetMinAndMaxActiveDates(new SalesLine[] { saleItem }, dateToCheck);
                ReadOnlyCollection <TradeAgreement>    agreements = pricingDataManager.ReadPriceTradeAgreements(
                    new HashSet <string> {
                    saleItem.ItemId
                },
                    priceGroupIds,
                    customerId,
                    dateRange.Item1,
                    dateRange.Item2,
                    currencyCode,
                    QueryResultSettings.AllRecords) as ReadOnlyCollection <TradeAgreement>;

                var agreementDict = new Dictionary <string, IList <TradeAgreement> >(StringComparer.OrdinalIgnoreCase);

                agreementDict.Add(saleItem.ItemId, agreements);

                result = TradeAgreementCalculator.GetPriceResultOfActiveTradeAgreement(
                    agreementDict,
                    priceParameters,
                    currencyCode,
                    saleItem.ItemId,
                    saleItem.OriginalSalesOrderUnitOfMeasure,
                    Discount.GetUnitOfMeasure(saleItem),
                    variantLine,
                    saleItem.UnitOfMeasureConversion,
                    quantity,
                    customerId,
                    customerPriceGroup,
                    priceGroupIds,
                    new List <SalesLine> {
                    saleItem
                },
                    new PriceContext(),
                    dateToCheck);

                return(result);
            }