using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Web.Helpers; using System.Web.Mvc; using System.Web.Security; using ApacKernel; using ApacKernel.Authentication; using ApacKernel.Date; using ApacKernel.Extensions; using ApacKernel.Globalization; using ApacKernel.Web.MVC; using Now.Business; using Now.Business.WorkFlows; using Now.Entities; using Now.Entities.Measure; using Now.Repositories.DC; using Now.Web.JsonNet; using Now.Web.Models; using Now.Web.Services; namespace Now.Web.Controllers { internal class OutputCahePeriods { public const int Minute = 60; public const int TenMinutes = 10*Minute; public const int Hour = 60*Minute; public const int Day = 24*Hour; public const int Week = 7*Day; } [AttributeUsage(AttributeTargets.Method)] public class AjaxValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationContext filterContext) { try { if (filterContext.HttpContext.Request.IsAjaxRequest()) { ValidateRequestHeader(filterContext.HttpContext.Request); } else { AntiForgery.Validate(); } } catch (HttpAntiForgeryException) { throw new HttpAntiForgeryException("Anti forgery token not found"); } } private void ValidateRequestHeader(HttpRequestBase request) { string cookieToken = string.Empty; string formToken = string.Empty; string tokenValue = request.Headers["X-AFT"]; if (!string.IsNullOrEmpty(tokenValue)) { string[] tokens = tokenValue.Split(':'); if (tokens.Length == 2) { cookieToken = tokens[0].Trim(); formToken = tokens[1].Trim(); } } AntiForgery.Validate(cookieToken, formToken); } } [Compress] [ServerStamp] [HandleError] [HttpsRequired] [RoutePrefix("api")] public class ApiController : JsonNetController { static readonly TimeZoneInfo TimeZone = TimeZoneInfo.FindSystemTimeZoneById(ApacConfig.AppSettings.TimeZone()); private readonly ILoginService _loginService; private readonly IPermissionProvider _permissionProvider; public ApiController(ILoginService loginService, IPermissionProvider userPermissionService) { _loginService = loginService; _permissionProvider = userPermissionService; } [HttpGet] [Route("mainmenu")] public ActionResult MainMenu() { return JsonNet(ApiWorkflow.Instance.GetMainMenu(), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Week, VaryByParam = "*")] [Route("leftmenu/{controllerName}/{viewName}")] public ActionResult LeftMenu(string controllerName, string viewName) { var name = controllerName + "/" + viewName; return JsonNet(ApiWorkflow.Instance.GetLeftMenu(name), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Week, VaryByParam = "*", VaryByCustom = "MeasureKey")] [Route("measure/summary/{period:enum(Now.Entities.Measure.MeasureSummaryPeriods)}/{filter?}")] [Permission(DashboardPermissions.MeasureSummary)] public ActionResult GetMeasureSummary(MeasureSummaryPeriods period, string filter, string region, string site, string stockLocation, string stockType, string team, string teamCountry) { var objFilter = new MeasureObjectFilter { Region = HttpUtility.UrlDecode(region), Site = HttpUtility.UrlDecode(site), StockLocation = HttpUtility.UrlDecode(stockLocation), StockType = HttpUtility.UrlDecode(stockType), Team = HttpUtility.UrlDecode(team), TeamCountry = HttpUtility.UrlDecode(teamCountry) }; return JsonNet(MeasureWorkflow.Instance.GetSummary(period, filter, new DateTime(2015, 06, 30), objFilter), JsonRequestBehavior.AllowGet); } [HttpGet] [Route("measure/summary/common/live/" + "{period:enum(Now.Entities.Measure.MeasureSummaryPeriods)}/" + "{filter?}")] [Permission(DashboardPermissions.MeasureSummaryLive)] [OutputCache(Duration = OutputCahePeriods.Hour, VaryByParam = "*")] public ActionResult GetCommonMeasureSummaryLive(MeasureSummaryPeriods period, string filter, string region, string site, string stockLocation, string stockType, string team, string teamCountry) { var objFilter = new MeasureObjectFilter { Region = HttpUtility.UrlDecode(region), Site = HttpUtility.UrlDecode(site), StockLocation = HttpUtility.UrlDecode(stockLocation), StockType = HttpUtility.UrlDecode(stockType), Team = HttpUtility.UrlDecode(team), TeamCountry = HttpUtility.UrlDecode(teamCountry) }; return JsonNet(MeasureServiceWorkflow.Instance.GetSummary(period, filter, DateTime.Today, objFilter, MeasureBudgetTypes.Live), JsonRequestBehavior.AllowGet); } [HttpGet] [Route("measure/summary/common/buyers/" + "{period:enum(Now.Entities.Measure.MeasureSummaryPeriods)}/" + "{filter?}")] [Permission(DashboardPermissions.MeasureSummaryBuyers)] [OutputCache(Duration = OutputCahePeriods.Hour, VaryByParam = "*")] public ActionResult GetCommonMeasureSummaryBuyers(MeasureSummaryPeriods period, string filter, string region, string site, string stockLocation, string stockType, string team, string teamCountry) { var objFilter = new MeasureObjectFilter { Region = HttpUtility.UrlDecode(region), Site = HttpUtility.UrlDecode(site), StockLocation = HttpUtility.UrlDecode(stockLocation), StockType = HttpUtility.UrlDecode(stockType), Team = HttpUtility.UrlDecode(team), TeamCountry = HttpUtility.UrlDecode(teamCountry) }; return JsonNet(MeasureServiceWorkflow.Instance.GetSummary(period, filter, DateTime.Today, objFilter, MeasureBudgetTypes.Buyers), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Week, VaryByParam = "*", VaryByCustom = "MeasureKey")] [Route("measure/summary/filter")] public ActionResult GetMeasureSummaryFilter() { return JsonNet(MeasureWorkflow.Instance.GetSummaryFilter(), JsonRequestBehavior.AllowGet); } [HttpGet] [Route("measure/summary/filter/common")] [OutputCache(Duration = OutputCahePeriods.Hour, VaryByParam = "*")] public ActionResult GetCommonMeasureSummaryFilters() { return JsonNet(MeasureServiceWorkflow.Instance.GetFilters(), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Week, VaryByParam = "*", VaryByCustom = "MeasureKey")] [Route("measure/flash/{year:int:min(2007)?}/{week:int:min(1):max(53)?}")] [Permission(DashboardPermissions.MeasureFlash)] public ActionResult GetMeasureFlash(int? year, int? week, string filter, string region, string site, string stockLocation, string stockType, string team, string teamCountry) { var objFilter = new MeasureObjectFilter { Region = HttpUtility.UrlDecode(region), Site = HttpUtility.UrlDecode(site), StockLocation = HttpUtility.UrlDecode(stockLocation), StockType = HttpUtility.UrlDecode(stockType), Team = HttpUtility.UrlDecode(team), TeamCountry = HttpUtility.UrlDecode(teamCountry) }; var today = DateTime.Today; return JsonNet( MeasureWorkflow.Instance.GetFlash(year ?? today.Year, week ?? today.GetWeekOfYear(), filter, objFilter), JsonRequestBehavior.AllowGet); } [HttpGet] [Route("measure/flash/live/{year:int:min(2007)?}/{week:int:min(1):max(53)?}")] [OutputCache(Duration = OutputCahePeriods.Hour, VaryByParam = "*")] [Permission(DashboardPermissions.MeasureFlashLive)] public ActionResult GetMeasureFlashLive(int? year, int? week, string filter, string region, string site, string stockLocation, string stockType, string team, string teamCountry) { var objFilter = new MeasureObjectFilter { Region = HttpUtility.UrlDecode(region), Site = HttpUtility.UrlDecode(site), StockLocation = HttpUtility.UrlDecode(stockLocation), StockType = HttpUtility.UrlDecode(stockType), Team = HttpUtility.UrlDecode(team), TeamCountry = HttpUtility.UrlDecode(teamCountry) }; var today = DateTime.Today; return JsonNet(MeasureServiceWorkflow.Instance.GetFlash(year ?? today.Year, week ?? today.GetWeekOfYear(), filter, DateTime.Today, objFilter, MeasureBudgetTypes.Live), JsonRequestBehavior.AllowGet); } [HttpGet] [Route("measure/flash/buyers/{year:int:min(2007)?}/{week:int:min(1):max(53)?}")] [OutputCache(Duration = OutputCahePeriods.Hour, VaryByParam = "*")] [Permission(DashboardPermissions.MeasureFlashBuyers)] public ActionResult GetMeasureFlashyBuyers(int? year, int? week, string filter, string region, string site, string stockLocation, string stockType, string team, string teamCountry) { var objFilter = new MeasureObjectFilter { Region = HttpUtility.UrlDecode(region), Site = HttpUtility.UrlDecode(site), StockLocation = HttpUtility.UrlDecode(stockLocation), StockType = HttpUtility.UrlDecode(stockType), Team = HttpUtility.UrlDecode(team), TeamCountry = HttpUtility.UrlDecode(teamCountry) }; var today = DateTime.Today; return JsonNet(MeasureServiceWorkflow.Instance.GetFlash(year ?? today.Year, week ?? today.GetWeekOfYear(), filter, DateTime.Today, objFilter, MeasureBudgetTypes.Buyers), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.TenMinutes, VaryByParam = "*")] [Route("revenue/weeks/{countryID?}")] [Permission(DashboardPermissions.RevenueWeekly)] public ActionResult GetRevenueWeeks(string countryID) { return Json(RevenueWorkflow.Instance.GetRevenueSeries(countryID), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Minute, VaryByParam = "*")] [Route("revenue/overview/countries")] [Permission(DashboardPermissions.RevenueOverview)] public ActionResult GetRevenueOverviewCountries(string period) { var pt = PeriodsHelper.GetPeriodTypeByRangeName(period); var p = Period.GetPeriod(pt, TimeZone); return JsonNet(RevenueServiceWorkflow.Instance.GetCountriesOverall(p), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Minute, VaryByParam = "*")] [Route("revenue/overview/sales")] [Permission(DashboardPermissions.RevenueOverview)] public ActionResult GetRevenueOverviewSales(string period) { var pt = PeriodsHelper.GetPeriodTypeByRangeName(period); var p = Period.GetPeriod(pt, TimeZone); return Json(RevenueServiceWorkflow.Instance.GetSalesOverall(p), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Minute, VaryByParam = "*")] [Route("revenue/sales")] [Permission(DashboardPermissions.RevenueSales)] public ActionResult GetRevenueSales(string period) { var pt = PeriodsHelper.GetPeriodTypeByRangeName(period); var p = Period.GetPeriod(pt, TimeZone); return JsonNet(RevenueServiceWorkflow.Instance.GetSalesOverall(p), JsonRequestBehavior.AllowGet); } [Route("measure/csv/upload")] [HttpPost] [Permission(DashboardPermissions.Administration)] public ActionResult UploadMeasureCsv() { var path = Path.Combine(HttpContext.Server.MapPath(ApacConfig.AppSettings.MeasureFileFolder()), ApacConfig.AppSettings.MeasureBudgetFileName()); var file = Request.Files["budgetFile"]; bool changed = false; if (file != null && file.FileName.IsNotNullOrTrimEmpty()) { file.SaveAs(path); MeasureWorkflow.Instance.LoadBudgetFile(path); changed = true; } path = Path.Combine(HttpContext.Server.MapPath(ApacConfig.AppSettings.MeasureFileFolder()), ApacConfig.AppSettings.MeasureActualFileName()); file = Request.Files["actualFile"]; if (file != null && file.FileName.IsNotNullOrTrimEmpty()) { file.SaveAs(path); MeasureWorkflow.Instance.LoadActualFile(path); changed = true; } if (changed) HttpContext.Application["MeasureKey"] = Guid.NewGuid(); return RedirectToAction("Summary", "Measure"); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.TenMinutes, VaryByParam = "*")] [Route("consolidation/dispatchedOrders/{interval?}")] [Permission(DashboardPermissions.ConsolidationStatistic)] public ActionResult GetDispatchedOrdersByDate(string interval) { interval = string.IsNullOrEmpty(interval) ? "week" : interval; var data = ConsolidationWorkflow.Instance.GetDipatchedOrdersByDate(interval); return JsonNet(data, JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Minute, VaryByParam = "*")] [Route("recommendations/settings")] [Permission(DashboardPermissions.RecommendationsSetup)] public ActionResult GetRecommendationsSettings() { var repository = new RecommendationSystemRepository(); return JsonNet(repository.GetConsumersSetUp(), JsonRequestBehavior.AllowGet); } [HttpGet] [OutputCache(Duration = OutputCahePeriods.Minute, VaryByParam = "*")] [Route("recommendations")] [Permission(DashboardPermissions.Recommendations)] public ActionResult GetRecommendations() { var repository = new RecommendationSystemRepository(); return JsonNet(repository.GetRecommendationData(), JsonRequestBehavior.AllowGet); } [HttpGet] [Route("measure/flash/period/{year?}/{week?}")] [Permission(DashboardPermissions.MeasureFlash)] public ActionResult GetFlashPeriodFilter(int? year, int? week) { var today = DateTime.Today; week = week ?? today.GetWeekOfYear(); year = year ?? today.Year; var prevWeek = week - 1; var nextWeek = week + 1; var prevYear = year; var nextYear = year; if (prevWeek < 1) { prevWeek = 53; prevYear = prevYear - 1; } if (nextWeek > 53) { nextWeek = 1; nextYear = nextYear + 1; } nextWeek = nextWeek > 53 ? 1 : nextWeek; ViewBag.CurrentSelectionWeek = week; ViewBag.CurrentSelectionYear = year; var result = new List { new {period = prevYear + "/" + prevWeek, text = HttpUtility.HtmlEncode("")} }; return JsonNet(result, JsonRequestBehavior.AllowGet); } [HttpPost] [AllowAnonymous] [AjaxValidateAntiForgeryToken] [Route("users/login")] public ActionResult Login(LoginModel loginModel) { ActionResult result; if (!ModelState.IsValid) { return JsonNet(new LoginErrorModel { Message = "Invalid username or password" }); } try { var status = _loginService.Login(loginModel.UserName, loginModel.Password); if (status.Success) { var now = DateTime.Now; FormsAuthentication.SetAuthCookie(loginModel.UserName, true); var cookie = FormsAuthentication.GetAuthCookie(loginModel.UserName, true); cookie.Expires = now.AddMonths(1); var ticket = FormsAuthentication.Decrypt(cookie.Value); var userId = status.UserID.ToString("D"); var userLoginData = new DashboardsUserLoginData { Fullname = status.FullName, Login = loginModel.UserName, LoggedTime = now, ExpiredTime = cookie.Expires, UserID = userId, Permissions = ((DashboardsPermissionService)_permissionProvider).LoadPermissions(new Guid(userId)).Cast().ToArray() }; var userLoginJson = userLoginData.SerializeToJson(); if (ticket != null) { var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userLoginJson, ticket.CookiePath); var encTicket = FormsAuthentication.Encrypt(newTicket); cookie.Value = encTicket; System.Web.HttpContext.Current.Response.Cookies.Add(cookie); } result = JsonNet(new { url = loginModel.ReturnUrl ?? "/" }); } else { var error = new LoginErrorModel(); var msg = status.Message; error.Message = msg.Contains("Only staff login allowed") ? "Only staff login allowed" : msg.Contains("Invalid username or password") ? "Invalid username or password" : "Login failed"; result = JsonNet(error); } } catch (Exception e) { var error = new LoginErrorModel { Message = "Exception occured", Exception = e.ToString() }; result = JsonNet(error); } return result; } } }