/// <summary> /// Adds a given reason to both Shifts and the Database. /// </summary> /// <param name="allRequiredConfigurations">Object containign the AccessToken.</param> /// <param name="teamsId">MS Teams Id.</param> /// <param name="reason">The name of the reason.</param> private async Task AddSingleReason(SetupDetails allRequiredConfigurations, string teamsId, string reason) { (var success, TimeOffReasonResponse.TimeOffReason reasonToAdd) = await this.CreateTimeOffReasonAsync(allRequiredConfigurations, teamsId, reason).ConfigureAwait(false); if (success) { var paycodeMapping = new PayCodeToTimeOffReasonsMappingEntity { PartitionKey = teamsId, RowKey = reasonToAdd.DisplayName, TimeOffReasonId = reasonToAdd.Id, }; await this.azureTableStorageHelper.InsertOrMergeTableEntityAsync(paycodeMapping, "PayCodeToTimeOffReasonsMapping").ConfigureAwait(true); } }
/// <summary> /// Update mapping reasons in storage. /// </summary> /// <param name="accessToken">Cached AccessToken.</param> /// <param name="teamsId">MS Teams Id.</param> /// <param name="tenantId">tenant Id.</param> /// <param name="kronosEndpoint">The Kronos WFC API endpoint.</param> /// <param name="kronosSession">The Kronos WFC Jsession.</param> /// <returns>List of TimeOffReasons.</returns> private async Task <dynamic> UpdateTimeOffReasonsAsync( string accessToken, string teamsId, string tenantId, string kronosEndpoint, string kronosSession) { this.telemetryClient.TrackTrace($"{MethodBase.GetCurrentMethod().Name}"); var paycodeList = await this.payCodeActivity.FetchPayCodesAsync(new Uri(kronosEndpoint), kronosSession).ConfigureAwait(true); var lstTimeOffReasons = await this.GetTimeOffReasonAsync(accessToken, teamsId).ConfigureAwait(true); if (lstTimeOffReasons != null) { var reasonList = lstTimeOffReasons.Select(c => c.DisplayName).ToList(); var newCodes = paycodeList.Except(reasonList); foreach (var payCode in newCodes) { await this.CreateTimeOffReasonAsync(accessToken, teamsId, payCode).ConfigureAwait(true); } var timeOffReasons = await this.GetTimeOffReasonAsync(accessToken, teamsId).ConfigureAwait(true); var mappedReasons = await this.timeOffReasonProvider.FetchReasonsForTeamsAsync(teamsId, tenantId).ConfigureAwait(true); foreach (var timeOffReason in timeOffReasons) { if ((paycodeList.Contains(timeOffReason.DisplayName) && !mappedReasons.ContainsKey(timeOffReason.Id)) || (paycodeList.Contains(timeOffReason.DisplayName) && mappedReasons.ContainsKey(timeOffReason.Id) && !mappedReasons[timeOffReason.Id].Contains(timeOffReason.DisplayName, StringComparison.InvariantCulture))) { var payCodeToTimeOffReasonsMappingEntity = new PayCodeToTimeOffReasonsMappingEntity { PartitionKey = teamsId, RowKey = timeOffReason.DisplayName, TimeOffReasonId = timeOffReason.Id, }; await this.azureTableStorageHelper.InsertOrMergeTableEntityAsync(payCodeToTimeOffReasonsMappingEntity, "PayCodeToTimeOffReasonsMapping").ConfigureAwait(true); } } } return(null); }
/// <summary> /// Creates a time off request that was requested in Teams. /// </summary> /// <param name="user">The user details of the time off requestor.</param> /// <param name="timeOffEntity">The time off to be created.</param> /// <param name="timeOffReason">The time off reason.</param> /// <param name="allRequiredConfigurations">Setup details.</param> /// <param name="kronosTimeZone">The kronos timezone.</param> /// <returns>Whether the time off request was created successfully or not.</returns> internal async Task <bool> CreateTimeOffRequestInKronosAsync( UserDetailsModel user, TimeOffRequestItem timeOffEntity, PayCodeToTimeOffReasonsMappingEntity timeOffReason, SetupDetails allRequiredConfigurations, string kronosTimeZone) { // Teams provides date times in UTC so convert to the local time. var localStartDateTime = this.utility.UTCToKronosTimeZone(timeOffEntity.StartDateTime, kronosTimeZone); var localEndDateTime = this.utility.UTCToKronosTimeZone(timeOffEntity.EndDateTime, kronosTimeZone); // Construct the query date span for the Kronos request var queryStartDate = localStartDateTime.AddDays( -Convert.ToInt16(this.appSettings.CorrectedDateSpanForOutboundCalls, CultureInfo.InvariantCulture)) .ToString(this.appSettings.KronosQueryDateSpanFormat, CultureInfo.InvariantCulture); var queryEndDate = localEndDateTime.AddDays( Convert.ToInt16(this.appSettings.CorrectedDateSpanForOutboundCalls, CultureInfo.InvariantCulture)) .ToString(this.appSettings.KronosQueryDateSpanFormat, CultureInfo.InvariantCulture); var timeOffReqQueryDateSpan = $"{queryStartDate}-{queryEndDate}"; var commentTimeStamp = this.utility.UTCToKronosTimeZone(DateTime.UtcNow, kronosTimeZone).ToString(CultureInfo.InvariantCulture); var comments = XmlHelper.GenerateKronosComments(timeOffEntity.SenderMessage, this.appSettings.SenderTimeOffRequestCommentText, commentTimeStamp); // Create the Kronos Time Off Request. var timeOffResponse = await this.timeOffActivity.CreateTimeOffRequestAsync( allRequiredConfigurations.KronosSession, localStartDateTime, localEndDateTime, timeOffReqQueryDateSpan, user.KronosPersonNumber, timeOffReason.RowKey, comments, new Uri(allRequiredConfigurations.WfmEndPoint)).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(timeOffResponse?.Error?.Message)) { this.telemetryClient.TrackTrace($"Could not create the time off request : {timeOffResponse?.Error?.Message} "); return(false); } var submitTimeOffResponse = await this.timeOffActivity.SubmitTimeOffRequestAsync( allRequiredConfigurations.KronosSession, user.KronosPersonNumber, timeOffResponse?.EmployeeRequestMgm?.RequestItem?.GlobalTimeOffRequestItms?.FirstOrDefault()?.Id, timeOffReqQueryDateSpan, new Uri(allRequiredConfigurations.WfmEndPoint)).ConfigureAwait(false); TimeOffMappingEntity newTimeOffReq = new TimeOffMappingEntity(); // IsActive represents whether the time off was successfully created. if (submitTimeOffResponse?.Status == ApiConstants.Failure) { newTimeOffReq.IsActive = false; } else { newTimeOffReq.IsActive = true; } newTimeOffReq.Duration = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().TimeOffPeriodsList.TimeOffPerd.FirstOrDefault().Duration; newTimeOffReq.EndDate = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().TimeOffPeriodsList.TimeOffPerd.FirstOrDefault().EndDate; newTimeOffReq.StartDate = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().TimeOffPeriodsList.TimeOffPerd.FirstOrDefault().StartDate; newTimeOffReq.StartTime = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().TimeOffPeriodsList.TimeOffPerd.FirstOrDefault().StartTime; newTimeOffReq.PayCodeName = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().TimeOffPeriodsList.TimeOffPerd.FirstOrDefault().PayCodeName; newTimeOffReq.KronosPersonNumber = timeOffResponse.EmployeeRequestMgm.Employees.PersonIdentity.PersonNumber; newTimeOffReq.PartitionKey = $"{localStartDateTime.Month}_{localStartDateTime.Year}"; newTimeOffReq.RowKey = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().Id; newTimeOffReq.ShiftsRequestId = timeOffEntity.Id; newTimeOffReq.KronosRequestId = timeOffResponse.EmployeeRequestMgm.RequestItem.GlobalTimeOffRequestItms.FirstOrDefault().Id; newTimeOffReq.KronosStatus = ApiConstants.Submitted; newTimeOffReq.ShiftsStatus = ApiConstants.Pending; this.AddorUpdateTimeOffMappingAsync(newTimeOffReq); // If isActive is false time off request was not submitted so return false and vice versa. return(newTimeOffReq.IsActive); }