public SeriesValueList[] GetElementValues(long patientId, string elementName, int records) { var patientFromRepo = _patientRepository.Get(p => p.Id == patientId); if (patientFromRepo == null) { throw new ArgumentException(nameof(patientId)); } if (string.IsNullOrWhiteSpace(elementName)) { throw new ArgumentException(nameof(elementName)); } var encounters = _encounterRepository.List(e => e.Patient.Id == patientId) .OrderBy(e => e.EncounterDate); var seriesValueArray = new List <SeriesValueList>(); var seriesValueList = new SeriesValueList() { Name = elementName }; var values = new List <SeriesValueListItem>(); foreach (Encounter encounter in encounters) { var datasetInstance = _datasetInstanceRepository.Get(di => di.ContextId == encounter.Id && di.Dataset.ContextType.Id == (int)ContextTypes.Encounter); if (datasetInstance != null) { var value = datasetInstance.GetInstanceValue(elementName); var decimalValue = 0M; Decimal.TryParse(value, out decimalValue); if (!String.IsNullOrWhiteSpace(value)) { var modelItem = new SeriesValueListItem() { Value = decimalValue, //Min = intValue - ((intValue * 20) / 100), //Max = intValue + ((intValue * 20) / 100), Name = encounter.EncounterDate.ToString("yyyy-MM-dd") }; values.Add(modelItem); if (values.Count >= records) { break; } } } } seriesValueList.Series = values; seriesValueArray.Add(seriesValueList); return(seriesValueArray.ToArray()); }
public async Task <ActionResult> DownloadDataset(Guid id, [FromQuery] AnalyserDatasetResourceParameters analyserDatasetResourceParameters) { var workflowFromRepo = await _workFlowRepository.GetAsync(f => f.WorkFlowGuid == id); if (workflowFromRepo == null) { return(NotFound()); } var userName = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; var userFromRepo = _userRepository.Get(u => u.UserName == userName); if (!userFromRepo.AllowDatasetDownload) { ModelState.AddModelError("Message", "You do not have permissions to download a dataset"); return(BadRequest(ModelState)); } var model = id == new Guid("4096D0A3-45F7-4702-BDA1-76AEDE41B986") ? _excelDocumentService.CreateSpontaneousDatasetForDownload() : _excelDocumentService.CreateActiveDatasetForDownload(new long[] { }, analyserDatasetResourceParameters?.CohortGroupId ?? 0); return(PhysicalFile(model.FullPath, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")); }
/// <summary> /// Prepare the model for the condition /// </summary> private ConditionDetail PrepareConditionDetail(PatientConditionForUpdateDto conditionForUpdate) { var conditionDetail = new ConditionDetail(); conditionDetail.CustomAttributes = _modelExtensionBuilder.BuildModelExtension <PatientCondition>(); //conditionDetail = _mapper.Map<ConditionDetail>(conditionForUpdate); foreach (var newAttribute in conditionForUpdate.Attributes) { var customAttribute = _customAttributeRepository.Get(ca => ca.Id == newAttribute.Key); if (customAttribute != null) { // Validate attribute exists for household entity and is a PMT attribute var attributeDetail = conditionDetail.CustomAttributes.SingleOrDefault(ca => ca.AttributeKey == customAttribute.AttributeKey); if (attributeDetail == null) { ModelState.AddModelError("Message", $"Unable to locate custom attribute on patient condition {newAttribute.Key}"); } else { attributeDetail.Value = newAttribute.Value; } } else { ModelState.AddModelError("Message", $"Unable to locate custom attribute {newAttribute.Key}"); } } // Update patient custom attributes from source return(conditionDetail); }
public async Task <bool> Handle(ChangeReportTerminologyCommand message, CancellationToken cancellationToken) { var reportInstanceFromRepo = await _reportInstanceRepository.GetAsync(ri => ri.WorkFlow.WorkFlowGuid == message.WorkFlowGuid && ri.Id == message.ReportInstanceId, new string[] { "" }); if (reportInstanceFromRepo == null) { throw new KeyNotFoundException("Unable to locate report instance"); } var terminologyFromRepo = _terminologyMeddraRepository.Get(message.TerminologyMedDraId); if (terminologyFromRepo == null) { throw new KeyNotFoundException("Unable to locate terminology"); } if (await _workFlowService.ValidateExecutionStatusForCurrentActivityAsync(reportInstanceFromRepo.ContextGuid, "MEDDRASET") == false) { throw new DomainException($"Activity MEDDRASET not valid for workflow"); } reportInstanceFromRepo.ChangeTerminology(terminologyFromRepo); _reportInstanceRepository.Update(reportInstanceFromRepo); await _unitOfWork.CompleteAsync(); _logger.LogInformation($"----- Report {reportInstanceFromRepo.Id} terminology updated"); await _workFlowService.ExecuteActivityAsync(reportInstanceFromRepo.ContextGuid, "MEDDRASET", $"AUTOMATION: MedDRA Term set to {terminologyFromRepo.DisplayName}", null, ""); return(true); }
public async Task <CustomAttributeIdentifierDto> Handle(AddCustomAttributeCommand message, CancellationToken cancellationToken) { var detail = new CustomAttributeConfigDetail() { AttributeDetail = message.AttributeDetail, AttributeName = message.AttributeKey, Category = message.Category, EntityName = message.ExtendableTypeName, CustomAttributeType = message.CustomAttributeType, Required = message.IsRequired, Searchable = message.IsSearchable, NumericMaxValue = message.MaxValue, NumericMinValue = message.MinValue, FutureDateOnly = message.FutureDateOnly.HasValue ? message.FutureDateOnly.Value : false, PastDateOnly = message.PastDateOnly.HasValue ? message.PastDateOnly.Value : false, StringMaxLength = message.MaxLength }; await _customAttributeService.AddCustomAttributeAsync(detail); _logger.LogInformation($"----- Custom Attribute {message.AttributeKey} created"); var newCustomAttribute = _customAttributeRepository.Get(ca => ca.ExtendableTypeName == message.ExtendableTypeName && ca.AttributeKey == message.AttributeKey); if (newCustomAttribute == null) { throw new KeyNotFoundException("Unable to locate new custom attribute"); } var mappedCustomAttribute = _mapper.Map <CustomAttributeIdentifierDto>(newCustomAttribute); CreateLinks(mappedCustomAttribute); return(mappedCustomAttribute); }
/// <summary> /// Handle the updating of medications for an existing condition /// </summary> /// <param name="conditionForUpdate">The payload containing the list of lab tests</param> /// <param name="conditionFromRepo">The condition entity that is being updated</param> /// <returns></returns> private void AddOrUpdateConditionMedications(ConditionForUpdateDto conditionForUpdate, Condition conditionFromRepo) { // Determine what has been removed ArrayList deleteCollection = new ArrayList(); foreach (var conditionMedication in conditionFromRepo.ConditionMedications) { if (!conditionForUpdate.ConditionMedications.Contains(conditionMedication.Product.Id)) { deleteCollection.Add(conditionMedication); } } // Process deletes foreach (var conditionMedication in deleteCollection) { _conditionMedicationRepository.Delete(conditionMedication); } // Determine what needs to be added foreach (var productId in conditionForUpdate.ConditionMedications) { if (!conditionFromRepo.ConditionMedications.Any(c => c.Product.Id == productId)) { var product = _productRepository.Get(f => f.Id == productId); var newConditionMedication = new ConditionMedication() { Condition = conditionFromRepo, Product = product, Concept = product.Concept }; _conditionMedicationRepository.Save(newConditionMedication); } } }
public async Task <ActionResult <AnalyserTermDetailDto> > GetAnalyserTermByDetail(Guid workFlowGuid, int id, [FromQuery] AnalyserTermSetResourceParameters analyserTermSetResourceParameters) { var workFlowFromRepo = _workFlowRepository.Get(r => r.WorkFlowGuid == workFlowGuid); if (workFlowFromRepo == null) { return(BadRequest()); } var mappedMeddraTerm = await GetMeddraTermAsync <AnalyserTermDetailDto>(id); if (mappedMeddraTerm == null) { return(NotFound()); } return(Ok(CreateLinksForMeddraTerm <AnalyserTermDetailDto>(CustomResultMap(mappedMeddraTerm, analyserTermSetResourceParameters)))); }
/// <summary> /// Add a new patient to the repository /// </summary> /// <param name="patientDetail">The details of the patient to add</param> public async Task <int> AddPatientAsync(PatientDetailForCreation patientDetail) { var facility = _facilityRepository.Get(f => f.FacilityName == patientDetail.CurrentFacilityName); if (facility == null) { throw new ArgumentException(nameof(patientDetail.CurrentFacilityName)); } var patientStatus = _patientStatusRepository.Get(f => f.Description == "Active"); var newPatient = new Patient { FirstName = patientDetail.FirstName, MiddleName = patientDetail.MiddleName, Surname = patientDetail.Surname, DateOfBirth = patientDetail.DateOfBirth, }; newPatient.ChangePatientFacility(facility); newPatient.SetPatientStatus(patientStatus); // Custom Property handling _typeExtensionHandler.UpdateExtendable(newPatient, patientDetail.CustomAttributes, "Admin"); // Clinical data AddConditions(newPatient, patientDetail.Conditions); await AddLabTestsAsync(newPatient, patientDetail.LabTests); await AddMedicationsAsync(newPatient, patientDetail.Medications); AddClinicalEvents(newPatient, patientDetail.ClinicalEvents); // Other data AddAttachments(newPatient, patientDetail.Attachments); if (patientDetail.CohortGroupId > 0) { AddCohortEnrollment(newPatient, patientDetail); } await _patientRepository.SaveAsync(newPatient); // Register encounter if (patientDetail.EncounterTypeId > 0) { await AddEncounterAsync(newPatient, new EncounterDetail() { EncounterDate = patientDetail.EncounterDate, EncounterTypeId = patientDetail.EncounterTypeId, PatientId = newPatient.Id, PriorityId = patientDetail.PriorityId }); } return(newPatient.Id); }
private string GetSelectionValue(CustomAttributeType attributeType, string attributeKey, string selectionKey) { if (attributeType == CustomAttributeType.Selection) { var selectionitem = _selectionDataItemRepository.Get(s => s.AttributeKey == attributeKey && s.SelectionKey == selectionKey); return(selectionitem == null ? string.Empty : selectionitem.Value); } return(""); }
/// <summary> /// Enrol patient into cohort /// </summary> private void AddCohortEnrollment(Patient patient, PatientDetailForCreation patientDetail) { var cohortGroup = _cohortGroupRepository.Get(cg => cg.Id == patientDetail.CohortGroupId); var enrolment = new CohortGroupEnrolment { Patient = patient, EnroledDate = Convert.ToDateTime(patientDetail.EnroledDate), CohortGroup = cohortGroup }; patient.CohortEnrolments.Add(enrolment); }
public async Task <IActionResult> ArchivePatientEnrolment(long patientId, long cohortGroupEnrolmentId, [FromBody] ArchiveDto enrolmentForDelete) { if (enrolmentForDelete == null) { ModelState.AddModelError("Message", "Archive payload not populated"); return(BadRequest(ModelState)); } var patientFromRepo = await _patientRepository.GetAsync(f => f.Id == patientId); if (patientFromRepo == null) { return(NotFound()); } var enrolmentFromRepo = await _cohortGroupEnrolmentRepository.GetAsync(f => f.Id == cohortGroupEnrolmentId); if (enrolmentFromRepo == null) { return(NotFound()); } if (Regex.Matches(enrolmentForDelete.Reason, @"[-a-zA-Z0-9 .']").Count < enrolmentForDelete.Reason.Length) { ModelState.AddModelError("Message", "Reason contains invalid characters (Enter A-Z, a-z, space, period, apostrophe)"); } var userName = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; var user = _userRepository.Get(u => u.UserName == userName); if (user == null) { ModelState.AddModelError("Message", "Unable to locate user"); } if (ModelState.IsValid) { enrolmentFromRepo.Archived = true; enrolmentFromRepo.ArchivedDate = DateTime.Now; enrolmentFromRepo.ArchivedReason = enrolmentForDelete.Reason; enrolmentFromRepo.AuditUser = user; _cohortGroupEnrolmentRepository.Update(enrolmentFromRepo); await _unitOfWork.CompleteAsync(); return(Ok()); } return(BadRequest(ModelState)); }
private void MapSenderAndReceivedRelatedFields(DatasetInstance e2bInstance) { var sendingAuthority = _siteContactDetailRepository.Get(cd => cd.ContactType == ContactType.SendingAuthority); if (sendingAuthority != null) { e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Type"), ((int)sendingAuthority.OrganisationType).ToString()); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Organization"), sendingAuthority.OrganisationName); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Department"), sendingAuthority.DepartmentName); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Given Name"), sendingAuthority.ContactFirstName); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Family Name"), sendingAuthority.ContactSurname); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Street Address"), sendingAuthority.StreetAddress); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender City"), sendingAuthority.City); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender State"), sendingAuthority.State); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Postcode"), sendingAuthority.PostCode); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Tel Number"), sendingAuthority.ContactNumber); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Tel Country Code"), sendingAuthority.CountryCode); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Sender Email Address"), sendingAuthority.ContactEmail); } var receivingAuthority = _siteContactDetailRepository.Get(cd => cd.ContactType == ContactType.ReceivingAuthority); if (receivingAuthority != null) { e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Type"), ((int)receivingAuthority.OrganisationType).ToString()); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Organization"), receivingAuthority.OrganisationName); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Department"), receivingAuthority.DepartmentName); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Given Name"), receivingAuthority.ContactFirstName); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Family Name"), receivingAuthority.ContactSurname); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Street Address"), receivingAuthority.StreetAddress); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver City"), receivingAuthority.City); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver State"), receivingAuthority.State); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Postcode"), receivingAuthority.PostCode); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Tel"), receivingAuthority.ContactNumber); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Tel Country Code"), receivingAuthority.CountryCode); e2bInstance.SetInstanceValue(_datasetElementRepository.Get(dse => dse.ElementName == "Receiver Email Address"), receivingAuthority.ContactEmail); } }
public async Task <IActionResult> ArchiveEncounter(long patientId, long id, [FromBody] ArchiveDto encounterForDelete) { var encounterFromRepo = await _encounterRepository.GetAsync(e => e.Patient.Id == patientId && e.Id == id); if (encounterFromRepo == null) { return(NotFound()); } if (Regex.Matches(encounterForDelete.Reason, @"[-a-zA-Z0-9 .']").Count < encounterForDelete.Reason.Length) { ModelState.AddModelError("Message", "Reason contains invalid characters (Enter A-Z, a-z, space, period, apostrophe)"); } var userName = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; var user = _userRepository.Get(u => u.UserName == userName); if (user == null) { ModelState.AddModelError("Message", "Unable to locate user"); } if (ModelState.IsValid) { foreach (var attachment in encounterFromRepo.Attachments.Where(x => !x.Archived)) { attachment.ArchiveAttachment(user, encounterForDelete.Reason); _attachmentRepository.Update(attachment); } foreach (var patientClinicalEvent in encounterFromRepo.PatientClinicalEvents.Where(x => !x.Archived)) { patientClinicalEvent.Archive(user, encounterForDelete.Reason); _patientClinicalEventRepository.Update(patientClinicalEvent); } encounterFromRepo.Archived = true; encounterFromRepo.ArchivedDate = DateTime.Now; encounterFromRepo.ArchivedReason = encounterForDelete.Reason; encounterFromRepo.AuditUser = user; _encounterRepository.Update(encounterFromRepo); await _unitOfWork.CompleteAsync(); return(Ok()); } return(BadRequest(ModelState)); }
/// <summary> /// Map additional dto detail elements not handled through automapper /// </summary> /// <param name="dto">The dto that the link has been added to</param> /// <returns></returns> private MetaReportDetailDto CustomReportMap(MetaReportDetailDto dto) { var metaReportFromRepo = _metaReportRepository.Get(p => p.Id == dto.Id); if (metaReportFromRepo == null) { return(dto); } // Map report definition attributes XmlDocument meta = new XmlDocument(); meta.LoadXml(metaReportFromRepo.MetaDefinition); XmlNode rootNode = meta.SelectSingleNode("//MetaReport"); XmlAttribute typeAttr = rootNode.Attributes["Type"]; XmlAttribute entityAttr = rootNode.Attributes["CoreEntity"]; dto.CoreEntity = entityAttr.Value; dto.ReportType = typeAttr.Value; return(dto); }
/// <summary> /// Map additional dto detail elements not handled through automapper /// </summary> /// <param name="dto">The dto that the link has been added to</param> /// <returns></returns> private MetaWidgetDetailDto CustomWidgetMap(MetaWidgetDetailDto dto) { var metaWidget = _metaWidgetRepository.Get(p => p.Id == dto.Id); if (metaWidget == null) { return(dto); } var widgetType = (MetaWidgetTypes)metaWidget.WidgetType.Id; if (widgetType == MetaWidgetTypes.SubItem) { XmlDocument wdoc = new XmlDocument(); wdoc.LoadXml(metaWidget.Content); XmlNode wroot = wdoc.DocumentElement; // Loop through each listitem foreach (XmlNode node in wroot.ChildNodes) { var listItem = new WidgetistItemDto() { Title = node.ChildNodes[0].InnerText, SubTitle = node.ChildNodes[1].InnerText, ContentPage = node.ChildNodes[2].InnerText, Modified = node.ChildNodes[3] != null ? node.ChildNodes[3].InnerText : DateTime.Today.ToString("yyyy-MM-dd") }; dto.ContentItems.Add(listItem); } } if (widgetType == MetaWidgetTypes.ItemList) { XmlDocument doc = new XmlDocument(); doc.LoadXml(metaWidget.Content); XmlNode root = doc.DocumentElement; // Loop through each listitem foreach (XmlNode node in root.ChildNodes) { var listItem = new WidgetistItemDto() { Title = node.ChildNodes[0].InnerText, Content = node.ChildNodes[1].InnerText, }; dto.ContentItems.Add(listItem); } } return(dto); }
private void UpdateValuesUsingSource(DatasetInstance e2bInstance, DatasetInstance spontaneousReport, Dataset dataset) { var userName = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; var user = _userRepository.Get(u => u.UserName == userName); if (dataset.DatasetName.Contains("(R2)")) { SetInstanceValuesForSpontaneousRelease2(e2bInstance, spontaneousReport, user); } if (dataset.DatasetName.Contains("(R3)")) { SetInstanceValuesForSpontaneousRelease3(e2bInstance, spontaneousReport, user); } }
/// <summary> /// Map additional dto detail elements not handled through automapper /// </summary> /// <param name="dto">The dto that the link has been added to</param> /// <returns></returns> private DatasetElementExpandedDto CustomElementMap(DatasetElementExpandedDto dto) { var datasetElement = _datasetElementRepository.Get(p => p.Id == dto.Id); if (datasetElement == null) { return(dto); } var rule = datasetElement.GetRule(DatasetRuleType.ElementCanoOnlyLinkToSingleDataset); dto.SingleDatasetRule = rule.RuleActive ? "Yes" : "No"; return(dto); }
/// <summary> /// Map additional dto detail elements not handled through automapper /// </summary> /// <param name="dto">The dto that the link has been added to</param> /// <returns></returns> private EncounterTypeDetailDto CustomTypeMap(EncounterTypeDetailDto dto) { var encounterTypeFromRepo = _encounterTypeRepository.Get(p => p.Id == dto.Id); if (encounterTypeFromRepo == null) { return(dto); } dto.WorkPlanName = string.Empty; if (encounterTypeFromRepo.EncounterTypeWorkPlans.Count > 0) { dto.WorkPlanName = encounterTypeFromRepo.EncounterTypeWorkPlans.First().WorkPlan.Description; } return(dto); }
private async Task CreateLinksAsync(ReportInstance reportInstanceFromRepo, ReportInstanceDetailDto mappedReportInstance) { if (reportInstanceFromRepo == null) { throw new ArgumentNullException(nameof(reportInstanceFromRepo)); } mappedReportInstance.Links.Add(new LinkDto(_linkGeneratorService.CreateReportInstanceResourceUri(reportInstanceFromRepo.WorkFlow.WorkFlowGuid, mappedReportInstance.Id), "self", "GET")); switch (reportInstanceFromRepo.CurrentActivity.QualifiedName) { case "Confirm Report Data": CreateLinksForConfirmationStep(reportInstanceFromRepo, mappedReportInstance); break; case "Set MedDRA and Causality": await CreateLinksForTerminologyStepAsync(reportInstanceFromRepo, mappedReportInstance); break; case "Extract E2B": await CreateLinksForE2BStepAsync(reportInstanceFromRepo, mappedReportInstance); break; default: break; } var validRoles = new string[] { "RegClerk", "DataCap", "Clinician" }; if (reportInstanceFromRepo.WorkFlow.Description == "New Active Surveilliance Report") { mappedReportInstance.Links.Add(new LinkDto(_linkGeneratorService.CreateResourceUri("Patient", reportInstanceFromRepo.Id), "viewpatient", "GET")); } if (reportInstanceFromRepo.WorkFlow.Description == "New Spontaneous Surveilliance Report") { var datasetInstance = _datasetInstanceRepository.Get(di => di.DatasetInstanceGuid == reportInstanceFromRepo.ContextGuid); if (datasetInstance != null) { mappedReportInstance.Links.Add(new LinkDto(_linkGeneratorService.CreateUpdateDatasetInstanceResourceUri( datasetInstance.Dataset.Id, datasetInstance.Id), "updatespont", "PUT")); } } }
/// <summary> /// Register patient encounter /// </summary> public async Task <int> AddEncounterAsync(Patient patient, EncounterDetail encounterDetail) { var encounterType = _encounterTypeRepository.Get(et => et.Id == encounterDetail.EncounterTypeId); if (encounterType == null) { throw new ArgumentException(nameof(encounterDetail.EncounterTypeId)); } var priority = _priorityRepository.Get(p => p.Id == encounterDetail.PriorityId); if (priority == null) { throw new ArgumentException(nameof(encounterDetail.PriorityId)); } var newEncounter = new Encounter(patient) { EncounterType = encounterType, Priority = priority, EncounterDate = encounterDetail.EncounterDate, Notes = encounterDetail.Notes }; //newEncounter.AuditStamp(user); await _encounterRepository.SaveAsync(newEncounter); var encounterTypeWorkPlan = _encounterTypeWorkPlanRepository.Get(et => et.EncounterType.Id == encounterType.Id, new string[] { "WorkPlan.Dataset" }); if (encounterTypeWorkPlan != null) { // Create a new instance var dataset = _datasetRepository.Get(d => d.Id == encounterTypeWorkPlan.WorkPlan.Dataset.Id, new string[] { "DatasetCategories.DatasetCategoryElements.DatasetElement.Field.FieldType" }); if (dataset != null) { var datasetInstance = dataset.CreateInstance(newEncounter.Id, "", encounterTypeWorkPlan, null, null); await _datasetInstanceRepository.SaveAsync(datasetInstance); } } return(newEncounter.Id); }
public async Task <string> GetCustomAttributeValueAsync(string extendableTypeName, string attributeKey, IExtendable extended) { var configuration = await _customAttributeConfigRepository.GetAsync(c => c.ExtendableTypeName == extendableTypeName && c.AttributeKey == attributeKey); if (configuration == null) { return(""); } DateTime dttemp; var val = extended.GetAttributeValue(configuration.AttributeKey); if (val == null) { return(""); } ; switch (configuration.CustomAttributeType) { case CustomAttributeType.FirstClassProperty: case CustomAttributeType.None: return(string.Empty); case CustomAttributeType.Numeric: case CustomAttributeType.String: return(val.ToString()); case CustomAttributeType.Selection: var selection = _selectionDataItemRepository.Get(s => s.AttributeKey == configuration.AttributeKey && s.SelectionKey == val.ToString()); return(selection?.Value); case CustomAttributeType.DateTime: return(DateTime.TryParse(val.ToString(), out dttemp) ? Convert.ToDateTime(val) > DateTime.MinValue ? Convert.ToDateTime(val).ToString("yyyy-MM-dd") : string.Empty : string.Empty); default: return(string.Empty); } }
public async Task AddToRoleAsync(UserInfo userInfo, string roleName) { var user = userRepository.Get(userInfo.Id); var role = roleRepository.Queryable().SingleOrDefault(r => r.Key == roleName); if (user == null) { throw new InvalidOperationException("User not found."); } if (role == null) { throw new InvalidOperationException("Role not recognised."); } await Task.Run(() => { userRoleRepository.Save(new UserRole { User = user, Role = role }); }); }
public async Task <bool> Handle(ChangeLabTestDetailsCommand message, CancellationToken cancellationToken) { var patientFromRepo = await _patientRepository.GetAsync(f => f.Id == message.PatientId, new string[] { "PatientLabTests.LabTest", "PatientLabTests.TestUnit" }); if (patientFromRepo == null) { throw new KeyNotFoundException($"Unable to locate patient {message.PatientId}"); } LabTestUnit labTestUnitFromRepo = null; if (!String.IsNullOrWhiteSpace(message.TestUnit)) { labTestUnitFromRepo = _labTestUnitRepository.Get(u => u.Description == message.TestUnit); if (labTestUnitFromRepo == null) { throw new KeyNotFoundException($"Unable to locate lab test unit with a description of {message.TestUnit}"); } } var labTestToUpdate = patientFromRepo.PatientLabTests.Single(plt => plt.Id == message.PatientLabTestId); var labTestAttributes = await PrepareAttributesWithNewValuesAsync(labTestToUpdate, message.Attributes); var userName = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; patientFromRepo.ChangeLabTestDetails(message.PatientLabTestId, message.TestDate, message.TestResultCoded, labTestUnitFromRepo, message.TestResultValue, message.ReferenceLower, message.ReferenceUpper); _modelExtensionBuilder.ValidateAndUpdateExtendable(labTestToUpdate, labTestAttributes, userName); _patientRepository.Update(patientFromRepo); _logger.LogInformation($"----- Lab Test {message.PatientLabTestId} details updated"); return(await _unitOfWork.CompleteAsync()); }
public async Task <bool> Handle(ChangePatientFacilityCommand message, CancellationToken cancellationToken) { var patientFromRepo = await _patientRepository.GetAsync(f => f.Id == message.PatientId); if (patientFromRepo == null) { throw new KeyNotFoundException("Unable to locate patient"); } var facilityFromRepo = _facilityRepository.Get(f => f.FacilityName == message.FacilityName); if (facilityFromRepo == null) { throw new KeyNotFoundException("Unable to locate facility"); } patientFromRepo.ChangePatientFacility(facilityFromRepo); _patientRepository.Update(patientFromRepo); _logger.LogInformation($"----- Patient {message.PatientId} facility details updated"); return(await _unitOfWork.CompleteAsync()); }
/// <summary> /// Get results from repository and auto map to Dto /// </summary> /// <typeparam name="T">Identifier, detail or expanded Dto</typeparam> /// <param name="analyserTermSetResourceParameters">Standard parameters for representing resource</param> /// <returns></returns> private PagedCollection <T> GetAnalyserTermSets <T>(AnalyserTermSetResourceParameters analyserTermSetResourceParameters) where T : class { var pagingInfo = new PagingInfo() { PageNumber = analyserTermSetResourceParameters.PageNumber, PageSize = analyserTermSetResourceParameters.PageSize }; // prepare risk factor xml var riskFactorXml = ""; var includeRiskFactor = "False"; XmlDocument xmlDoc = new XmlDocument(); if (analyserTermSetResourceParameters.RiskFactorOptionNames?.Count > 0) { XmlNode rootNode = xmlDoc.CreateElement("Factors", ""); foreach (var display in analyserTermSetResourceParameters.RiskFactorOptionNames) { var riskFactor = _riskFactorRepository.Get(r => r.Options.Any(ro => ro.Display == display)); if (riskFactor != null) { XmlNode factorNode = xmlDoc.CreateElement("Factor", ""); XmlNode factorChildNode = xmlDoc.CreateElement("Name", ""); factorChildNode.InnerText = riskFactor.FactorName; factorNode.AppendChild(factorChildNode); factorChildNode = xmlDoc.CreateElement("Option", ""); factorChildNode.InnerText = riskFactor.Options.Single(ro => ro.Display == display)?.Display; factorNode.AppendChild(factorChildNode); rootNode.AppendChild(factorNode); includeRiskFactor = "True"; } } xmlDoc.AppendChild(rootNode); riskFactorXml = xmlDoc.InnerXml; } List <SqlParameter> parameters = new List <SqlParameter>(); parameters.Add(new SqlParameter("@ConditionId", analyserTermSetResourceParameters.ConditionId.ToString())); parameters.Add(new SqlParameter("@CohortId", analyserTermSetResourceParameters.CohortGroupId.ToString())); parameters.Add(new SqlParameter("@StartDate", analyserTermSetResourceParameters.SearchFrom.ToString())); parameters.Add(new SqlParameter("@FinishDate", analyserTermSetResourceParameters.SearchTo.ToString())); parameters.Add(new SqlParameter("@TermID", "0")); parameters.Add(new SqlParameter("@IncludeRiskFactor", includeRiskFactor)); parameters.Add(new SqlParameter("@RateByCount", "True")); parameters.Add(new SqlParameter("@DebugPatientList", "False")); parameters.Add(new SqlParameter("@RiskFactorXml", riskFactorXml)); parameters.Add(new SqlParameter("@DebugMode", "False")); var resultsFromService = _context.ContingencyAnalysisLists .FromSqlRaw($"EXECUTE spGenerateAnalysis @ConditionId, @CohortId, @StartDate, @FinishDate, @TermID, @IncludeRiskFactor, @RateByCount, @DebugPatientList, @RiskFactorXml, @DebugMode", parameters.ToArray()).ToList(); if (resultsFromService != null) { // Map results to Dto var mappedResults = PagedCollection <T> .Create(_mapper.Map <PagedCollection <T> >(resultsFromService), pagingInfo.PageNumber, pagingInfo.PageSize, resultsFromService.Count); // Prepare pagination data for response var paginationMetadata = new { totalCount = mappedResults.TotalCount, pageSize = mappedResults.PageSize, currentPage = mappedResults.CurrentPage, totalPages = mappedResults.TotalPages, }; Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(paginationMetadata)); return(mappedResults); } return(null); }
/// <summary> /// Map additional dto detail elements not handled through automapper /// </summary> /// <param name="dto">The dto that the link has been added to</param> /// <returns></returns> private MetaReportExpandedDto CustomReportMap(MetaReportExpandedDto dto) { var metaReportFromRepo = _metaReportRepository.Get(p => p.Id == dto.Id); if (metaReportFromRepo == null) { return(dto); } // Map report definition attributes XmlDocument meta = new XmlDocument(); meta.LoadXml(metaReportFromRepo.MetaDefinition); XmlNode rootNode = meta.SelectSingleNode("//MetaReport"); XmlAttribute typeAttr = rootNode.Attributes["Type"]; XmlAttribute entityAttr = rootNode.Attributes["CoreEntity"]; dto.CoreEntity = entityAttr.Value; dto.ReportType = typeAttr.Value; // Map attributes var rootNodeName = dto.ReportType == "List" ? "//List" : "//Summary"; XmlNode mainNode = rootNode.SelectSingleNode(rootNodeName); if (mainNode != null) { foreach (XmlNode subNode in mainNode.ChildNodes) { var attribute = new MetaAttributeDto() { AttributeName = subNode.Attributes.GetNamedItem("AttributeName").Value, Aggregate = subNode.Attributes.GetNamedItem("Aggregate").Value, DisplayName = subNode.Attributes.GetNamedItem("DisplayName").Value, Index = dto.Attributes.Count + 1 }; dto.Attributes.Add(attribute); } } // Map filters mainNode = rootNode.SelectSingleNode("//Filter"); if (mainNode != null) { foreach (XmlNode subNode in mainNode.ChildNodes) { var attributeName = subNode.Attributes.GetNamedItem("AttributeName").Value; var filter = new MetaFilterDto() { AttributeName = attributeName, ColumnType = _metaColumnRepository.Get(mc => mc.ColumnName == attributeName)?.ColumnType.Description, Operator = subNode.Attributes.GetNamedItem("Operator").Value, Relation = subNode.Attributes.GetNamedItem("Relation").Value, Index = dto.Attributes.Count + 1 }; dto.Filters.Add(filter); } } // Map core entity var metaTableFromRepo = _metaTableRepository.Get(p => p.TableName == dto.CoreEntity, new string[] { "TableType", "Columns.ColumnType" }); if (metaTableFromRepo == null) { return(dto); } // Map EF entity to Dto dto.CoreMetaTable = _mapper.Map <MetaTableExpandedDto>(metaTableFromRepo); dto.CoreMetaTable.Columns = dto.CoreMetaTable.Columns.OrderBy(c => c.ColumnName).ToList(); dto.CoreMetaTable.Columns.ForEach(column => CustomColumnMap(column)); return(dto); }
public async Task <IActionResult> CreateForm([FromBody] FormForCreationDto formForCreation) { if (formForCreation == null) { ModelState.AddModelError("Message", "Unable to locate payload for new form"); return(BadRequest(ModelState)); } if (formForCreation.HasAttachment == false) { ModelState.AddModelError("Message", "Unable to process form as no attachment has been submitted"); return(BadRequest(ModelState)); } // Meta form for template extraction var metaFormFromRepo = await _metaFormRepository.GetAsync(f => f.ActionName.ToLower().Replace(" ", "") == formForCreation.FormType.ToLower().Replace(" ", "")); if (metaFormFromRepo == null) { ModelState.AddModelError("Message", "Unable to locate meta form for template extraction"); return(BadRequest(ModelState)); } // Store user for audit log generation purposes var userName = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value; var userFromRepo = _userRepository.Get(u => u.UserName == userName); AuditLog auditLog = null; // TODO Use meta form to identify context handler (add/update encounter/patient) //var handler = new FormValueHandler(formForCreation.FormValues.Where(fv => fv.FormControlKey == "Object").Select(fv => fv.FormControlValue).ToList()); _formHandler.SetForm(formForCreation); // Validation of the source entity _formHandler.ValidateSourceIdentifier(); if (_formHandler.GetValidationErrors().Count > 0) { foreach (string message in _formHandler.GetValidationErrors()) { ModelState.AddModelError("Message", message); } } if (ModelState.IsValid) { _formHandler.PreparePatientAndClinicalDetail(); if (_formHandler.GetValidationErrors().Count > 0) { foreach (string message in _formHandler.GetValidationErrors()) { ModelState.AddModelError("Message", message); } } } if (ModelState.IsValid) { try { auditLog = new AuditLog() { AuditType = AuditType.SynchronisationForm, User = userFromRepo, ActionDate = DateTime.Now, Details = $"Form submission successful {formForCreation.FormIdentifier}", Log = JsonConvert.SerializeObject(formForCreation, Formatting.Indented) }; await _auditLogRepository.SaveAsync(auditLog); await _formHandler.ProcessFormForCreationOrUpdateAsync(); await _unitOfWork.CompleteAsync(); return(Ok()); } catch (Exception ex) { var error = new Dictionary <string, string> { { "Type", ex.GetType().ToString() }, { "Message", ex.Message }, { "StackTrace", ex.StackTrace } }; auditLog = new AuditLog() { AuditType = AuditType.SynchronisationError, User = userFromRepo, ActionDate = DateTime.Now, Details = $"Error on form {formForCreation.FormIdentifier}", Log = JsonConvert.SerializeObject(error, Formatting.Indented) }; _auditLogRepository.Save(auditLog); return(StatusCode(500, ex.Message + " " + ex.InnerException?.Message)); } } var audit = new AuditLog() { AuditType = AuditType.SynchronisationError, User = userFromRepo, ActionDate = DateTime.Now, Details = $"Form submission with model error {formForCreation.FormIdentifier}", Log = JsonConvert.SerializeObject(formForCreation, Formatting.Indented) }; await _auditLogRepository.SaveAsync(audit); return(BadRequest(ModelState)); }
public async Task <IActionResult> CreatePatientCondition(int patientId, [FromBody] PatientConditionForUpdateDto conditionForUpdate) { if (conditionForUpdate == null) { ModelState.AddModelError("Message", "Unable to locate payload for new condition"); return(BadRequest(ModelState)); } var patientFromRepo = await _patientRepository.GetAsync(f => f.Id == patientId); if (patientFromRepo == null) { return(NotFound()); } var sourceTermFromRepo = _terminologyMeddraRepository.Get(conditionForUpdate.SourceTerminologyMedDraId); if (sourceTermFromRepo == null) { ModelState.AddModelError("Message", "Unable to locate source term"); } Outcome outcomeFromRepo = null; if (!String.IsNullOrWhiteSpace(conditionForUpdate.Outcome)) { outcomeFromRepo = _outcomeRepository.Get(o => o.Description == conditionForUpdate.Outcome); if (outcomeFromRepo == null) { ModelState.AddModelError("Message", "Unable to locate outcome"); } } TreatmentOutcome treatmentOutcomeFromRepo = null; if (!String.IsNullOrWhiteSpace(conditionForUpdate.TreatmentOutcome)) { treatmentOutcomeFromRepo = _treatmentOutcomeRepository.Get(to => to.Description == conditionForUpdate.TreatmentOutcome); if (treatmentOutcomeFromRepo == null) { ModelState.AddModelError("Message", "Unable to locate treatment outcome"); } } ValidateConditionForUpdateModel(patientFromRepo, conditionForUpdate, 0); // Custom validation if (outcomeFromRepo != null && treatmentOutcomeFromRepo != null) { if (outcomeFromRepo.Description == "Fatal" && treatmentOutcomeFromRepo.Description != "Died") { ModelState.AddModelError("Message", "Treatment Outcome not consistent with Condition Outcome"); } if (outcomeFromRepo.Description != "Fatal" && treatmentOutcomeFromRepo.Description == "Died") { ModelState.AddModelError("Message", "Condition Outcome not consistent with Treatment Outcome"); } } if (ModelState.IsValid) { var conditionDetail = PrepareConditionDetail(conditionForUpdate); if (!conditionDetail.IsValid()) { conditionDetail.InvalidAttributes.ForEach(element => ModelState.AddModelError("Message", element)); } if (ModelState.IsValid) { var patientCondition = patientFromRepo.AddOrUpdatePatientCondition(0, sourceTermFromRepo, conditionForUpdate.StartDate, conditionForUpdate.OutcomeDate, outcomeFromRepo, treatmentOutcomeFromRepo, conditionForUpdate.CaseNumber, conditionForUpdate.Comments, conditionForUpdate.SourceDescription, _patientStatusRepository.Get(ps => ps.Description == "Died")); //throw new Exception(JsonConvert.SerializeObject(patientCondition)); _modelExtensionBuilder.UpdateExtendable(patientCondition, conditionDetail.CustomAttributes, "Admin"); _patientConditionRepository.Save(patientCondition); await _unitOfWork.CompleteAsync(); var mappedPatientCondition = _mapper.Map <PatientConditionIdentifierDto>(patientCondition); if (mappedPatientCondition == null) { return(StatusCode(500, "Unable to locate newly added condition")); } return(CreatedAtAction("GetPatientConditionByIdentifier", new { id = mappedPatientCondition.Id }, CreateLinksForPatientCondition <PatientConditionIdentifierDto>(mappedPatientCondition))); } } return(BadRequest(ModelState)); }
public async Task <bool> Handle(ChangeConditionDetailsCommand message, CancellationToken cancellationToken) { var patientFromRepo = await _patientRepository.GetAsync(f => f.Id == message.PatientId, new string[] { "PatientConditions.TerminologyMedDra", "PatientStatusHistories.PatientStatus" }); if (patientFromRepo == null) { throw new KeyNotFoundException("Unable to locate patient"); } var sourceTerminologyFromRepo = _terminologyMeddraRepository.Get(message.SourceTerminologyMedDraId); if (sourceTerminologyFromRepo == null) { throw new KeyNotFoundException("Unable to locate source terminology"); } Outcome outcomeFromRepo = null; if (!String.IsNullOrWhiteSpace(message.Outcome)) { outcomeFromRepo = _outcomeRepository.Get(o => o.Description == message.Outcome); if (outcomeFromRepo == null) { throw new KeyNotFoundException("Unable to locate outcome"); } } TreatmentOutcome treatmentOutcomeFromRepo = null; if (!String.IsNullOrWhiteSpace(message.TreatmentOutcome)) { treatmentOutcomeFromRepo = _treatmentOutcomeRepository.Get(to => to.Description == message.TreatmentOutcome); if (treatmentOutcomeFromRepo == null) { throw new KeyNotFoundException("Unable to locate treatment outcome"); } } if (outcomeFromRepo != null && treatmentOutcomeFromRepo != null) { if (outcomeFromRepo.Description == "Fatal" && treatmentOutcomeFromRepo.Description != "Died") { throw new DomainException("Treatment Outcome not consistent with Condition Outcome"); } if (outcomeFromRepo.Description != "Fatal" && treatmentOutcomeFromRepo.Description == "Died") { throw new DomainException("Condition Outcome not consistent with Treatment Outcome"); } } var conditionDetail = await PrepareConditionDetailAsync(message.Attributes); if (!conditionDetail.IsValid()) { conditionDetail.InvalidAttributes.ForEach(element => throw new DomainException(element)); } patientFromRepo.ChangeConditionDetails(message.PatientConditionId, message.SourceTerminologyMedDraId, message.StartDate, message.OutcomeDate, outcomeFromRepo, treatmentOutcomeFromRepo, message.CaseNumber, message.Comments); _modelExtensionBuilder.UpdateExtendable(patientFromRepo.PatientConditions.Single(pm => pm.Id == message.PatientConditionId), conditionDetail.CustomAttributes, "Admin"); if (outcomeFromRepo?.Description == "Fatal" && patientFromRepo.GetCurrentStatus().PatientStatus.Description != "Died") { var patientStatus = await _patientStatusRepository.GetAsync(ps => ps.Description == "Died"); patientFromRepo.ChangePatientStatus(patientStatus, message.OutcomeDate ?? DateTime.Now, $"Marked as deceased through condition ({sourceTerminologyFromRepo.DisplayName})"); } _patientRepository.Update(patientFromRepo); _logger.LogInformation($"----- Condition {message.PatientConditionId} details updated"); return(await _unitOfWork.CompleteAsync()); }
public async Task <IActionResult> CreateEncounterType( [FromBody] EncounterTypeForUpdateDto encounterTypeForUpdate) { if (encounterTypeForUpdate == null) { ModelState.AddModelError("Message", "Unable to locate payload for new request"); } if (Regex.Matches(encounterTypeForUpdate.EncounterTypeName, @"[a-zA-Z ']").Count < encounterTypeForUpdate.EncounterTypeName.Length) { ModelState.AddModelError("Message", "Description contains invalid characters (Enter A-Z, a-z)"); } if (!String.IsNullOrWhiteSpace(encounterTypeForUpdate.Help)) { if (Regex.Matches(encounterTypeForUpdate.Help, @"[a-zA-Z0-9. ']").Count < encounterTypeForUpdate.Help.Length) { ModelState.AddModelError("Message", "Help contains invalid characters (Enter A-Z, a-z, 0-9, period)"); } } if (_unitOfWork.Repository <EncounterType>().Queryable(). Where(l => l.Description == encounterTypeForUpdate.EncounterTypeName) .Count() > 0) { ModelState.AddModelError("Message", "Item with same name already exists"); } var workPlan = _workPlanRepository.Get(wp => wp.Description == encounterTypeForUpdate.WorkPlanName); if (workPlan == null) { ModelState.AddModelError("Message", "Unable to locate work plan"); } long id = 0; if (ModelState.IsValid) { var newEncounterType = new EncounterType() { Description = encounterTypeForUpdate.EncounterTypeName, Help = encounterTypeForUpdate.Help }; var newEncounterTypeWorkPlan = new EncounterTypeWorkPlan() { CohortGroup = null, EncounterType = newEncounterType, WorkPlan = workPlan }; _encounterTypeRepository.Save(newEncounterType); _encounterTypeWorkPlanRepository.Save(newEncounterTypeWorkPlan); id = newEncounterType.Id; var mappedEncounterType = await GetEncounterTypeAsync <EncounterTypeIdentifierDto>(id); if (mappedEncounterType == null) { return(StatusCode(500, "Unable to locate newly added item")); } return(CreatedAtAction("GetEncounterTypeByIdentifier", new { id = mappedEncounterType.Id }, CreateLinksForEncounterType <EncounterTypeIdentifierDto>(mappedEncounterType))); } return(BadRequest(ModelState)); }