Example #1
0
        public SmCalcRecommendation(SmScenario scenario, SmDenseSchedule schedule, decimal[] pricePath, int revisionId, bool isCsp = false)
        {
            ScheduleId            = schedule.ScheduleNumber;
            ScheduleMask          = scenario.ScheduleMask;
            ScheduleMarkdownCount = schedule.MarkdownCount;

            IsCsp      = isCsp;
            PricePath  = pricePath;
            RevisionId = revisionId;

            // Defaults
            Rank = 0;
            TotalMarkdownCount = 0;
            TerminalStock      = 0;
            TotalRevenue       = 0M;
            TotalCost          = 0M;
            TotalMarkdownCost  = 0M;
            FinalDiscount      = null;
            StockValue         = 0M;
            EstimatedProfit    = 0M;
            EstimatedSales     = 0M;
            SellThroughRate    = 0M;
            SellThroughTarget  = 0M;
            FinalMarkdownType  = MarkdownType.None;

            Projections = new List <SmCalcRecommendationProjection>();
        }
Example #2
0
        public static List <Tuple <int, decimal> > Optimise(SmDenseSchedule schedule, SmPriceLadder priceLadder)
        {
            var weeks         = schedule.MarkdownWeeks;
            var prices        = priceLadder.Values;
            var width         = weeks.Length;
            var height        = prices.Length;
            var markdownCount = weeks.Length;
            var minDepths     = weeks.Select(x => schedule.Constraints?.SingleOrDefault(y => y.Week == x)?.Min).ToArray();
            var maxDepths     = weeks.Select(x => schedule.Constraints?.SingleOrDefault(y => y.Week == x)?.Max).ToArray();

            if (prices.Length < markdownCount)
            {
                throw new ArgumentException("Insufficient number of price paths to satisfy markdown count requirement", nameof(prices));
            }

            var weekDiscounts     = new List <Tuple <int, decimal> >();
            var previousDiscounts = new List <decimal>();

            for (var w = 0; w < width; w++)
            {
                var week      = weeks[w];
                var discounts = new List <decimal>();

                for (var p = 0; p < height; p++)
                {
                    var discount = prices[p];

                    var isLong     = width - w >= markdownCount - p;
                    var isShort    = height - p >= markdownCount - w;
                    var isLow      = minDepths[w] != null && discount < minDepths[w];
                    var isHigh     = maxDepths[w] != null && discount > maxDepths[w];
                    var isMarkdown = !previousDiscounts.Any() || discount > previousDiscounts[0];

                    if (isLong && isShort && !isHigh & !isLow && isMarkdown)
                    {
                        discounts.Add(discount);
                    }
                }

                weekDiscounts.AddRange(discounts.Select(x => Tuple.Create(week, x)));
                previousDiscounts = discounts;
            }

            return(weekDiscounts);
        }