public async Task <StatisticsReport> GetStatsAsync(StatisticEventType type, StatisticEventDimension dimension, DateTime start, int count, TimeInterval timeInterval, CancellationToken cancellationToken = default(CancellationToken))
        {
            var current = start;

            var results = new StatisticsReport()
            {
                StartDate = start,
                Interval  = timeInterval,
                Global    = new StatisticMetric {
                },
                Report    = new List <StatisticsPeriodReport>()
            };

            while (results.Report.Count() < count)
            {
                var currentEnd = start;
                switch (timeInterval)
                {
                case TimeInterval.Year:
                    currentEnd = current.AddYears(1);
                    break;

                case TimeInterval.Month:
                    currentEnd = current.AddMonths(1);
                    break;

                case TimeInterval.Day:
                    currentEnd = current.AddDays(1);
                    break;

                case TimeInterval.Hour:
                    currentEnd = current.AddHours(1);
                    break;

                case TimeInterval.Week:
                    currentEnd = current.AddDays(7);
                    break;
                }

                var filter = Filter.And(
                    Filter.Gte(nameof(IOrder.Date), current),
                    Filter.Lt(nameof(IOrder.Date), currentEnd),
                    Filter.Ne(nameof(IOrder.Canceled), true),
                    Filter.Eq(nameof(IOrder.OrderType), OrderType.Order)
                    );

                var periodResult = await FindAsync(filter, cancellationToken : cancellationToken);


                var dimensionsGroup = periodResult.GroupBy(r => _GetDimension(r, dimension) ?? "");
                var perdimensions   = dimensionsGroup.ToDictionary(
                    group => group.Key,
                    group => group.Select(g => new StatisticMetric()
                {
                    Amount = g.Total,
                    Sales  = 1,
                    Units  = g.Units
                }).Aggregate((m1, m2) => m1 + m2)
                    );

                var allevents = periodResult.Select(g => new StatisticMetric()
                {
                    Amount = g.Total, Sales = 1, Units = g.Units
                }).Where(e => e != null);
                var global = allevents.Any() ? allevents.Where(e => e != null).Aggregate((m1, m2) => m1 + m2) : new StatisticMetric();

                var stats = new StatisticsPeriodReport
                {
                    StartDate = current,
                    EndDate   = currentEnd,
                    Global    = global,
                    Dimension = perdimensions
                };

                results.Global += global;
                results.Report.Add(stats);
                current = currentEnd;
            }
            results.Currency = configuration.DefaultCurrency().Code;

            return(results);
        }
 // Used for mock services
 internal StatisticEvent(StatisticEventType type, XboxLiveUser user, StatisticEventArgs args)
 {
     EventType = type;
     EventArgs = args;
     User      = user;
 }
        public async Task <IActionResult> Reports([FromRoute] StatisticEventType eventType, [FromRoute] StatisticEventDimension dimension, [FromBody] ReportRequest binding, CancellationToken cancellationToken = default(CancellationToken))
        {
            var reports = await orderService.GetStatsAsync(eventType, dimension, binding.Start, binding.Count, binding.TimeInterval, cancellationToken);

            return(Ok(ApiModel.AsSuccess(reports)));
        }