private async Task CheckSubmitState() { // Query options to filter expired work hours entries var queryOptions = new List <QueryOption>(); queryOptions.Add(new QueryOption("filter", @"startswith(fields/AutoSubmitData,'scheduled')")); // Call graph to get all registered users var usersList = await _graphSharePointService.GetSiteListItemsAsync(_usersSiteList, queryOptions); if (usersList?.Count > 0) { foreach (var item in usersList) { await updateStatus("inprogress", item.Id); var substractMonths = -3; try { while (substractMonths != 0) { var queryOptionsExpired = new List <QueryOption>(); var nextOccurrence = DateTime.Now.AddMonths(substractMonths); queryOptionsExpired.Add(new QueryOption("filter", @"startswith(fields/Date,'" + nextOccurrence.ToString("yyyyMM") + "')")); var userObjectIdentifier = item.Properties["ObjectIdentifier"].ToString(); var workHoursSiteList = await _graphSharePointService.GetSiteListAsync(userObjectIdentifier, ListSchema.WorkHoursListSchema); // Call graph to get hours not submitted but expired due to cut off setting var workHoursList = await _graphSharePointService.GetSiteListItemsAsync(workHoursSiteList, queryOptionsExpired); if (workHoursList?.Count > 0) { var workHoursToSubmit = new List <WorkHours>(); var managerOfUser = await _graphUserService.GetUserManagerAsync(userObjectIdentifier); foreach (var graphItem in workHoursList) { workHoursToSubmit.Add(new WorkHours { Id = graphItem.Id, ListId = workHoursSiteList.ListId, Fields = WorkHoursRepository.ConvertToWorkHours(graphItem, userObjectIdentifier) }); } var result = await SubmitHoursAsync(workHoursToSubmit, userObjectIdentifier, managerOfUser); } substractMonths++; } await updateStatus("updated", item.Id); } catch (Exception ex) { //go to the next user. } } } }
private async Task <string> refreshHoursTask() { var queryOptions = new List <QueryOption>(); queryOptions.Add(new QueryOption("filter", @"startswith(fields/DailyUpdateStatus,'scheduled')")); // Call graph to get all registered users var usersList = await _graphSharePointService.GetSiteListItemsAsync(_usersSiteList, queryOptions); HelperMethods helperMethods = new HelperMethods(_context); if (usersList?.Count > 0) { foreach (var item in usersList) { try { updateStatus("inprogress", item.Id); var userObjectIdentifier = item.Properties["ObjectIdentifier"].ToString(); var workHrsRepo = helperMethods.GetWorkHoursRepository(userObjectIdentifier); var workHoursList = await workHrsRepo.GetItemsAsync(DateTime.Now); updateStatus("updated", item.Id); } catch (Exception ex) { updateStatus("scheduled", item.Id); } } } return("Data Refresh Is Complete"); }
public async Task <string> refreshHoursTask() { var queryOptions = new List <QueryOption>(); queryOptions.Add(new QueryOption("filter", @"startswith(fields/DailyUpdateStatus,'scheduled')")); // Call graph to get all registered users var usersList = await _graphSharePointService.GetSiteListItemsAsync(_usersSiteList, queryOptions); var date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 00, 00, 00, 000); HelperMethods helperMethods = new HelperMethods(_context); if (usersList?.Count > 0) { foreach (var item in usersList) { try { updateStatus("inprogress", item.Id); var userObjectIdentifier = item.Properties["ObjectIdentifier"].ToString(); var workHrsRepo = helperMethods.GetWorkHoursRepository(userObjectIdentifier); var workHoursList = await workHrsRepo.GetItemsAsync(DateTime.Now); //calculate timer hours if the timer is enabled if (_timeTrackerOptions.EnableTimer == true) { var dateEntry = from x in workHoursList where x.Fields.Date.ToString() == DateTime.Now.AddDays(-1).ToString("yyyyMMdd") select x; string id = dateEntry.ToArray()[0].Id; await UpdateTimerHours(id, date.AddDays(-1), userObjectIdentifier); } updateStatus("updated", item.Id); } catch (Exception ex) { updateStatus("scheduled", item.Id); } } } return("Data Refresh Is Complete"); }
public async Task SubmitHoursAsync(IEnumerable <TeamHours> teamHoursToSubmit, string messageBody = "") { try { if (teamHoursToSubmit == null) { throw new ArgumentNullException(nameof(teamHoursToSubmit)); } var hoursToSubmit = teamHoursToSubmit.ToList(); if (hoursToSubmit?.Count == 0) { return; // Nothing to do } // Get the Team hours site list for current user, if the list does not exists, it will create one var userProfile = await _userProfileRepository.GetItemAsync(); var managerObjectIdentifier = userProfile.Id; var teamHoursSiteList = await _graphSharePointService.GetSiteListAsync(managerObjectIdentifier, ListSchema.TeamHoursListSchema); var reportHoursSiteList = await _graphSharePointService.GetSiteListAsync(_reportHoursListIdentifier, ListSchema.ReportHoursListSchema); // Try fetching the data from cache var dateKey = hoursToSubmit[0].Fields.Date.ToString(); var cacheKey = managerObjectIdentifier + dateKey; var teamHoursSubmitList = teamHoursToSubmit.ToList(); var submittedDate = DateTime.Now; var teamHoursDate = DateTime.Now; foreach (var item in teamHoursToSubmit) { // Hours Submitted, but NO HR Report. //if (item.Fields.TeamHoursItemState == ItemState.NotSubmitted || item.Fields.TeamHoursItemState == ItemState.RequiresRevision) if (item.Fields.TeamHoursItemState == ItemState.NotSubmitted && item.Fields.ItemState == ItemState.Submitted) { // Update teamHoursDate with last date value which is used in the notificationn message body // Date contains a string! yyyyMMdd teamHoursDate = DateTime.ParseExact(item.Fields.Date, "yyyyMMdd", CultureInfo.InvariantCulture); // Create JSON object to update Team Hours in SharePoint dynamic teamHoursFieldsObject = new JObject(); teamHoursFieldsObject.TeamHoursItemState = ItemState.Submitted.ToString(); teamHoursFieldsObject.TeamHoursSubmittedDate = submittedDate; dynamic teamHoursRootObject = new JObject(); teamHoursRootObject.fields = teamHoursFieldsObject; // Create JSON object to create entries in Report Hours in SharePoint dynamic reportHoursFieldsObject = new JObject(); reportHoursFieldsObject.ObjectIdentifier = item.Fields.ObjectIdentifier; reportHoursFieldsObject.ManagerObjectIdentifier = managerObjectIdentifier; reportHoursFieldsObject.Date = item.Fields.Date; reportHoursFieldsObject.TeamHoursItemState = ItemState.Submitted.ToString(); reportHoursFieldsObject.TeamHoursSubmittedDate = submittedDate; reportHoursFieldsObject.ItemState = item.Fields.ItemState.ToString(); reportHoursFieldsObject.SubmittedDate = item.Fields.SubmittedDate; dynamic reportHoursRootObject = new JObject(); reportHoursRootObject.fields = reportHoursFieldsObject; // Update the team hours entry in SharePoint await _graphSharePointService.UpdateSiteListItemAsync(teamHoursSiteList, item.Id, teamHoursRootObject.ToString()); // Create List Item in ReportHours List var createResult = await _graphSharePointService.CreateSiteListItemAsync(reportHoursSiteList, reportHoursRootObject.ToString()); // Get work hours list for this teamHours entry and update the TeamHoursItemState var workHoursSiteList = await _graphSharePointService.GetSiteListAsync(item.Fields.ObjectIdentifier, ListSchema.WorkHoursListSchema); // Works for longer yyyyMMdd date. var dateQuery = item.Fields.Date.Remove(6); var workHoursResult = await _graphSharePointService.GetSiteListItemsAsync(workHoursSiteList, dateQuery); if (workHoursResult?.Count == 0) { throw new ServiceException(new Error { Code = ErrorConstants.Codes.InvalidRequest, Message = "Can't retrieve work hours for a team hours entry" }); } foreach (var workHoursItem in workHoursResult) { // Create JSON object to update Work Hours list in SharePoint dynamic workHoursFieldsObject = new JObject(); workHoursFieldsObject.TeamHoursItemState = ItemState.Submitted.ToString(); workHoursFieldsObject.TeamHoursSubmittedDate = submittedDate; dynamic workHoursRootObject = new JObject(); workHoursRootObject.fields = workHoursFieldsObject; // Update List Item in WorkHours List // var updateResult = await _graphSharePointService.UpdateSiteListItemAsync(workHoursSiteList, workHoursItem.Id, workHoursRootObject.ToString()); await _graphSharePointService.UpdateSiteListItemAsync(workHoursSiteList, workHoursItem.Id, workHoursRootObject.ToString()); } } } // Create notification and send email var sendToObject = new GraphResultItem { Id = _hrListIdentifier, Properties = new Dictionary <string, object> { { "Mail", _timeTrackerOptions.HrNotificationMail }, } }; // Send notification //var messageBody = _workflowServiceHelper.ComposeMessageBody(NotificationType.SubmitTeamHours, teamHoursDate); await _workflowServiceHelper.SendNotificationAsync(sendToObject, NotificationType.SubmitTeamHours, messageBody); } catch (Exception ex) { throw ex; } }
public async Task SubmitHoursAsync(IEnumerable <WorkHours> workHoursToSubmit, string userObjectIdentifier, GraphResultItem managerOfUser, string messageBody = "") { try { if (workHoursToSubmit == null) { throw new ArgumentNullException(nameof(workHoursToSubmit)); } if (((List <WorkHours>)workHoursToSubmit)?.Count == 0) { return; // Nothing to do } if (String.IsNullOrEmpty(userObjectIdentifier)) { return; // Nothing to do } // Try to get the work hours from cache var workHoursListCollectionPage = new ListCollectionPage <WorkHours>(); var dateQuery = workHoursToSubmit.ToList(); // Works for longer Date yyyyMMdd var cacheKey = userObjectIdentifier + dateQuery[0].Fields.Date.Remove(6); //var workHoursCacheEntry = await _cacheService.TryRetrieveFromCacheAsync(workHoursListCollectionPage, cacheKey); //if (workHoursCacheEntry != null) //{ // workHoursListCollectionPage = workHoursCacheEntry; //} var managerObjectIdentifier = managerOfUser.Id ?? ""; var teamHoursSiteList = new SiteList(); if (String.IsNullOrEmpty(managerObjectIdentifier)) { // Skip manager by passing report hours identifier as manager identifier and handling that when building the models for the report by setting the manager display name to blank managerObjectIdentifier = ""; managerOfUser.DisplayName = ""; teamHoursSiteList = await _graphSharePointService.GetSiteListAsync("entries", ListSchema.ReportHoursListSchema); } // Get the SpSiteList, if the list does not exists, it will create one var workHoursSiteList = workHoursListCollectionPage.SiteList; if (String.IsNullOrEmpty(workHoursSiteList.ListId)) { workHoursSiteList = await _graphSharePointService.GetSiteListAsync(userObjectIdentifier, ListSchema.WorkHoursListSchema); } if (!String.IsNullOrEmpty(managerObjectIdentifier)) { teamHoursSiteList = await _graphSharePointService.GetSiteListAsync(managerObjectIdentifier, ListSchema.TeamHoursListSchema); } var teamHoursRow = new TeamHours(); var submittedDate = DateTime.Now; var hasRequestedRevision = false; var tasksList = new List <Task>(); var workHoursDate = DateTime.Now; foreach (var workHours in workHoursToSubmit) { // Only count not submitted and requieres revision if (workHours.Fields.ItemState == ItemState.NotSubmitted || workHours.Fields.ItemState == ItemState.RequiresRevision) { //Update the workHoursDate so we can assamble the message of the notification workHoursDate = DateTime.ParseExact(workHours.Fields.Date, "yyyyMMdd", CultureInfo.InvariantCulture); // To track if there is an entry that has a requiered revision if (!hasRequestedRevision && workHours.Fields.ItemState == ItemState.RequiresRevision) { hasRequestedRevision = true; } teamHoursRow.Fields.Date = workHours.Fields.Date; teamHoursRow.Fields.ObjectIdentifier = workHours.Fields.ObjectIdentifier; teamHoursRow.Fields.MeetingHours += workHours.Fields.MeetingHours; teamHoursRow.Fields.MeetingMinutes += workHours.Fields.MeetingMinutes; if (workHours.Fields.MeetingAdjustedHours != 0 || workHours.Fields.MeetingAdjustedMinutes != 0) { teamHoursRow.Fields.MeetingAdjustedHours += workHours.Fields.MeetingAdjustedHours; teamHoursRow.Fields.MeetingAdjustedMinutes += workHours.Fields.MeetingAdjustedMinutes; } else { teamHoursRow.Fields.MeetingAdjustedHours += workHours.Fields.MeetingHours; teamHoursRow.Fields.MeetingAdjustedMinutes += workHours.Fields.MeetingMinutes; } teamHoursRow.Fields.EmailHours += workHours.Fields.EmailHours; teamHoursRow.Fields.EmailMinutes += workHours.Fields.EmailMinutes; if (workHours.Fields.EmailAdjustedHours != 0 || workHours.Fields.EmailAdjustedMinutes != 0) { teamHoursRow.Fields.EmailAdjustedHours += workHours.Fields.EmailAdjustedHours; teamHoursRow.Fields.EmailAdjustedMinutes += workHours.Fields.EmailAdjustedMinutes; } else { teamHoursRow.Fields.EmailAdjustedHours += workHours.Fields.EmailHours; teamHoursRow.Fields.EmailAdjustedMinutes += workHours.Fields.EmailMinutes; } teamHoursRow.Fields.OtherHours += workHours.Fields.OtherHours; teamHoursRow.Fields.OtherMinutes += workHours.Fields.OtherMinutes; if (workHours.Fields.OtherAdjustedHours != 0 || workHours.Fields.OtherAdjustedMinutes != 0) { teamHoursRow.Fields.OtherAdjustedHours += workHours.Fields.OtherAdjustedHours; teamHoursRow.Fields.OtherAdjustedMinutes += workHours.Fields.OtherAdjustedMinutes; } else { teamHoursRow.Fields.OtherAdjustedHours += workHours.Fields.OtherHours; teamHoursRow.Fields.OtherAdjustedMinutes += workHours.Fields.OtherMinutes; } teamHoursRow.Fields.TeamHoursItemState = ItemState.NotSubmitted; teamHoursRow.Fields.ItemState = ItemState.Submitted; teamHoursRow.Fields.SubmittedDate = submittedDate; // Create JSON object to update WORK HOURS (aka employee entries) in SharePoint dynamic workHoursFieldsObject = new JObject(); if (String.IsNullOrEmpty(managerObjectIdentifier)) { // Skip submit to manager and send to HR since user does not has manager workHoursFieldsObject.TeamHoursItemState = ItemState.Submitted.ToString(); workHoursFieldsObject.TeamHoursSubmittedDate = submittedDate; } workHoursFieldsObject.ItemState = ItemState.Submitted.ToString(); workHoursFieldsObject.SubmittedDate = submittedDate; dynamic workHoursRootObject = new JObject(); workHoursRootObject.fields = workHoursFieldsObject; // Update List Item in WorkHours List await _graphSharePointService.UpdateSiteListItemAsync(workHoursSiteList, workHours.Id, workHoursRootObject.ToString()); } } // Adjust minutes to hours due the sum (above) var timeSpan = new TimeSpan(teamHoursRow.Fields.MeetingHours, teamHoursRow.Fields.MeetingMinutes, 0); teamHoursRow.Fields.MeetingHours = Convert.ToInt16(timeSpan.Hours + (timeSpan.Days * 24)); teamHoursRow.Fields.MeetingMinutes = Convert.ToInt16(timeSpan.Minutes); timeSpan = new TimeSpan(teamHoursRow.Fields.MeetingAdjustedHours, teamHoursRow.Fields.MeetingAdjustedMinutes, 0); teamHoursRow.Fields.MeetingAdjustedHours = Convert.ToInt16(timeSpan.Hours + (timeSpan.Days * 24)); teamHoursRow.Fields.MeetingAdjustedMinutes = Convert.ToInt16(timeSpan.Minutes); timeSpan = new TimeSpan(teamHoursRow.Fields.EmailHours, teamHoursRow.Fields.EmailMinutes, 0); teamHoursRow.Fields.EmailHours = Convert.ToInt16(timeSpan.Hours + (timeSpan.Days * 24)); teamHoursRow.Fields.EmailMinutes = Convert.ToInt16(timeSpan.Minutes); timeSpan = new TimeSpan(teamHoursRow.Fields.EmailAdjustedHours, teamHoursRow.Fields.EmailAdjustedMinutes, 0); teamHoursRow.Fields.EmailAdjustedHours = Convert.ToInt16(timeSpan.Hours + (timeSpan.Days * 24)); teamHoursRow.Fields.EmailAdjustedMinutes = Convert.ToInt16(timeSpan.Minutes); timeSpan = new TimeSpan(teamHoursRow.Fields.OtherHours, teamHoursRow.Fields.OtherMinutes, 0); teamHoursRow.Fields.OtherHours = Convert.ToInt16(timeSpan.Hours + (timeSpan.Days * 24)); teamHoursRow.Fields.OtherMinutes = Convert.ToInt16(timeSpan.Minutes); timeSpan = new TimeSpan(teamHoursRow.Fields.OtherAdjustedHours, teamHoursRow.Fields.OtherAdjustedMinutes, 0); teamHoursRow.Fields.OtherAdjustedHours = Convert.ToInt16(timeSpan.Hours + (timeSpan.Days * 24)); teamHoursRow.Fields.OtherAdjustedMinutes = Convert.ToInt16(timeSpan.Minutes); // Create JSON object to add a new list item in team Hours list in SharePoint dynamic teamHoursFieldsObject = new JObject(); teamHoursFieldsObject.ObjectIdentifier = teamHoursRow.Fields.ObjectIdentifier; teamHoursFieldsObject.Date = teamHoursRow.Fields.Date; teamHoursFieldsObject.MeetingHours = teamHoursRow.Fields.MeetingHours; teamHoursFieldsObject.MeetingMinutes = teamHoursRow.Fields.MeetingMinutes; teamHoursFieldsObject.MeetingAdjustedHours = teamHoursRow.Fields.MeetingAdjustedHours; teamHoursFieldsObject.MeetingAdjustedMinutes = teamHoursRow.Fields.MeetingAdjustedMinutes; teamHoursFieldsObject.EmailHours = teamHoursRow.Fields.EmailHours; teamHoursFieldsObject.EmailMinutes = teamHoursRow.Fields.EmailMinutes; teamHoursFieldsObject.EmailAdjustedHours = teamHoursRow.Fields.EmailAdjustedHours; teamHoursFieldsObject.EmailAdjustedMinutes = teamHoursRow.Fields.EmailAdjustedMinutes; teamHoursFieldsObject.OtherHours = teamHoursRow.Fields.OtherHours; teamHoursFieldsObject.OtherMinutes = teamHoursRow.Fields.OtherMinutes; teamHoursFieldsObject.OtherAdjustedHours = teamHoursRow.Fields.OtherAdjustedHours; teamHoursFieldsObject.OtherAdjustedMinutes = teamHoursRow.Fields.OtherAdjustedMinutes; teamHoursFieldsObject.AdjustedHoursReason = "" + teamHoursRow.Fields.AdjustedHoursReason; if (String.IsNullOrEmpty(managerObjectIdentifier)) { // Skip submit to manager and send to HR since user does not has manager teamHoursFieldsObject.TeamHoursItemState = ItemState.Submitted.ToString(); teamHoursFieldsObject.TeamHoursSubmittedDate = submittedDate; } else { teamHoursFieldsObject.TeamHoursItemState = teamHoursRow.Fields.TeamHoursItemState.ToString(); } teamHoursFieldsObject.ItemState = teamHoursRow.Fields.ItemState.ToString(); teamHoursFieldsObject.SubmittedDate = teamHoursRow.Fields.SubmittedDate; dynamic teamHoursRootObject = new JObject(); teamHoursRootObject.fields = teamHoursFieldsObject; // If submit is not due to a request revision, create team hours entry otherwise we only update the existing one if (hasRequestedRevision) { // Update existing team hours entry (this is the case for requesting revision) List <QueryOption> options = new List <QueryOption>(); options.Add(new QueryOption("filter", @"startswith(fields/Date,'" + teamHoursRow.Fields.Date + "') and startswith(fields/ObjectIdentifier,'" + teamHoursRow.Fields.ObjectIdentifier + "')")); var teamHoursResults = await _graphSharePointService.GetSiteListItemsAsync(teamHoursSiteList, options); var updateResults = await _graphSharePointService.UpdateSiteListItemAsync(teamHoursSiteList, teamHoursResults[0].Id, teamHoursRootObject.ToString()); } else { // Create List Item in TeamHours list var createResults = await _graphSharePointService.CreateSiteListItemAsync(teamHoursSiteList, teamHoursRootObject.ToString()); } // Create notification and send email //var messageBody = _workflowServiceHelper.ComposeMessageBody(NotificationType.SubmitWorkHours, workHoursDate); await _workflowServiceHelper.SendNotificationAsync(managerOfUser, NotificationType.SubmitWorkHours, messageBody); // Clear te cache //await _cacheService.ClearCacheAsync(cacheKey); } catch (Exception ex) { } }
public async Task <bool> UpdateAnalytics() { try { // Get the site list string objectIdentifier = Guid.NewGuid().ToString(); var analyticsSiteList = await _graphSharePointService.GetSiteListAsync(objectIdentifier, ListSchema.TotalHrsListSchema); bool processForToday = true; var analyticsRecords = await _graphSharePointService.GetSiteListItemsAsync(analyticsSiteList); processForToday = analyticsRecords.Count > 0; // get the reportHours var reportHoursSiteList = await _graphSharePointService.GetSiteListAsync(_reportHoursListIdentifier, ListSchema.ReportHoursListSchema); // if is first time process the submissions during current month up until yesteray // else check for any submits on yesterday. TimezoneHelper timezoneHelper = new TimezoneHelper(_timeTrackerOptions); var definedZone = timezoneHelper.timeZoneInfo; var today = TimeZoneInfo.ConvertTime(DateTime.Now, definedZone); var submitDate = today.Date.AddDays(-1); var startDate = processForToday ? submitDate : submitDate.AddDays(1 - submitDate.Day); var endDate = submitDate; //TODO: filtering upfront would be more performant and less demanding for resources. //var options = new List<QueryOption>(); //options.Add(new QueryOption("filter", @"startswith(fields/TeamHoursSubmittedDate,'" + submittedDate + "')")); //var reportHoursList = await _graphSharePointService.GetSiteListItemsAsync(reportHoursSiteList, options); var reportHoursList = await _graphSharePointService.GetSiteListItemsAsync(reportHoursSiteList); var filteredList = reportHoursList.Where(k => (DateTime.Parse(k.Properties["TeamHoursSubmittedDate"].ToString()).Date >= startDate) && (DateTime.Parse(k.Properties["TeamHoursSubmittedDate"].ToString()).Date <= endDate)).ToList(); foreach (var item in filteredList) { // Get work hours list for this teamHours entry and update the TeamHoursItemState var userObjectIdentifier = item.Properties["ObjectIdentifier"].ToString(); var workHoursSiteList = await _graphSharePointService.GetSiteListAsync(userObjectIdentifier, ListSchema.WorkHoursListSchema); // Works for longer yyyyMMdd date. var dateQuery = item.Properties["Date"].ToString().Remove(6); var workHoursResult = await _graphSharePointService.GetSiteListItemsAsync(workHoursSiteList, dateQuery); if (workHoursResult?.Count == 0) { throw new ServiceException(new Error { Code = "invalidRequest", Message = "Can't retrieve work hours for a team hours entry" }); } foreach (var workHoursItem in workHoursResult) { if ((workHoursItem.Properties["TeamHoursItemState"].ToString() != ItemState.Submitted.ToString()) || (item.Properties["TeamHoursSubmittedDate"].ToString() != workHoursItem.Properties["TeamHoursSubmittedDate"].ToString())) { // log error and continue; // continue; //TODO: find out why only one item is getting updated in workhours with teamhourssubmitteddate. } WorkHoursFields whf = WorkHoursRepository.ConvertToWorkHours(workHoursItem, userObjectIdentifier); Dictionary <string, short> dailyTotals = Helpers.HoursComputeHelper.ComputeDailyTotals(whf); // calculate totals and overtime int totalHours = Convert.ToInt16(dailyTotals["FinalTotalHrs"]); int totalMins = Convert.ToInt16(dailyTotals["FinalTotalMins"]); int dailyGoalHrs = _timeTrackerOptions.DayHours; int dailyGoalMin = 0; int OTHours = 0; int OTMins = 0; if ((totalHours > dailyGoalHrs) || ((totalHours == dailyGoalHrs) && (dailyGoalMin > 0) && (totalMins > dailyGoalMin))) { OTHours = totalHours - dailyGoalHrs; OTMins = totalMins - dailyGoalMin; //TODO: verify -ve values; Shouldn't encounter -ve ot mins. if (OTMins < 0) { OTMins += 60; OTHours--; } } // create analytic record. // Create JSON object to add a new list item in Daily OT Hours list in SharePoint dynamic dailyOTHoursFieldsObject = new JObject(); dailyOTHoursFieldsObject.ObjectIdentifier = userObjectIdentifier; dailyOTHoursFieldsObject.Date = workHoursItem.Properties["Date"].ToString(); dailyOTHoursFieldsObject.TotalHours = totalHours; dailyOTHoursFieldsObject.TotalMins = totalMins; dailyOTHoursFieldsObject.OTHours = OTHours; dailyOTHoursFieldsObject.OTMins = OTMins; dynamic dailyOTHoursRootObject = new JObject(); dailyOTHoursRootObject.fields = dailyOTHoursFieldsObject; var saveResults = await _graphSharePointService.CreateSiteListItemAsync(analyticsSiteList, dailyOTHoursRootObject.ToString()); } } } catch (Exception ex) { throw ex; } return(true); }