/// <summary>
        /// Method to create the DraftOpenShift.
        /// </summary>
        /// <param name="obj">The OpenShift object.</param>
        /// <returns>The XML string.</returns>
        private string CreateOpenShiftDraftRequest(OpenShiftObj obj)
        {
            OpenShiftSubmitReq.Request rq = new OpenShiftSubmitReq.Request()
            {
                Action = ApiConstants.AddRequests,
                EmployeeRequestMgmt = new OpenShiftSubmitReq.EmployeeRequestMgmt
                {
                    Employee = new Models.RequestEntities.ShiftsToKronos.AddRequest.Employee
                    {
                        PersonIdentity = new Models.RequestEntities.ShiftsToKronos.AddRequest.PersonIdentity
                        {
                            PersonNumber = obj.PersonNumber,
                        },
                    },
                    QueryDateSpan = obj.QueryDateSpan,
                    RequestItems  = new OpenShiftSubmitReq.RequestItems
                    {
                        GlobalOpenShiftRequestItem = new GlobalOpenShiftRequestItem
                        {
                            Employee = new Models.RequestEntities.ShiftsToKronos.AddRequest.Employee
                            {
                                PersonIdentity = new Models.RequestEntities.ShiftsToKronos.AddRequest.PersonIdentity
                                {
                                    PersonNumber = obj.PersonNumber,
                                },
                            },
                            RequestFor    = ApiConstants.OpenShiftRequest,
                            ShiftDate     = obj.ShiftDate,
                            ShiftSegments = new ShiftSegments()
                            {
                                ShiftSegment = obj.OpenShiftSegments,
                            },
                        },
                    },
                },
            };

            return(rq.XmlSerialize());
        }
        /// <summary>
        /// Method that will have the create the DraftOpenShift.
        /// </summary>
        /// <param name="tenantId">The TenantId.</param>
        /// <param name="jSession">The jSession.</param>
        /// <param name="obj">The Open Shift object.</param>
        /// <param name="endPointUrl">The Kronos API endpoint.</param>
        /// <returns>A unit of execution that contains a response.</returns>
        public async Task <Models.ResponseEntities.OpenShiftRequest.Response> PostDraftOpenShiftRequestAsync(
            string tenantId,
            string jSession,
            OpenShiftObj obj,
            Uri endPointUrl)
        {
            if (obj is null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            string xmlRequest    = this.CreateOpenShiftDraftRequest(obj);
            var    tupleResponse = await this.apiHelper.SendSoapPostRequestAsync(
                endPointUrl,
                ApiConstants.SoapEnvOpen,
                xmlRequest,
                ApiConstants.SoapEnvClose,
                jSession).ConfigureAwait(false);

            Models.ResponseEntities.OpenShiftRequest.Response response =
                this.ProcessCreateDraftOpenShiftResponse(tupleResponse.Item1);

            return(response);
        }
        public async Task <ShiftsIntegResponse> SubmitOpenShiftRequestToKronosAsync(
            Models.IntegrationAPI.OpenShiftRequestIS request, string teamsId)
        {
            ShiftsIntegResponse openShiftSubmitResponse;

            this.telemetryClient.TrackTrace($"{Resource.SubmitOpenShiftRequestToKronosAsync} starts at: {DateTime.Now.ToString("O", CultureInfo.InvariantCulture)}");

            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            GraphOpenShift graphOpenShift;
            var            telemetryProps = new Dictionary <string, string>()
            {
                { "CallingAssembly", Assembly.GetCallingAssembly().GetName().Name },
                { "CallingMethod", "UpdateTeam" },
                { "OpenShiftId", request.OpenShiftId },
                { "OpenShiftRequestId", request.Id },
                { "RequesterId", request.SenderUserId },
            };

            // Prereq. Steps
            // Step 1 - Obtain the necessary prerequisites required.
            // Step 1a - Obtain the ConfigurationInfo entity.
            // Step 1b - Obtain the Team-Department Mapping.
            // Step 1c - Obtain the Graph Token and other prerequisite information.
            // Step 1d - Obtain the user from the user to user mapping table.
            // Step 1e - Login to Kronos.

            // Step 1c.
            var allRequiredConfigurations = await this.utility.GetAllConfigurationsAsync().ConfigureAwait(false);

            var kronosTimeZoneId   = this.appSettings.KronosTimeZone;
            var kronosTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(kronosTimeZoneId);

            if (allRequiredConfigurations != null && (bool)allRequiredConfigurations?.IsAllSetUpExists)
            {
                // Step 1d.
                var userMappingRecord = await this.GetMappedUserDetailsAsync(
                    allRequiredConfigurations.WFIId,
                    request?.SenderUserId,
                    teamsId).ConfigureAwait(false);

                // Submit open shift request to Kronos if user and it's corresponding team is mapped correctly.
                if (string.IsNullOrEmpty(userMappingRecord.Error))
                {
                    var queryingOrgJobPath    = userMappingRecord.OrgJobPath;
                    var teamDepartmentMapping = await this.teamDepartmentMappingProvider.GetTeamMappingForOrgJobPathAsync(
                        allRequiredConfigurations.WFIId,
                        queryingOrgJobPath).ConfigureAwait(false);

                    telemetryProps.Add("TenantId", allRequiredConfigurations.TenantId);
                    telemetryProps.Add("WorkforceIntegrationId", allRequiredConfigurations.WFIId);

                    // Step 2 - Getting the Open Shift - the start date/time and end date/time are needed.
                    var httpClient = this.httpClientFactory.CreateClient("ShiftsAPI");
                    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", allRequiredConfigurations.ShiftsAccessToken);
                    using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "teams/" + teamDepartmentMapping.TeamId + "/schedule/openShifts/" + request.OpenShiftId))
                    {
                        var response = await httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);

                        if (response.IsSuccessStatusCode)
                        {
                            var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                            graphOpenShift = JsonConvert.DeserializeObject <GraphOpenShift>(responseContent);

                            // Logging the required Open Shift ID from the Graph call.
                            this.telemetryClient.TrackTrace($"OpenShiftRequestController - OpenShift Graph API call succeeded with getting the Open Shift: {graphOpenShift?.Id}");

                            var shiftStartDate = graphOpenShift.SharedOpenShift.StartDateTime.AddDays(
                                -Convert.ToInt16(this.appSettings.CorrectedDateSpanForOutboundCalls, CultureInfo.InvariantCulture))
                                                 .ToString(this.appSettings.KronosQueryDateSpanFormat, CultureInfo.InvariantCulture);

                            var shiftEndDate = graphOpenShift.SharedOpenShift.EndDateTime.AddDays(
                                Convert.ToInt16(this.appSettings.CorrectedDateSpanForOutboundCalls, CultureInfo.InvariantCulture))
                                               .ToString(this.appSettings.KronosQueryDateSpanFormat, CultureInfo.InvariantCulture);

                            var openShiftReqQueryDateSpan = $"{shiftStartDate}-{shiftEndDate}";

                            // Builds out the Open Shift Segments prior to actual object being built.
                            // Take into account the activities of the open shift that has been retrieved
                            // from the Graph API call for open shift details.
                            var openShiftSegments = this.BuildKronosOpenShiftSegments(
                                graphOpenShift.SharedOpenShift.Activities,
                                queryingOrgJobPath,
                                kronosTimeZoneInfo,
                                graphOpenShift.Id);

                            // Step 3 - Create the necessary OpenShiftObj
                            // Having the open shift segments which have been retrieved.
                            var inputDraftOpenShiftRequest = new OpenShiftObj()
                            {
                                StartDayNumber    = Constants.StartDayNumberString,
                                EndDayNumber      = Constants.EndDayNumberString,
                                SegmentTypeName   = Resource.DraftOpenShiftRequestSegmentTypeName,
                                StartTime         = TimeZoneInfo.ConvertTime(graphOpenShift.SharedOpenShift.StartDateTime, kronosTimeZoneInfo).ToString("h:mm tt", CultureInfo.InvariantCulture),
                                EndTime           = TimeZoneInfo.ConvertTime(graphOpenShift.SharedOpenShift.EndDateTime, kronosTimeZoneInfo).ToString("h:mm tt", CultureInfo.InvariantCulture),
                                ShiftDate         = TimeZoneInfo.ConvertTime(graphOpenShift.SharedOpenShift.StartDateTime, kronosTimeZoneInfo).ToString(Constants.DateFormat, CultureInfo.InvariantCulture).Replace('-', '/'),
                                OrgJobPath        = Utility.OrgJobPathKronosConversion(userMappingRecord?.OrgJobPath),
                                QueryDateSpan     = openShiftReqQueryDateSpan,
                                PersonNumber      = userMappingRecord?.KronosPersonNumber,
                                OpenShiftSegments = openShiftSegments,
                            };

                            // Step 4 - Submit over to Kronos WFC, Open Shift Request goes into DRAFT state.
                            var postDraftOpenShiftRequestResult = await this.openShiftActivity.PostDraftOpenShiftRequestAsync(
                                allRequiredConfigurations.TenantId,
                                allRequiredConfigurations.KronosSession,
                                inputDraftOpenShiftRequest,
                                new Uri(allRequiredConfigurations.WfmEndPoint)).ConfigureAwait(false);

                            if (postDraftOpenShiftRequestResult?.Status == ApiConstants.Success)
                            {
                                this.telemetryClient.TrackTrace($"{Resource.SubmitOpenShiftRequestToKronosAsync} - Operation to submit the DRAFT request has succeeded with: {postDraftOpenShiftRequestResult?.Status}");

                                // Step 5 - Update the submitted Open Shift Request from DRAFT to SUBMITTED
                                // so that it renders inside of the Kronos WFC Request Manager for final approval/decline.
                                var postUpdateOpenShiftRequestStatusResult = await this.openShiftActivity.PostOpenShiftRequestStatusUpdateAsync(
                                    userMappingRecord.KronosPersonNumber,
                                    postDraftOpenShiftRequestResult.EmployeeRequestMgmt?.RequestItems?.EmployeeGlobalOpenShiftRequestItem?.Id,
                                    openShiftReqQueryDateSpan,
                                    Resource.KronosOpenShiftStatusUpdateToSubmittedMessage,
                                    new Uri(allRequiredConfigurations.WfmEndPoint),
                                    allRequiredConfigurations.KronosSession).ConfigureAwait(false);

                                if (postUpdateOpenShiftRequestStatusResult?.Status == ApiConstants.Success)
                                {
                                    this.telemetryClient.TrackTrace($"{Resource.SubmitOpenShiftRequestToKronosAsync} - Operation to update the DRAFT request to SUBMITTED has succeeded with: {postUpdateOpenShiftRequestStatusResult?.Status}");

                                    var openShiftEntityWithKronosUniqueId = await this.openShiftMappingEntityProvider.GetOpenShiftMappingEntitiesAsync(
                                        request.OpenShiftId).ConfigureAwait(false);

                                    // Step 6 - Insert the submitted open shift request into Azure table storage.
                                    // Ensuring to pass the monthwise partition key from the Open Shift as the partition key for the Open Shift
                                    // Request mapping entity.
                                    var openShiftRequestMappingEntity = CreateOpenShiftRequestMapping(
                                        request?.OpenShiftId,
                                        request?.Id,
                                        request?.SenderUserId,
                                        userMappingRecord?.KronosPersonNumber,
                                        postDraftOpenShiftRequestResult.EmployeeRequestMgmt?.RequestItems?.EmployeeGlobalOpenShiftRequestItem?.Id,
                                        ApiConstants.Submitted,
                                        openShiftEntityWithKronosUniqueId.FirstOrDefault().RowKey,
                                        openShiftEntityWithKronosUniqueId.FirstOrDefault().PartitionKey,
                                        ApiConstants.Pending);

                                    telemetryProps.Add(
                                        "KronosRequestId",
                                        postDraftOpenShiftRequestResult.EmployeeRequestMgmt?.RequestItems?.EmployeeGlobalOpenShiftRequestItem?.Id);
                                    telemetryProps.Add(
                                        "KronosRequestStatus",
                                        postUpdateOpenShiftRequestStatusResult.EmployeeRequestMgmt?.RequestItems?.EmployeeGlobalOpenShiftRequestItem?.StatusName);
                                    telemetryProps.Add("KronosOrgJobPath", Utility.OrgJobPathKronosConversion(userMappingRecord?.OrgJobPath));

                                    await this.openShiftRequestMappingEntityProvider.SaveOrUpdateOpenShiftRequestMappingEntityAsync(openShiftRequestMappingEntity).ConfigureAwait(false);

                                    this.telemetryClient.TrackTrace(Resource.SubmitOpenShiftRequestToKronosAsync, telemetryProps);

                                    openShiftSubmitResponse = new ShiftsIntegResponse()
                                    {
                                        Id     = request.Id,
                                        Status = StatusCodes.Status200OK,
                                        Body   = new Body
                                        {
                                            Error = null,
                                            ETag  = GenerateNewGuid(),
                                        },
                                    };
                                }
                                else
                                {
                                    this.telemetryClient.TrackTrace(Resource.SubmitOpenShiftRequestToKronosAsync, telemetryProps);
                                    openShiftSubmitResponse = new ShiftsIntegResponse()
                                    {
                                        Id     = request.Id,
                                        Status = StatusCodes.Status500InternalServerError,
                                        Body   = new Body
                                        {
                                            Error = new ResponseError
                                            {
                                                Code    = Resource.KronosWFCOpenShiftRequestErrorCode,
                                                Message = postUpdateOpenShiftRequestStatusResult?.Status,
                                            },
                                        },
                                    };
                                }
                            }
                            else
                            {
                                this.telemetryClient.TrackTrace($"{Resource.SubmitOpenShiftRequestToKronosAsync} - There was an error from Kronos WFC when updating the DRAFT request to SUBMITTED status: {postDraftOpenShiftRequestResult?.Status}");

                                openShiftSubmitResponse = new ShiftsIntegResponse()
                                {
                                    Id     = request.Id,
                                    Status = StatusCodes.Status500InternalServerError,
                                    Body   = new Body
                                    {
                                        Error = new ResponseError
                                        {
                                            Code    = Resource.KronosWFCOpenShiftRequestErrorCode,
                                            Message = postDraftOpenShiftRequestResult?.Status,
                                        },
                                    },
                                };
                            }
                        }
                        else
                        {
                            this.telemetryClient.TrackTrace($"{Resource.SubmitOpenShiftRequestToKronosAsync} - There is an error when getting Open Shift: {request?.OpenShiftId} from Graph APIs: {response.StatusCode.ToString()}");

                            openShiftSubmitResponse = new ShiftsIntegResponse
                            {
                                Id     = request.Id,
                                Status = StatusCodes.Status404NotFound,
                                Body   = new Body
                                {
                                    Error = new ResponseError()
                                    {
                                        Code    = Resource.OpenShiftNotFoundCode,
                                        Message = string.Format(CultureInfo.InvariantCulture, Resource.OpenShiftNotFoundMessage, request.OpenShiftId),
                                    },
                                },
                            };
                        }
                    }
                }

                // Either user or it's team is not mapped correctly.
                else
                {
                    openShiftSubmitResponse = new ShiftsIntegResponse
                    {
                        Id     = request.Id,
                        Status = StatusCodes.Status500InternalServerError,
                        Body   = new Body
                        {
                            Error = new ResponseError
                            {
                                Code    = userMappingRecord.Error,
                                Message = userMappingRecord.Error,
                            },
                        },
                    };
                }
            }
            else
            {
                this.telemetryClient.TrackTrace(Resource.SubmitOpenShiftRequestToKronosAsync + "-" + Resource.SetUpNotDoneMessage);

                openShiftSubmitResponse = new ShiftsIntegResponse
                {
                    Id     = request.Id,
                    Status = StatusCodes.Status500InternalServerError,
                    Body   = new Body
                    {
                        Error = new ResponseError
                        {
                            Code    = Resource.SetUpNotDoneCode,
                            Message = Resource.SetUpNotDoneMessage,
                        },
                    },
                };
            }

            this.telemetryClient.TrackTrace($"{Resource.SubmitOpenShiftRequestToKronosAsync} ends at: {DateTime.Now.ToString("O", CultureInfo.InvariantCulture)}");
            return(openShiftSubmitResponse);
        }