public HttpResponseMessage PostDailyStat(DailyStats dailyStat) { var createdDailyStat = DailyStatsServices.CreateDailyStat(dailyStat); // If stats already exists within database, return 409. if (createdDailyStat == null) { var alreadyExistsResponse = Request.CreateResponse (HttpStatusCode.Conflict, "(409) Daily Stat already exists", Configuration.Formatters.JsonFormatter); alreadyExistsResponse.Headers.Add("API-Version", apiVersion); alreadyExistsResponse.Headers.Add("ERROR", "(409) Resource already exists"); return(alreadyExistsResponse); } // Daily Stat doesn't exist inside the database, proceed. else { var response = Request.CreateResponse(HttpStatusCode.Created, dailyStat, Configuration.Formatters.JsonFormatter); response.Headers.Add("API-Version", apiVersion); response.Headers.Add("Response-Type", "JSON"); if (Request.RequestUri.AbsoluteUri.EndsWith("/")) { response.Headers.Add("DailyStats-URL", Request.RequestUri.AbsoluteUri + createdDailyStat.ID); } else { response.Headers.Add("DailyStats-URL", Request.RequestUri.AbsoluteUri + "/" + createdDailyStat.ID); } return(response); } }
public async Task <DailyStats> CreateOrAddAsync(DailyStats dailyStats) { try { var oldDEnergy = await _DailyStats.Find(o => o.Date == dailyStats.Date && o.UserId == dailyStats.UserId).SingleOrDefaultAsync(); if (null == oldDEnergy) {//Create await _DailyStats.InsertOneAsync(dailyStats); } else {//Update dailyStats.Id = oldDEnergy.Id; dailyStats.Creativity += oldDEnergy.Creativity; dailyStats.Fluency += oldDEnergy.Fluency; dailyStats.Intelligence += oldDEnergy.Intelligence; dailyStats.Strength += oldDEnergy.Strength; await UpdateAsync(dailyStats); } return(dailyStats); } catch (Exception e) { _logger.LogError("Error cached in DailyEnergyServices CreateOrUpdateAsync {error}", e); return(null); } }
public HttpResponseMessage UpdateDailyStats(int statID, DailyStats dailyStat) { var updatedDailyStat = DailyStatsServices.UpdateDailyStat(statID, dailyStat); var response = Request.CreateResponse(HttpStatusCode.OK, updatedDailyStat, Configuration.Formatters.JsonFormatter); response.Headers.Add("API-Version", apiVersion); response.Headers.Add("Response-Type", "JSON"); response.Headers.Add("DailyStats-URL", Request.RequestUri.AbsoluteUri); if (updatedDailyStat == null) { var notFoundResponse = Request.CreateResponse(HttpStatusCode.NotFound, "(404) Daily Stats Not Found", Configuration.Formatters.JsonFormatter); notFoundResponse.Headers.Add("API-Version", apiVersion); return(notFoundResponse); } else { return(response); } }
public string GenerateEmailBody(DailyStats stats, string email) { DateTime date = DateTime.Today; string dateStr = string.Format("{0} {1}, {2}", date.Day, date.ToString("MMMM"), date.Year); string unsubscribeURL = "\"https://192.168.1.3:45458/emailUnreg/" + email + "\""; string body = string.Empty; body = @"<!doctype html> <html lang=""en""> <head> <meta charset = ""UTF-8""> <meta name = ""viewport"" content = ""width=device-width, initial-scale=1""> <link rel = ""stylesheet"" href = ""https://www.w3schools.com/w3css/4/w3.css""> <link rel = ""stylesheet"" href = ""https://fonts.googleapis.com/css?family=Raleway""> </head> <style> i { border: solid red; border-width: 0 3px 3px 0; display: inline-block; padding: 3px; transform: rotate(-135deg); -webkit-transform: rotate(-135deg); } </style> <!-- Header --> <header class=""w3-container w3-center w3-padding-32""> <h1><b> Covid- 19 Updates </b></h1> </header > <div style=""margin-left: 10vw; margin-right: 10vw""> <div class=""w3-card-4 w3-margin w3-white""> <img src = ""https://www.knowablemagazine.org/sites/default/files/styles/1600_600/public/articles/442/coronavirus-structure-1600x600_0.jpg?itok=usw1MShH"" style=""width:100%;height:40vh;""> <div class=""w3-container""> <h3><b>New Zealand</b></h3> <h5><b>Summary on</b> <span class=""w3-opacity"">" + dateStr + @"</span></h5> </div> <div class=""w3-container""> <p>Number of confirmed cases: " + stats.ConfirmedCases + @"</p> <p>Number of probable cases: " + stats.ProbableCases + @"</p> <p>Number of recovered cases: " + stats.RecoveredCases + @"</p> <p>Number of deaths: " + stats.TotalDeath + @"</p> <div class=""w3-row""> <div class=""w3-col m8 s12""> <p><button class=""w3-button w3-padding-large w3-white w3-border""><a href=""https://192.168.1.3:45458/""><b>READ MORE »</b></a></button></p--> </div> </div> </div> </div> <hr> </div> <p class=""w3-center"" style=""text-align: center;""><a href=""https://192.168.1.3:45458/emailUnreg/[email protected]"">Unsubscribe</a></p> </html>"; return(body); }
private async Task manageStatsAsync(Dictionary <STATS, int> wages, TimeSpend timeSpend) { DailyStats dailyStats = calculateStats(wages, timeSpend); dailyStats.UserId = timeSpend.UserId; dailyStats.Date = DateTime.UtcNow.Date; await _dailyStatsService.CreateOrAddAsync(dailyStats); }
private void Awake() { summary.SetActive(false); moneyManager = FindObjectOfType <MoneyManager>(); dayText = GetComponent <Text>(); timeManager = FindObjectOfType <TimeManager>(); dailyStats = summary.GetComponentInChildren <DailyStats>(); }
private static DailyStats GetDailyStatsDiff(DailyStats currentDay, DailyStats previousDay) { var day = new DailyStats { Cured = currentDay.Cured - previousDay.Cured, DatePublished = currentDay.DatePublished, DatePublishedString = currentDay.DatePublishedString, Deaths = currentDay.Deaths - previousDay.Deaths, Infected = currentDay.Infected - previousDay.Infected, Complete = currentDay.Complete }; return(day); }
private DailyStats GetStats(DateTime day) { DailyStats dailyStats = new DailyStats(); var fileName = day.ToString("dd") + "_" + day.ToString("MM") + "_" + day.ToString("yyyy"); var statsPath = Path.Combine(App.FolderPath, "user", $"{fileName}.json"); try { dailyStats = JsonConvert.DeserializeObject <DailyStats>(File.ReadAllText(@statsPath)); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return(dailyStats); }
public static Sale CreateSale(Sale sale) { using (var context = new ServicesContext()) { var currentDate = DateTime.Now.Date; // Check if there's already a sales stat for this day. var findDailyStat = context.dailyStats.FirstOrDefault (b => b.salesDate == currentDate); var findMonthlyStat = context.monthlyStats.FirstOrDefault (b => b.salesMonth == DateTime.Now.Month && b.salesYear == DateTime.Now.Year); // If there is an existing daily stat, sum one to the counter. if (findDailyStat != null) { findDailyStat.productsSold++; } // If there isn't, create a new stat for this day. else { DailyStats newStats = new DailyStats(); newStats.productsSold++; context.dailyStats.Add(newStats); } // If the monthly stat already exists, sum one to the counter of that month. if (findMonthlyStat != null) { findMonthlyStat.productsSold++; } // If there isn't an existing monthly stat, create one. else { MonthlyStats newStats = new MonthlyStats(); newStats.productsSold++; context.monthlyStats.Add(newStats); } // Sale object corrections sale.saleDescription = sale.saleDescription.Trim(); context.Sales.Add(sale); context.SaveChanges(); return(sale); } }
private void UpdateAllOnClick(object sender, RoutedEventArgs e) { DataTable dt = SqlDB.Select($"select * from Dayily_Stats where id_user={SqlDB.UserID} and [date]=(select convert(varchar(10),(select getdate()), 120))"); if (dt.Rows.Count <= 0) { MessageBox.Show("Продукты не добавлены"); return; } DataRow dr = dt.Rows[0]; DailyStats ds = new DailyStats(); ds = new DailyStats { Date = dr["date"].ToString(), Water = Convert.ToInt32(dr["water"]), Calories = Convert.ToInt32(dr["calories"]), Fats = Convert.ToInt32(dr["fats"]), Proteins = Convert.ToInt32(dr["proteins"]), Carbohydrates = Convert.ToInt32(dr["carbohydrates"]) }; foreach (var series in Chart.Series) { foreach (var observable in series.Values.Cast <ObservableValue>()) { switch (series.Title) { case "Калории": observable.Value = ds.Calories; break; case "Белки": observable.Value = ds.Proteins; break; case "Жиры": observable.Value = ds.Fats; break; case "Углеводы": observable.Value = ds.Carbohydrates; break; case "Вода": observable.Value = ds.Water; break; } } } }
internal FlightStatGroup(string name) : base(name, new ChartOptions(ChartOptions.ChartTypes.line, i18n.Get("TBFlash.AirportStats.json.flightStats"), "false", i18n.Get("TBFlash.AirportStats.json.numberFlights"))) { nSchedFlights = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats0"), new SeriesData(i18n.Get("TBFlash.AirportStats.json.scheduledDepartures"), "schedDepart", "white", "4")); nDelayedArrival = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats1"), null); nRequiresCrew = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats2"), null); nOntimeDeparture = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats3"), new SeriesData(i18n.Get("TBFlash.AirportStats.json.ontimeDepartures"), "ontimeDepart", "green", "1")); nDelayedDeparture = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats4"), new SeriesData(i18n.Get("TBFlash.AirportStats.json.delayedDepartures"), "delayDepart", "cyan", "2")); nCancelled = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats5"), new SeriesData(i18n.Get("TBFlash.AirportStats.json.canceled"), "canx", "red", "3")); nAirportInvalid = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats6"), null); nWeather = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats7"), null); nRunway = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats8"), null); nGate = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats9"), null); nExpired = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats10"), null); nReneged = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.stats11"), null); nSmallGates = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.smallFlights"), null); nLargeGates = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.largeFlights"), null); nXLGates = new DailyStats <IntStat>(i18n.Get("TBFlash.AirportStats.AirlineCompanyStats.XLFlights"), null); ontimeDeparturePer = new DailyStats <AverageStat>(i18n.Get("TBFlash.AirportStats.AirlineDailyStats.ontimeDepartPer"), null); }
// GET: Home public ActionResult Index() { string url = "https://api-metrika.yandex.com.tr/stat/traffic/summary?id=d636c1f9abc04439ab36cde51a1cfd84&oauth_token=d636c1f9abc04439ab36cde51a1cfd84&date1=20151201&date2=20151231"; XmlDocument visits = new XmlDocument(); XmlNodeList nodelist = visits.GetElementsByTagName("row"); List <DailyStats> stats = new List <DailyStats>(); foreach (XmlNode item in nodelist) { DailyStats stt = new DailyStats(); stt.Day = DateTime.ParseExact(item["date"].InnerText, "yyyyMMdd", null); stt.Visits = Convert.ToInt32(item["visits"].InnerText); stt.Visitors = Convert.ToInt32(item["visitors"].InnerText); stt.PageViews = Convert.ToInt32(item["page_views"].InnerText); stt.NewVisitors = Convert.ToInt32(item["new_visitors"].InnerText); stats.Add(stt); } return(View()); }
public void SendEmail(DailyStats stats, string email) { using (MailMessage mail = new MailMessage()) { mail.From = new MailAddress("*****@*****.**"); mail.To.Add(email); //mail.To.Add("*****@*****.**"); mail.Subject = "Covid-19 Updates"; string body = _formatter.GenerateEmailBody(stats, email); mail.Body = body; mail.IsBodyHtml = true; using (SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587)) { smtp.Credentials = new NetworkCredential("*****@*****.**", "zc83608810"); smtp.EnableSsl = true; smtp.Send(mail); } } }
public IHttpActionResult GetDailyStat(int id) { DailyStats dailyStat = DailyStatsServices.GetDailyStat(id); HttpContext.Current.Response.AppendHeader("API-Version", apiVersion); if (dailyStat == null) { HttpContext.Current.Response.AppendHeader("ERROR", "(404) Resource Not Found"); return(NotFound()); } else { HttpContext.Current.Response.AppendHeader("Response-Type", "JSON"); HttpContext.Current.Response.AppendHeader("Object-URL", Request.RequestUri.AbsoluteUri); JsonSerializerSettings serializerSettings = new JsonSerializerSettings { Formatting = Formatting.Indented }; return(Json(dailyStat, serializerSettings)); } }
private void Statistic_MouseDoubleClick(object sender, MouseButtonEventArgs e) { Statistic.SelectedItem = sender; DailyStats daily = (DailyStats)Statistic.SelectedItem; DateTime result = DateTime.ParseExact(daily.Date.Substring(0, 10), "dd.MM.yyyy", CultureInfo.InvariantCulture); string date = result.ToString("yyyy-MM-dd"); DataTable dt = SqlDB.Select($"select Dishes.[name], proteins, fats, carbohydrates, calories from Users_Dishes join Dishes on Dishes.id = id_dish where id_user={SqlDB.UserID} and [date]='{date}'"); List <Dish> dishes = new List <Dish>(); foreach (DataRow dr in dt.Rows) { dishes.Add(new Dish { Name = dr["name"].ToString(), Proteins = Convert.ToDouble(dr["proteins"]), Fats = Convert.ToDouble(dr["fats"]), Carbohydrates = Convert.ToDouble(dr["carbohydrates"]), Calories = Convert.ToDouble(dr["calories"]) }); } Table.ItemsSource = dishes; }
public static DailyStats CreateDailyStat(DailyStats dailyStat) { using (var context = new ServicesContext()) { // Check if there's already a daily stat for this day. var findDailyStat = context.dailyStats.FirstOrDefault (b => b.salesDate == dailyStat.salesDate); // If there isn't, create one. if (findDailyStat == null) { context.dailyStats.Add(dailyStat); context.SaveChanges(); return(dailyStat); } // If there is, return null and let the controller handle it. else { return(null); } } }
public static DailyStats UpdateDailyStat(int statID, DailyStats dailyStat) { using (var context = new ServicesContext()) { var selectedStat = context.dailyStats.FirstOrDefault(b => b.ID == statID); // Checking if the stat does exist within the database. if (selectedStat != null) { selectedStat.salesDate = dailyStat.salesDate; selectedStat.productsSold = dailyStat.productsSold; context.SaveChanges(); return(selectedStat); } // If it does not, return null. else { return(null); } } }
public Task AddDailyStats(DailyStats stats) { return(DailyStats.InsertOneAsync(stats)); }
private OverAllStatsCsvResult(OverAllStatsTypeCsvResult type, DailyStats dailyStats) { Type = type; Date = dailyStats.Date; Count = dailyStats.Count; }
public DailyStatsResult(DailyStats jumpStartDailyStats) { Date = jumpStartDailyStats.Date; Count = jumpStartDailyStats.Count; }
private NewJumpStartOverAllStatsCsvResult(NewJumpStartOverAllStatsTypeCsvResult type, DailyStats dailyStats) { Type = type; Date = dailyStats.Date; Count = dailyStats.Count; }
public StatsHandler() { _globalStats = ReadFromFile(_globalStatsPath); _dailyStats = new DailyStats(); _sessionTimer = new Stopwatch(); }
private NewJumpStartOverAllStatsCsvResult(NewJumpStartOverAllStatsTypeCsvResult type, DailyStats dailyStats, string tag) { Type = type; Date = dailyStats.Date; Count = dailyStats.Count; Tag = tag; }
public void Remove(DailyStats dailyStats) => _DailyStats.DeleteOne(o => o.Id == dailyStats.Id);
public DailyStats Create(DailyStats DailyStats) { _DailyStats.InsertOne(DailyStats); return(DailyStats); }
static public void DailyStatsHandler(DateTime day, bool add = false, bool delete = false, string deletedFile = "", bool edit = false) { Write("[APP.DailyStatsHandler] Daily stats handling initiated..."); Write("[APP.DailyStatsHandler] Setting file name."); var fileName = day.ToString("dd") + "_" + day.ToString("MM") + "_" + day.ToString("yyyy"); Write("[APP.DailyStatsHandler] File name set. Setting file path..."); var statsPath = Path.Combine(App.FolderPath, "user", $"{fileName}.json"); Write("[APP.DailyStatsHandler] File path set."); var statsDir = Path.Combine(App.FolderPath, "user/"); Write("[APP.DailyStatsHandler] Checking if path exists..."); DirectoryInfo di = new DirectoryInfo(@statsDir); if (!di.Exists) { Write("[APP.DailyStatsHandler] Path not found. Creating directory..."); Directory.CreateDirectory(@statsDir); Write("[APP.DailyStatsHandler] Directory created."); } Write("[APP.DailyStatsHandler] Path found. Instantiating new JsonSerializer..."); JsonSerializer serializer = new JsonSerializer { NullValueHandling = NullValueHandling.Ignore }; Write("[APP.DailyStatsHandler] Instantiating new Daily stats object..."); DailyStats dailystats = new DailyStats { Day = day, CzasTreningu = TimeSpan.Zero }; Write("[APP.DailyStatsHandler] Object instantiated. Checking if activities path exists..."); di = new DirectoryInfo(Path.Combine(App.FolderPath, "activities")); if (!di.Exists) { Write("[APP.DailyStatsHandler] Path not found. Creating directory..."); Directory.CreateDirectory(Path.Combine(App.FolderPath, "activities")); Write("[APP.DailyStatsHandler] Directory created."); } Write("[APP.DailyStatsHandler] Path found."); Write("[APP.DailyStatsHandler] Enumerating files in activities path..."); var dailyActivities = Directory.EnumerateFiles(App.FolderPath, "activities/*.json"); Write("[APP.DailyStatsHandler] Files enumerated."); Write("[APP.DailyStatsHandler] Checking for add, delete and edit conditions..."); if (!File.Exists(statsPath) && !add) { Write("[APP.DailyStatsHandler] File not found. Creating a new file..."); foreach (var file in dailyActivities) { Write("[APP.DailyStatsHandler] Deserializing activity object " + file + "..."); Activity activity = JsonConvert.DeserializeObject <Activity>(File.ReadAllText(@file)); Write("[APP.DailyStatsHandler] Object deserialized."); Write("[APP.DailyStatsHandler] Checking if activity is from today..."); if (activity.Date == day) { Write("[APP.DailyStatsHandler] Activity from today. Adding stats to daily stats..."); Write("[APP.DailyStatsHandler] Calculating duration time..."); TimeSpan activityDuration = activity.EndTime - activity.StartTime; Write("[APP.DailyStatsHandler] Duration time calculated. Adding steps count..."); dailystats.DzienneKroki += System.Convert.ToInt32(activity.Steps); Write("[APP.DailyStatsHandler] Steps added. Adding duration..."); dailystats.CzasTreningu += activityDuration; Write("[APP.DailyStatsHandler] Duration added. Adding kilometres..."); dailystats.Kilometry += System.Convert.ToDecimal(activity.Kilometres); Write("[APP.DailyStatsHandler] Kilometres added. Increasing training count..."); dailystats.IloscTreningow++; Write("[APP.DailyStatsHandler] Training count increased. All stats have been added. Checking next file..."); } else { Write("[APP.DailyStatsHandler] Activity is not from today. Skipping..."); } } ; } else if (File.ReadAllLines(statsPath) == null) { Write("[APP.DailyStatsHandler] File is empty."); } else if (add) { dailystats = JsonConvert.DeserializeObject <DailyStats>(File.ReadAllText(statsPath)); foreach (var file in dailyActivities) { Activity activity = JsonConvert.DeserializeObject <Activity>(File.ReadAllText(@file)); if (File.GetCreationTime(file) > File.GetCreationTime(statsPath) && activity.Date == day) { TimeSpan activityDuration = activity.EndTime - activity.StartTime; dailystats.DzienneKroki += System.Convert.ToInt32(activity.Steps); dailystats.CzasTreningu += activityDuration; dailystats.Kilometry += System.Convert.ToDecimal(activity.Kilometres); dailystats.IloscTreningow++; } } ; } else if (!add && !delete || edit) { DailyStats checksum = new DailyStats { Day = day, CzasTreningu = TimeSpan.Zero }; foreach (var file in dailyActivities) { Activity activity = JsonConvert.DeserializeObject <Activity>(File.ReadAllText(@file)); if (activity.Date == day) { TimeSpan activityDuration = activity.EndTime - activity.StartTime; checksum.DzienneKroki += System.Convert.ToInt32(activity.Steps); checksum.CzasTreningu += activityDuration; checksum.Kilometry += System.Convert.ToDecimal(activity.Kilometres); checksum.IloscTreningow++; } } ; dailystats = JsonConvert.DeserializeObject <DailyStats>(File.ReadAllText(statsPath)); if (checksum.DzienneKroki != dailystats.DzienneKroki || checksum.CzasTreningu != dailystats.CzasTreningu || checksum.Kilometry != dailystats.Kilometry || checksum.IloscTreningow != dailystats.IloscTreningow) { dailystats = checksum; } } if (delete) { Activity DeletedFile = new Activity(); if (File.Exists(deletedFile)) { DeletedFile = JsonConvert.DeserializeObject <Activity>(File.ReadAllText(deletedFile)); } if (DeletedFile.Date == day) { TimeSpan duration = DeletedFile.EndTime - DeletedFile.StartTime; dailystats = JsonConvert.DeserializeObject <DailyStats>(File.ReadAllText(statsPath)); dailystats.DzienneKroki -= System.Convert.ToInt32(DeletedFile.Steps); dailystats.Kilometry -= System.Convert.ToDecimal(DeletedFile.Kilometres); dailystats.CzasTreningu -= duration; dailystats.IloscTreningow--; } } using StreamWriter sw = new StreamWriter(@statsPath); using JsonWriter writer = new JsonTextWriter(sw); serializer.Serialize(writer, dailystats); }
public async Task UpdateAsync(DailyStats dailyStats) => await _DailyStats.ReplaceOneAsync(o => o.Id == dailyStats.Id, dailyStats);
public void Update(DailyStats dailyStats) => _DailyStats.ReplaceOne(o => o.Id == dailyStats.Id, dailyStats);
public async Task <IActionResult> Upload( [FromBody] DailyStats stats ) { if (!ModelState.IsValid) { Logger.LogError("Failed to parse input data: {0}", ModelState); return(BadRequest(ModelState)); } Logger.LogInformation("Receiving daily stats from device {0} for {1}", stats.InstallationId, stats.Date.ToString("d", CultureInfo.InvariantCulture)); // Safety checks if (stats.Date < MinDate) { Logger.LogError("Daily statistics for unacceptable date {0}", stats.Date); return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Unacceptable date (out of valid range)", type: "https://arianna.digit.srl/api/problems/invalid-date" ))); } if (stats.TotalMinutesTracked > MinutesADay) { Logger.LogError("Total minutes tracked ({0}) exceeds minutes in a day", stats.TotalMinutesTracked); return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Total minutes tracked exceeds minutes in a day", type: "https://arianna.digit.srl/api/problems/invalid-data" ))); } if (stats.Date >= DateTime.UtcNow.Date) { Logger.LogError("Daily statistics for non-elapsed day {0}", stats.Date.Date); return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Unacceptable date (future date)", type: "https://arianna.digit.srl/api/problems/invalid-date" ))); } GeoJsonPoint <GeoJson2DGeographicCoordinates> position; string geohash; try { geohash = stats.CentroidHash.Substring(0, 5); var decoded = Geohasher.Decode(geohash); position = new GeoJsonPoint <GeoJson2DGeographicCoordinates>(new GeoJson2DGeographicCoordinates(decoded.Item2, decoded.Item1)); Logger.LogInformation("GeoHash {0} decoded as {1:F5},{2:F5}", geohash, position.Coordinates.Latitude, position.Coordinates.Longitude); } catch (Exception ex) { return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Cannot decode geohash", type: "https://arianna.digit.srl/api/problems/invalid-data", detail: ex.Message ))); } if (stats.LocationTracking == null) { Logger.LogError("Payload does not contain location tracking section"); return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Payload does not contain location tracking section", type: "https://arianna.digit.srl/api/problems/invalid-data" ))); } if (stats.LocationTracking.MinutesAtHome < 0 || stats.LocationTracking.MinutesAtWork < 0 || stats.LocationTracking.MinutesAtSchool < 0 || stats.LocationTracking.MinutesAtOtherKnownLocations < 0 || stats.LocationTracking.MinutesElsewhere < 0) { Logger.LogError("Location tracking minutes cannot be negative"); return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Negative location tracking value", type: "https://arianna.digit.srl/api/problems/invalid-data" ))); } if (stats.LocationTracking.MinutesAtHome > MinutesADay || stats.LocationTracking.MinutesAtWork > MinutesADay || stats.LocationTracking.MinutesAtSchool > MinutesADay || stats.LocationTracking.MinutesAtOtherKnownLocations > MinutesADay || stats.LocationTracking.MinutesElsewhere > MinutesADay) { Logger.LogError("One entry in the location tracking section exceeds minutes in a day"); return(UnprocessableEntity(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "One entry in the location tracking section exceeds minutes in a day", type: "https://arianna.digit.srl/api/problems/invalid-data" ))); } // Check for duplicates var existingStats = await Mongo.GetDailyStats(stats.InstallationId, stats.Date); if (existingStats != null) { Logger.LogError("Duplicate statistics from device ID {0} for date {1}", stats.InstallationId, stats.Date.ToString("d", CultureInfo.InvariantCulture)); return(Conflict(ProblemDetailsFactory.CreateProblemDetails(HttpContext, title: "Duplicate statistics for date", type: "https://arianna.digit.srl/api/problems/duplicate" ))); } // Compute voucher amounts int stayAtHomeBonus = 0; int womCount = (int)Math.Ceiling(stats.TotalMinutesTracked / 60.0) + stayAtHomeBonus; Logger.LogInformation("Generating {0} WOM vouchers for {1} total minutes and {2} minutes at home ({3} stay at home bonus)", womCount, stats.TotalMinutesTracked, stats.LocationTracking.MinutesAtHome, stayAtHomeBonus); var voucherRequest = await Wom.Instrument.RequestVouchers(new VoucherCreatePayload.VoucherInfo[] { new VoucherCreatePayload.VoucherInfo { Aim = "P", Count = womCount, Latitude = position.Coordinates.Latitude, Longitude = position.Coordinates.Longitude, Timestamp = stats.Date.Date.AddHours(23.999) } }); // OK-dokey await Mongo.AddDailyStats(new DataModels.DailyStats { InstallationId = stats.InstallationId, Date = stats.Date.Date, TotalMinutesTracked = stats.TotalMinutesTracked, TotalWomVouchersEarned = womCount, Centroid = position, CentroidHash = geohash, LocationCount = stats.LocationCount, VehicleCount = stats.VehicleCount, EventCount = stats.EventCount, SampleCount = stats.SampleCount, DiscardedSampleCount = stats.DiscardedSampleCount, BoundingBoxDiagonal = stats.BoundingBoxDiagonal, LocationTracking = new DataModels.LocationTrackingStats { MinutesAtHome = stats.LocationTracking.MinutesAtHome, MinutesAtWork = stats.LocationTracking.MinutesAtWork, MinutesAtSchool = stats.LocationTracking.MinutesAtSchool, MinutesAtOtherKnownLocations = stats.LocationTracking.MinutesAtOtherKnownLocations, MinutesElsewhere = stats.LocationTracking.MinutesElsewhere } }); return(Ok(new UploadConfirmation { WomLink = voucherRequest.Link, WomPassword = voucherRequest.Password, WomCount = womCount })); }