async Task ConfirmProxyUser(CNDSRegisterRequestDTO dto) { await ConfirmProxyUser(dto.SourceNetworkID, dto.SourceNetworkName); }
public async Task <HttpResponseMessage> Register(CNDSRegisterRequestDTO dto) { await ConfirmProxyUser(dto); var requestTypeDetails = await DataContext.RequestTypes.Where(rt => rt.ID == dto.RequestTypeID) .Select(rt => new { rt.ID, rt.WorkflowID, StartActivityID = rt.Workflow.RequestReviewWorkflowActivityID ?? DataContext.WorkflowActivityCompletionMaps.Where(wa => wa.WorkflowID == rt.WorkflowID && wa.SourceWorkflowActivity.Start == true).Select(wa => wa.SourceWorkflowActivityID).FirstOrDefault(), SubmittedActivityID = rt.Workflow.CompleteDistributionWorkflowActivityID, WorkflowRoleID = rt.Workflow.Roles.Where(wr => wr.IsRequestCreator == true).Select(wr => wr.ID).FirstOrDefault() } ).FirstOrDefaultAsync(); DTO.RequestDTO sourceRequest = Newtonsoft.Json.JsonConvert.DeserializeObject <DTO.RequestDTO>(dto.RequestDetails); //register the request, routes, responses, documents var request = DataContext.Requests.Add(new Data.Request { ID = dto.ParticipantID, ProjectID = dto.ProjectID, RequestTypeID = dto.RequestTypeID, WorkflowID = requestTypeDetails.WorkflowID, WorkFlowActivityID = requestTypeDetails.StartActivityID, CreatedByID = dto.SourceNetworkID, UpdatedByID = dto.SourceNetworkID, SubmittedOn = DateTime.UtcNow, SubmittedByID = dto.SourceNetworkID, Description = sourceRequest.Description, //TODO: figure out the naming format of the request Name = sourceRequest.Project + ": " + sourceRequest.Name, OrganizationID = Requests.RequestsController.CNDSOrganizationRouteProxyID, Priority = sourceRequest.Priority, Query = sourceRequest.Query, DataMarts = new List <RequestDataMart>(), AdapterPackageVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(this.GetType().Assembly.Location).FileVersion, RejectedByID = null, RejectedOn = null, Private = false }); if (sourceRequest.DueDate.HasValue) { request.DueDate = sourceRequest.DueDate.Value.DateTime; } request.Users.Add(new RequestUser { RequestID = request.ID, UserID = dto.SourceNetworkID, WorkflowRoleID = requestTypeDetails.WorkflowRoleID }); var workflowTask = DataContext.Actions.Add(PmnTask.CreateForWorkflowActivity(request.ID, request.WorkFlowActivityID.Value, request.WorkflowID.Value, DataContext)); //register the documents List <Document> documents = new List <Document>(); foreach (var doc in dto.Documents) { var document = DataContext.Documents.Add(new Document { ID = doc.DocumentID, RevisionSetID = doc.RevisionSetID, ItemID = workflowTask.ID, Name = doc.Name, FileName = doc.FileName, Kind = doc.Kind, Length = doc.Length, Description = doc.Description, MimeType = doc.MimeType, UploadedByID = dto.SourceNetworkID }); DataContext.ActionReferences.Add(new TaskReference { TaskID = workflowTask.ID, ItemID = document.ID, Type = DTO.Enums.TaskItemTypes.ActivityDataDocument }); documents.Add(document); } foreach (var datamart in dto.Routes) { var route = new RequestDataMart { ID = datamart.RouteID, DataMartID = datamart.DataMartID, DueDate = datamart.DueDate, Priority = datamart.Priority, RequestID = request.ID, RoutingType = DTO.Enums.RoutingType.ExternalCNDS, //default status is awaiting request approval, if the proxy user has permission to skip will be updated and notification sent to source request Status = DTO.Enums.RoutingStatus.AwaitingRequestApproval, Responses = new HashSet <Response>() }; var response = route.AddResponse(request.CreatedByID); response.ID = datamart.ResponseID; var responseDocuments = datamart.DocumentIDs.Select(docID => { var dd = documents.First(d => d.ID == docID); return(new RequestDocument { DocumentType = DTO.Enums.RequestDocumentType.Input, ResponseID = response.ID, RevisionSetID = dd.RevisionSetID.Value }); }); DataContext.RequestDocuments.AddRange(responseDocuments); request.DataMarts.Add(DataContext.RequestDataMarts.Add(route)); } //Parse the query and fix the document references in the fileupload and modular program terms DTO.QueryComposer.QueryComposerRequestDTO queryDTO = Newtonsoft.Json.JsonConvert.DeserializeObject <DTO.QueryComposer.QueryComposerRequestDTO>(request.Query); var fileUploadTerms = queryDTO.Where.Criteria.SelectMany(c => c.Terms.Where(t => t.Type == Lpp.QueryComposer.ModelTermsFactory.FileUploadID || t.Type == QueryComposer.ModelTermsFactory.ModularProgramID)).ToArray(); if (fileUploadTerms.Length > 0) { foreach (var term in fileUploadTerms) { var termValue = Newtonsoft.Json.JsonConvert.DeserializeObject <FileUploadValues>(term.Values["Values"].ToString()); foreach (var termDoc in termValue.Documents) { var docDTO = dto.Documents.Where(d => d.SourceRevisionSetID == termDoc.RevisionSetID).FirstOrDefault(); if (docDTO != null) { termDoc.RevisionSetID = docDTO.RevisionSetID; } } term.Values["Values"] = termValue; } request.Query = Newtonsoft.Json.JsonConvert.SerializeObject(queryDTO); } try { await DataContext.SaveChangesAsync(); } catch (Exception ex) { Logger.Error("Error saving request: " + request.ID, ex); System.Diagnostics.Debugger.Break(); return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)); } if (documents.Count > 0) { //var tasks = dto.Documents.Select(async doc => await GetDocumentContent(doc.DocumentID)); //await Task.WhenAll(tasks); foreach (var doc in documents) { await GetDocumentContent(doc.ID); } } //Submit the request if the proxy user has permission to skip request approval var permissionFilter = new ExtendedQuery { Projects = (a) => a.ProjectID == request.ProjectID, ProjectOrganizations = (a) => a.ProjectID == request.ProjectID && a.OrganizationID == request.OrganizationID, Organizations = (a) => a.OrganizationID == request.OrganizationID, Users = (a) => a.UserID == request.CreatedByID }; var apiIdentity = new Utilities.Security.ApiIdentity(dto.SourceNetworkID, dto.SourceNetworkName.Replace(" ", "_"), dto.SourceNetworkName, Requests.RequestsController.CNDSOrganizationRouteProxyID); var permissions = await DataContext.HasGrantedPermissions <Request>(apiIdentity, request.ID, permissionFilter, Dns.DTO.Security.PermissionIdentifiers.Request.SkipSubmissionApproval); if (permissions.Contains(DTO.Security.PermissionIdentifiers.Request.SkipSubmissionApproval)) { await DataContext.Entry(request).ReloadAsync(); await DataContext.Entry(request).Collection(r => r.DataMarts).LoadAsync(); var responses = (await DataContext.RequestDataMarts.Where(rdm => rdm.RequestID == request.ID && rdm.Status == DTO.Enums.RoutingStatus.AwaitingRequestApproval).SelectMany(rdm => rdm.Responses.Where(rsp => rsp.Count == rdm.Responses.Max(rr => rr.Count))).ToArrayAsync()).ToDictionary(r => r.RequestDataMartID); //update the routings to Submitted foreach (var dm in request.DataMarts) { await DataContext.Entry(dm).ReloadAsync(); Response response = null; if (responses.TryGetValue(dm.ID, out response)) { response.SubmittedByID = dto.SourceNetworkID; response.SubmittedOn = DateTime.UtcNow; } dm.Status = DTO.Enums.RoutingStatus.Submitted; } try { await DataContext.SaveChangesAsync(); } catch (Exception ex) { Logger.Error(ex.Message, ex); return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)); } //update the request to submitted //manually override the request status using sql direct, EF does not allow update of computed await DataContext.Database.ExecuteSqlCommandAsync("UPDATE Requests SET Status = @status WHERE ID = @ID", new System.Data.SqlClient.SqlParameter("@status", (int)DTO.Enums.RequestStatuses.Submitted), new System.Data.SqlClient.SqlParameter("@ID", request.ID)); await DataContext.Entry(request).ReloadAsync(); //close the review task workflowTask.Status = DTO.Enums.TaskStatuses.Complete; workflowTask.EndOn = DateTime.UtcNow; workflowTask.PercentComplete = 100d; //create a new task for the next activity, and set the activity on the request request.WorkFlowActivityID = requestTypeDetails.SubmittedActivityID; var submitTask = DataContext.Actions.Add(PmnTask.CreateForWorkflowActivity(request.ID, request.WorkFlowActivityID.Value, request.WorkflowID.Value, DataContext)); try { await DataContext.SaveChangesAsync(); } catch (Exception ex) { Logger.Error(ex.Message, ex); return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)); } //notify CNDS of request status change, which will in turn notify the source network to update the status of the route System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => { using (var helper = new Lpp.CNDS.ApiClient.NetworkRequestDispatcher()) { foreach (var responseID in dto.Routes.Select(rt => rt.ResponseID)) { await helper.UpdateSourceRoutingStatus(new[] { new DTO.CNDSUpdateRoutingStatusDTO { ResponseID = responseID, Message = string.Empty, RoutingStatus = DTO.Enums.RoutingStatus.Submitted } }); } } }); } return(Request.CreateResponse(HttpStatusCode.OK));; }