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> /// 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); }