public IHttpActionResult GetDashboardStatistics([FromUri] DateTime?start = null, [FromUri] DateTime?end = null) { webModel.DashboardStatisticsResult retVal = null; start = start ?? DateTime.UtcNow.AddYears(-1); end = end ?? DateTime.UtcNow; // Hack: to compinsate for incorrect Local dates to UTC end = end.Value.AddDays(2); var cacheKey = CacheKey.Create("Statistic", start.Value.ToString("yyyy-MM-dd"), end.Value.ToString("yyyy-MM-dd")); lock (_lockObject) { retVal = _cacheManager.Get(cacheKey, () => { var collectStaticJob = new CollectOrderStatisticJob(_repositoryFactory, _cacheManager); return(collectStaticJob.CollectStatistics(start.Value, end.Value)); }); } return(Ok(retVal)); }
public DashboardStatisticsResult CollectStatistics(DateTime start, DateTime end) { var retVal = new DashboardStatisticsResult(); using (var repository = _repositoryFactory()) { var currencies = repository.InPayments.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Where(x => !x.IsCancelled) .GroupBy(x => x.Currency).Select(x => x.Key); retVal.OrderCount = repository.CustomerOrders.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Where(x => !x.IsCancelled).Count(); //avg order value var avgValues = repository.CustomerOrders.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .GroupBy(x => x.Currency) .Select(x => new { Currency = x.Key, AvgValue = x.Select(y=>y.Sum).DefaultIfEmpty(0).Average() }) .ToArray(); retVal.AvgOrderValue = avgValues.Select(x=> new Money(x.Currency, x.AvgValue) ).ToList(); //Revenue var revenues = repository.InPayments.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Where(x => !x.IsCancelled) .GroupBy(x => x.Currency).Select(x => new { Currency = x.Key, Value = x.Select(y=>y.Sum).DefaultIfEmpty(0).Sum() }) .ToArray(); retVal.Revenue = revenues.Select(x => new Money(x.Currency, x.Value)).ToList(); retVal.RevenuePeriodDetails = new List<QuarterPeriodMoney>(); retVal.AvgOrderValuePeriodDetails = new List<QuarterPeriodMoney>(); var endDate = end; foreach (var currency in currencies) { for (var startDate = start; startDate < end; startDate = endDate) { endDate = startDate.AddMonths(3 - ((startDate.Month - 1)% 3)); endDate = new DateTime(endDate.Year, endDate.Month, 1); endDate = new DateTime(Math.Min(end.Ticks, endDate.Ticks)); var quarter = (int)((startDate.Month - 1) / 3) + 1; var amount = repository.InPayments.Where(x => x.CreatedDate >= startDate && x.CreatedDate <= endDate) .Where(x => !x.IsCancelled & x.Currency == currency).Select(x=>x.Sum).DefaultIfEmpty(0).Sum(); var avgOrderValue = repository.CustomerOrders.Where(x => x.CreatedDate >= startDate && x.CreatedDate <= endDate) .Where(x => x.Currency == currency) .Select(x=>x.Sum).DefaultIfEmpty(0).Average(); var periodStat = new QuarterPeriodMoney(currency, amount) { Quarter = quarter, Year = startDate.Year }; retVal.RevenuePeriodDetails.Add(periodStat); periodStat = new QuarterPeriodMoney(currency, avgOrderValue) { Quarter = quarter, Year = startDate.Year }; retVal.AvgOrderValuePeriodDetails.Add(periodStat); } } //RevenuePerCustomer var revenuesPerCustomer = repository.InPayments.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Where(x => !x.IsCancelled).GroupBy(x => x.Currency) .Select(x => new { Currency = x.Key, AvgValue = x.GroupBy(y => y.CustomerId).Average(y => y.Sum(z => z.Sum)) }) .ToArray(); retVal.RevenuePerCustomer = revenuesPerCustomer.Select(x => new Money(x.Currency, x.AvgValue)).ToList(); //Items purchased retVal.ItemsPurchased = repository.CustomerOrders.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Where(x => !x.IsCancelled).SelectMany(x => x.Items).Count(); //Line items per order retVal.LineitemsPerOrder = repository.CustomerOrders.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Where(x => !x.IsCancelled).Select(x=>x.Items.Count()).DefaultIfEmpty(0).Average(); //Customer count retVal.CustomersCount = repository.CustomerOrders.Where(x => x.CreatedDate >= start && x.CreatedDate <= end) .Select(x => x.CustomerId).Distinct().Count(); } retVal.StartDate = start; retVal.EndDate = end; return retVal; }