/// <summary>
        /// Maps the outbound resource to FHIR.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override ImmunizationRecommendation MapToFhir(SubstanceAdministration model)
        {
            ImmunizationRecommendation retVal = new ImmunizationRecommendation();

            retVal.Id          = model.Key.ToString();
            retVal.DateElement = new FhirDateTime(DateTimeOffset.Now);
            retVal.Identifier  = model.Identifiers.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            var rct = model.LoadCollection <ActParticipation>(nameof(Act.Participations)).FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget)?.LoadProperty <Entity>(nameof(ActParticipation.PlayerEntity));

            if (rct != null)
            {
                retVal.Patient = DataTypeConverter.CreateNonVersionedReference <Patient>(rct);
            }

            var mat = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Product).PlayerEntity;

            // Recommend
            string status         = (model.StopTime ?? model.ActTime) < DateTimeOffset.Now ? "overdue" : "due";
            var    recommendation = new ImmunizationRecommendation.RecommendationComponent()
            {
                DoseNumber  = new PositiveInt(model.SequenceId),
                VaccineCode = new List <CodeableConcept>()
                {
                    DataTypeConverter.ToFhirCodeableConcept(mat?.TypeConceptKey)
                },
                ForecastStatus = new CodeableConcept("http://hl7.org/fhir/conceptset/immunization-recommendation-status", status),
                DateCriterion  = new List <ImmunizationRecommendation.DateCriterionComponent>()
                {
                    new ImmunizationRecommendation.DateCriterionComponent()
                    {
                        Code         = new CodeableConcept("http://hl7.org/fhir/conceptset/immunization-recommendation-date-criterion", "recommended"),
                        ValueElement = new FhirDateTime(model.ActTime)
                    }
                }
            };

            if (model.StartTime.HasValue)
            {
                recommendation.DateCriterion.Add(new ImmunizationRecommendation.DateCriterionComponent()
                {
                    Code         = new CodeableConcept("http://hl7.org/fhir/conceptset/immunization-recommendation-date-criterion", "earliest"),
                    ValueElement = new FhirDateTime(model.StartTime.Value)
                });
            }
            if (model.StopTime.HasValue)
            {
                recommendation.DateCriterion.Add(new ImmunizationRecommendation.DateCriterionComponent()
                {
                    Code         = new CodeableConcept("http://hl7.org/fhir/conceptset/immunization-recommendation-date-criterion", "overdue"),
                    ValueElement = new FhirDateTime(model.StopTime.Value)
                });
            }

            retVal.Recommendation = new List <ImmunizationRecommendation.RecommendationComponent>()
            {
                recommendation
            };
            return(retVal);
        }
예제 #2
0
 /// <summary>
 /// Construct the extension
 /// </summary>
 public IEnumerable <Extension> Construct(IIdentifiedEntity modelObject)
 {
     if (modelObject is SanteDB.Core.Model.Roles.Patient patient && patient.ReligiousAffiliationKey.HasValue)
     {
         yield return(new Extension(this.Uri.ToString(), DataTypeConverter.ToFhirCodeableConcept(patient.ReligiousAffiliationKey)));
     }
 }
        /// <summary>
        /// Map the substance to FHIR
        /// </summary>
        protected override Substance MapToFhir(Material model)
        {
            var retVal = DataTypeConverter.CreateResource <Substance>(model);

            // Identifiers
            retVal.Identifier = model.Identifiers.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            // sTatus
            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.New:
            case StatusKeyStrings.Active:
                retVal.Status = Substance.FHIRSubstanceStatus.Active;
                break;

            case StatusKeyStrings.Nullified:
                retVal.Status = Substance.FHIRSubstanceStatus.EnteredInError;
                break;

            case StatusKeyStrings.Obsolete:
                retVal.Status = Substance.FHIRSubstanceStatus.Inactive;
                break;
            }

            // Category and code
            retVal.Category = new List <CodeableConcept>
            {
                DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey, "http://terminology.hl7.org/CodeSystem/substance-category")
            };

            retVal.Code        = DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey, "http://snomed.info/sct");
            retVal.Description = model.LoadCollection <EntityName>("Names").FirstOrDefault(o => o.NameUseKey == NameUseKeys.OfficialRecord)?.LoadCollection <EntityNameComponent>("Components")?.FirstOrDefault()?.Value;

            // TODO: Instance or kind
            if (model.DeterminerConceptKey == DeterminerKeys.Described)
            {
                retVal.Instance = model.GetRelationships().Where(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Instance).Select(s => s.LoadProperty <Material>(nameof(EntityRelationship.TargetEntity))).Select(m => new Substance.InstanceComponent
                {
                    ExpiryElement = DataTypeConverter.ToFhirDateTime(model.ExpiryDate),
                    Identifier    = DataTypeConverter.ToFhirIdentifier(m.GetIdentifiers().FirstOrDefault()),
                    Quantity      = DataTypeConverter.ToQuantity(m.Quantity, m.QuantityConceptKey)
                }).ToList();
            }
            else if (model.DeterminerConceptKey == DeterminerKeys.Specific)
            {
                var conceptRepo = ApplicationServiceContext.Current.GetService <IConceptRepositoryService>();

                retVal.Instance = new List <Substance.InstanceComponent>
                {
                    new Substance.InstanceComponent
                    {
                        ExpiryElement = DataTypeConverter.ToFhirDateTime(model.ExpiryDate),
                        Quantity      = DataTypeConverter.ToQuantity(model.Quantity, model.QuantityConceptKey)
                    }
                };
            }

            return(retVal);
        }
예제 #4
0
        /// <summary>
        /// Map the inbound place to a FHIR model
        /// </summary>
        protected override Location MapToFhir(Place model, WebOperationContext webOperationContext)
        {
            Location retVal = DataTypeConverter.CreateResource <Location>(model);

            retVal.Identifier = model.Identifiers.Select(o => DataTypeConverter.ToFhirIdentifier <Entity>(o)).ToList();

            // Map status
            if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Status = LocationStatus.Active;
            }
            else if (model.StatusConceptKey == StatusKeys.Obsolete)
            {
                retVal.Status = LocationStatus.Inactive;
            }
            else
            {
                retVal.Status = LocationStatus.Suspended;
            }

            retVal.Name  = model.LoadCollection <EntityName>("Names").FirstOrDefault(o => o.NameUseKey == NameUseKeys.OfficialRecord)?.LoadCollection <EntityNameComponent>("Component")?.FirstOrDefault()?.Value;
            retVal.Alias = model.LoadCollection <EntityName>("Names").Where(o => o.NameUseKey != NameUseKeys.OfficialRecord)?.Select(n => (FhirString)n.LoadCollection <EntityNameComponent>("Component")?.FirstOrDefault()?.Value).ToList();

            // Convert the determiner code
            if (model.DeterminerConceptKey == DeterminerKeys.Described)
            {
                retVal.Mode = LocationMode.Kind;
            }
            else
            {
                retVal.Mode = LocationMode.Instance;
            }

            retVal.Type = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"), "http://hl7.org/fhir/ValueSet/v3-ServiceDeliveryLocationRoleType");

            retVal.Telecom = model.LoadCollection <EntityTelecomAddress>("Telecoms").Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();
            retVal.Address = DataTypeConverter.ToFhirAddress(model.LoadCollection <EntityAddress>("Addresses").FirstOrDefault());

            if (model.Lat.HasValue && model.Lng.HasValue)
            {
                retVal.Position = new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.Position()
                {
                    Latitude  = (decimal)model.Lat.Value,
                    Longitude = (decimal)model.Lng.Value
                }
            }
            ;

            // Part of?
            var parent = model.LoadCollection <EntityRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Parent);

            if (parent != null)
            {
                retVal.PartOf = DataTypeConverter.CreateReference <Location>(parent.LoadProperty <Entity>("TargetEntity"), webOperationContext);
            }

            return(retVal);
        }
        /// <summary>
        /// Map a user entity to a practitioner
        /// </summary>
        protected override Practitioner MapToFhir(Provider model)
        {
            // Is there a provider that matches this user?
            var provider = model.LoadCollection(o => o.Relationships).FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.AssignedEntity)?.LoadProperty(o => o.TargetEntity) as Provider;

            model = provider ?? model;

            var retVal = DataTypeConverter.CreateResource <Practitioner>(model);

            // Identifiers
            retVal.Identifier = model.LoadCollection(o => o.Identifiers)?.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            // ACtive
            retVal.Active = StatusKeys.ActiveStates.Contains(model.StatusConceptKey.Value);

            // Names
            retVal.Name = model.LoadCollection(o => o.Names)?.Select(o => DataTypeConverter.ToFhirHumanName(o)).ToList();

            // Telecoms
            retVal.Telecom = model.LoadCollection(o => o.Telecoms)?.Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();

            // Address
            retVal.Address = model.LoadCollection(p => p.Addresses)?.Select(o => DataTypeConverter.ToFhirAddress(o)).ToList();

            // Birthdate
            retVal.BirthDateElement = DataTypeConverter.ToFhirDate(provider?.DateOfBirth ?? model.DateOfBirth);

            var photo = (provider?.LoadCollection <EntityExtension>(nameof(Entity.Extensions)) ?? model.LoadCollection <EntityExtension>(nameof(Entity.Extensions)))?.FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.JpegPhotoExtension);

            if (photo != null)
            {
                retVal.Photo = new List <Attachment>()
                {
                    new Attachment()
                    {
                        ContentType = "image/jpg",
                        Data        = photo.ExtensionValueXml
                    }
                }
            }
            ;

            // Load the koala-fication
            retVal.Qualification = new List <Practitioner.QualificationComponent>()
            {
                new Practitioner.QualificationComponent()
                {
                    Code = DataTypeConverter.ToFhirCodeableConcept(provider.ProviderSpecialtyKey)
                }
            };

            // Language of communication
            retVal.Communication = model.LoadCollection(o => o.LanguageCommunication)?.Select(o => new CodeableConcept("http://tools.ietf.org/html/bcp47", o.LanguageCode)).ToList();

            return(retVal);
        }
        /// <summary>
        /// Map the substance to FHIR
        /// </summary>
        protected override Substance MapToFhir(Material model, RestOperationContext restOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Substance>(model);

            // Identifiers
            retVal.Identifier = model.Identifiers.Select(o => DataTypeConverter.ToFhirIdentifier <Entity>(o)).ToList();

            // sTatus
            if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Status = SubstanceStatus.Active;
            }
            else if (model.StatusConceptKey == StatusKeys.Nullified)
            {
                retVal.Status = SubstanceStatus.Nullified;
            }
            else if (model.StatusConceptKey == StatusKeys.Obsolete)
            {
                retVal.Status = SubstanceStatus.Inactive;
            }

            // Category and code
            if (model.LoadProperty <Concept>("TypeConcept").ConceptSetsXml.Any(o => o == ConceptSetKeys.VaccineTypeCodes))
            {
                retVal.Category = new SanteDB.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/substance-category"), "drug");
            }
            else
            {
                retVal.Category = new SanteDB.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/substance-category"), "material");
            }

            retVal.Code = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"), "http://hl7.org/fhir/ValueSet/substance-code");

            retVal.Description = model.LoadCollection <EntityName>("Names").FirstOrDefault(o => o.NameUseKey == NameUseKeys.OfficialRecord)?.LoadCollection <EntityNameComponent>("Components")?.FirstOrDefault()?.Value;

            // TODO: Instance or kind
            if (model.DeterminerConceptKey == DeterminerKeys.Specific)
            {
                var conceptRepo = ApplicationServiceContext.Current.GetService <IConceptRepositoryService>();
                retVal.Instance = new List <SanteDB.Messaging.FHIR.Backbone.SubstanceInstance>()
                {
                    new SanteDB.Messaging.FHIR.Backbone.SubstanceInstance()
                    {
                        Expiry   = model.ExpiryDate,
                        Quantity = new SanteDB.Messaging.FHIR.DataTypes.FhirQuantity()
                        {
                            Units = model.QuantityConceptKey.HasValue ? conceptRepo.GetConceptReferenceTerm(model.QuantityConceptKey.Value, "UCUM").Mnemonic : null,
                            Value = model.Quantity
                        }
                    }
                };
            }

            return(retVal);
        }
예제 #7
0
        /// <summary>
        /// Map this manufactured material to FHIR
        /// </summary>
        protected override Medication MapToFhir(ManufacturedMaterial model, RestOperationContext restOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Medication>(model);

            // Code of medication code
            retVal.Code = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"));

            if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Status = SubstanceStatus.Active;
            }
            else if (model.StatusConceptKey == StatusKeys.Obsolete)
            {
                retVal.Status = SubstanceStatus.Inactive;
            }
            else if (model.StatusConceptKey == StatusKeys.Nullified)
            {
                retVal.Status = SubstanceStatus.Nullified;
            }

            // Is brand?
            retVal.IsBrand          = false;
            retVal.IsOverTheCounter = model.Tags.Any(o => o.TagKey == "isOtc");

            var manufacturer = model.LoadCollection <EntityRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.WarrantedProduct);

            if (manufacturer != null)
            {
                retVal.Manufacturer = DataTypeConverter.CreateReference <SanteDB.Messaging.FHIR.Resources.Organization>(manufacturer.LoadProperty <Entity>("TargetEntity"), restOperationContext);
            }

            // Form
            retVal.Form          = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("FormConcept"), "http://hl7.org/fhir/ValueSet/medication-form-codes");
            retVal.Package       = new SanteDB.Messaging.FHIR.Backbone.MedicationPackage();
            retVal.Package.Batch = new SanteDB.Messaging.FHIR.Backbone.MedicationBatch()
            {
                LotNumber  = model.LotNumber,
                Expiration = model.ExpiryDate
            };

            // Picture of the object?

            var photo = model.LoadCollection <EntityExtension>("Extensions").FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.JpegPhotoExtension);

            if (photo != null)
            {
                retVal.Image = new SanteDB.Messaging.FHIR.DataTypes.Attachment()
                {
                    ContentType = "image/jpg",
                    Data        = photo.ExtensionValueXml
                }
            }
            ;
            return(retVal);
        }
예제 #8
0
        /// <summary>
        /// Map a user entity to a practitioner
        /// </summary>
        protected override Practitioner MapToFhir(UserEntity model, RestOperationContext restOperationContext)
        {
            // Is there a provider that matches this user?
            var provider = model.LoadCollection <EntityRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.AssignedEntity)?.LoadProperty <Provider>("TargetEntity");
            var retVal   = DataTypeConverter.CreateResource <Practitioner>(model);

            // Identifiers
            retVal.Identifier = (provider?.Identifiers ?? model.Identifiers)?.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            // ACtive
            retVal.Active = model.StatusConceptKey == StatusKeys.Active;

            // Names
            retVal.Name = (provider?.LoadCollection <EntityName>("Names") ?? model.LoadCollection <EntityName>("Names"))?.Select(o => DataTypeConverter.ToFhirHumanName(o)).ToList();

            // Telecoms
            retVal.Telecom = (provider?.LoadCollection <EntityTelecomAddress>("Telecom") ?? model.LoadCollection <EntityTelecomAddress>("Telecom"))?.Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();

            // Address
            retVal.Address = (provider?.LoadCollection <EntityAddress>("Addresses") ?? model.LoadCollection <EntityAddress>("Addresses"))?.Select(o => DataTypeConverter.ToFhirAddress(o)).ToList();

            // Birthdate
            retVal.BirthDate = (provider?.DateOfBirth ?? model.DateOfBirth);

            var photo = (provider?.LoadCollection <EntityExtension>("Extensions") ?? model.LoadCollection <EntityExtension>("Extensions"))?.FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.JpegPhotoExtension);

            if (photo != null)
            {
                retVal.Photo = new List <Attachment>()
                {
                    new Attachment()
                    {
                        ContentType = "image/jpg",
                        Data        = photo.ExtensionValueXml
                    }
                }
            }
            ;

            // Load the koala-fications
            retVal.Qualification = provider?.LoadCollection <Concept>("ProviderSpecialty").Select(o => new Qualification()
            {
                Code = DataTypeConverter.ToFhirCodeableConcept(o)
            }).ToList();

            // Language of communication
            retVal.Communication = (provider?.LoadCollection <PersonLanguageCommunication>("LanguageCommunication") ?? model.LoadCollection <PersonLanguageCommunication>("LanguageCommunication"))?.Select(o => new FhirCodeableConcept(new Uri("http://tools.ietf.org/html/bcp47"), o.LanguageCode)).ToList();

            return(retVal);
        }
        /// <summary>
        /// Maps a <see cref="ManufacturedMaterial"/> instance to a FHIR <see cref="Medication"/> instance.
        /// </summary>
        /// <param name="model">The instance to map.</param>
        /// <returns>Returns the mapped instance.</returns>
        protected override Medication MapToFhir(ManufacturedMaterial model)
        {
            var retVal = DataTypeConverter.CreateResource <Medication>(model);

            // Code of medication code
            retVal.Code       = DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey, "http://snomed.info/sct");
            retVal.Identifier = model.LoadCollection <EntityIdentifier>(nameof(Entity.Identifiers)).Select(DataTypeConverter.ToFhirIdentifier).ToList();

            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.Active:
            case StatusKeyStrings.New:
                retVal.Status = Medication.MedicationStatusCodes.Active;
                break;

            case StatusKeyStrings.Obsolete:
                retVal.Status = Medication.MedicationStatusCodes.Inactive;
                break;

            case StatusKeyStrings.Nullified:
                retVal.Status = Medication.MedicationStatusCodes.EnteredInError;
                break;
            }

            // Is brand?
            var manufacturer = model.LoadCollection <EntityRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.ManufacturedProduct);

            if (manufacturer != null)
            {
                retVal.Manufacturer = DataTypeConverter.CreateVersionedReference <Organization>(manufacturer.LoadProperty <Entity>(nameof(EntityRelationship.TargetEntity)));
            }

            // Form
            retVal.Form  = DataTypeConverter.ToFhirCodeableConcept(model.FormConceptKey, "http://hl7.org/fhir/ValueSet/medication-form-codes");
            retVal.Batch = new Medication.BatchComponent
            {
                LotNumber             = model.LotNumber,
                ExpirationDateElement = DataTypeConverter.ToFhirDateTime(model.ExpiryDate)
            };

            return(retVal);
        }
예제 #10
0
        /// <summary>
        /// Maps the specified act to an adverse event
        /// </summary>
        protected override AdverseEvent MapToFhir(Act model, WebOperationContext webOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <AdverseEvent>(model);

            retVal.Identifier = DataTypeConverter.ToFhirIdentifier <Act>(model.Identifiers.FirstOrDefault());
            retVal.Category   = AdverseEventCategory.AdverseEvent;
            retVal.Type       = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"));

            var recordTarget = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (recordTarget != null)
            {
                retVal.Subject = DataTypeConverter.CreateReference <Patient>(recordTarget.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            // Main topic of the concern
            var subject = model.LoadCollection <ActRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.HasSubject)?.LoadProperty <Act>("TargetAct");

            if (subject == null)
            {
                throw new InvalidOperationException("This act does not appear to be an adverse event");
            }
            retVal.Date = subject.ActTime.DateTime;

            // Reactions = HasManifestation
            var reactions = subject.LoadCollection <ActRelationship>("Relationships").Where(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.HasManifestation);

            retVal.Reaction = reactions.Select(o => DataTypeConverter.CreateReference <Condition>(o.LoadProperty <Act>("TargetAct"), webOperationContext)).ToList();

            var location = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Location);

            if (location != null)
            {
                retVal.Location = DataTypeConverter.CreateReference <Location>(location.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            // Severity
            var severity = subject.LoadCollection <ActRelationship>("Relationships").First(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent && o.LoadProperty <Act>("TargetAct").TypeConceptKey == ObservationTypeKeys.Severity);

            if (severity != null)
            {
                retVal.Seriousness = DataTypeConverter.ToFhirCodeableConcept(severity.LoadProperty <CodedObservation>("TargetAct").Value, "http://hl7.org/fhir/adverse-event-seriousness");
            }

            // Did the patient die?
            var causeOfDeath = model.LoadCollection <ActRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.IsCauseOf && o.LoadProperty <Act>("TargetAct").TypeConceptKey == ObservationTypeKeys.ClinicalState && (o.TargetAct as CodedObservation)?.ValueKey == Guid.Parse("6df3720b-857f-4ba2-826f-b7f1d3c3adbb"));

            if (causeOfDeath != null)
            {
                retVal.Outcome = new MARC.HI.EHRS.SVC.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/adverse-event-outcome"), "fatal");
            }
            else if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Outcome = new MARC.HI.EHRS.SVC.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/adverse-event-outcome"), "ongoing");
            }
            else if (model.StatusConceptKey == StatusKeys.Completed)
            {
                retVal.Outcome = new MARC.HI.EHRS.SVC.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/adverse-event-outcome"), "resolved");
            }

            var author = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Authororiginator);

            if (author != null)
            {
                retVal.Recorder = DataTypeConverter.CreatePlainReference <Practitioner>(author.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            // Suspect entities
            var refersTo = model.LoadCollection <ActRelationship>("Relationships").Where(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.RefersTo);

            if (refersTo.Count() > 0)
            {
                retVal.SuspectEntity = refersTo.Select(o => o.LoadProperty <Act>("TargetAct")).OfType <SubstanceAdministration>().Select(o =>
                {
                    var consumable = o.LoadCollection <ActParticipation>("Participations").FirstOrDefault(x => x.ParticipationRoleKey == ActParticipationKey.Consumable)?.LoadProperty <ManufacturedMaterial>("PlayerEntity");
                    if (consumable == null)
                    {
                        var product = o.LoadCollection <ActParticipation>("Participations").FirstOrDefault(x => x.ParticipationRoleKey == ActParticipationKey.Product)?.LoadProperty <Material>("PlayerEntity");
                        return(new AdverseEventSuspectEntity()
                        {
                            Instance = DataTypeConverter.CreatePlainReference <Substance>(product, webOperationContext)
                        });
                    }
                    else
                    {
                        return new AdverseEventSuspectEntity()
                        {
                            Instance = DataTypeConverter.CreatePlainReference <Medication>(consumable, webOperationContext)
                        }
                    };
                }).ToList();
            }

            return(retVal);
        }
        /// <summary>
        /// Maps the outbound resource to FHIR.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override ImmunizationRecommendation MapToFhir(SubstanceAdministration model, WebOperationContext webOperationContext)
        {
            ImmunizationRecommendation retVal = new ImmunizationRecommendation();

            retVal.Id         = model.Key.ToString();
            retVal.Timestamp  = DateTime.Now;
            retVal.Identifier = model.Identifiers.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            var rct = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget).PlayerEntity;

            if (rct != null)
            {
                retVal.Patient = Reference.CreateResourceReference(new Patient()
                {
                    Id = model.Key.ToString(), VersionId = model.VersionKey.ToString()
                }, WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri);
            }

            var mat = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Product).PlayerEntity;

            // Recommend
            string status         = (model.StopTime ?? model.ActTime) < DateTimeOffset.Now ? "overdue" : "due";
            var    recommendation = new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.ImmunizationRecommendation()
            {
                Date           = model.CreationTime.DateTime,
                DoseNumber     = model.SequenceId,
                VaccineCode    = DataTypeConverter.ToFhirCodeableConcept(mat?.TypeConcept),
                ForecastStatus = new FhirCodeableConcept(new Uri("http://hl7.org/fhir/conceptset/immunization-recommendation-status"), status),
                DateCriterion  = new List <MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.ImmunizationRecommendationDateCriterion>()
                {
                    new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.ImmunizationRecommendationDateCriterion()
                    {
                        Code  = new FhirCodeableConcept(new Uri("http://hl7.org/fhir/conceptset/immunization-recommendation-date-criterion"), "recommended"),
                        Value = model.ActTime.DateTime
                    }
                }
            };

            if (model.StartTime.HasValue)
            {
                recommendation.DateCriterion.Add(new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.ImmunizationRecommendationDateCriterion()
                {
                    Code  = new FhirCodeableConcept(new Uri("http://hl7.org/fhir/conceptset/immunization-recommendation-date-criterion"), "earliest"),
                    Value = model.StartTime.Value.DateTime
                });
            }
            if (model.StopTime.HasValue)
            {
                recommendation.DateCriterion.Add(new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.ImmunizationRecommendationDateCriterion()
                {
                    Code  = new FhirCodeableConcept(new Uri("http://hl7.org/fhir/conceptset/immunization-recommendation-date-criterion"), "overdue"),
                    Value = model.StopTime.Value.DateTime
                });
            }

            retVal.Recommendation = new List <MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.ImmunizationRecommendation>()
            {
                recommendation
            };
            return(retVal);
        }
예제 #12
0
        /// <summary>
        /// Map a patient object to FHIR.
        /// </summary>
        /// <param name="model">The patient to map to FHIR</param>
        /// <param name="restOperationContext">The current REST operation context</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override Patient MapToFhir(Core.Model.Roles.Patient model, RestOperationContext restOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Patient>(model);

            retVal.Active    = model.StatusConceptKey == StatusKeys.Active;
            retVal.Address   = model.LoadCollection <EntityAddress>("Addresses").Select(o => DataTypeConverter.ToFhirAddress(o)).ToList();
            retVal.BirthDate = model.DateOfBirth;
            retVal.Deceased  = model.DeceasedDate == DateTime.MinValue ? (object)new FhirBoolean(true) : model.DeceasedDate != null ? new FhirDate(model.DeceasedDate.Value) : null;
            retVal.Gender    = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("GenderConcept"), "http://hl7.org/fhir/administrative-gender")?.GetPrimaryCode()?.Code;

            retVal.Identifier    = model.Identifiers?.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();
            retVal.MultipleBirth = model.MultipleBirthOrder == 0 ? (FhirElement) new FhirBoolean(true) : model.MultipleBirthOrder.HasValue ? new FhirInt(model.MultipleBirthOrder.Value) : null;
            retVal.Name          = model.LoadCollection <EntityName>("Names").Select(o => DataTypeConverter.ToFhirHumanName(o)).ToList();
            retVal.Timestamp     = model.ModifiedOn.DateTime;
            retVal.Telecom       = model.LoadCollection <EntityTelecomAddress>("Telecoms").Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();

            // TODO: Relationships
            foreach (var rel in model.LoadCollection <EntityRelationship>("Relationships").Where(o => !o.InversionIndicator))
            {
                // Family member
                if (rel.LoadProperty <Concept>(nameof(EntityRelationship.RelationshipType)).ConceptSetsXml.Contains(ConceptSetKeys.FamilyMember))
                {
                    // Create the relative object
                    var relative = DataTypeConverter.CreateResource <RelatedPerson>(rel.LoadProperty <Person>(nameof(EntityRelationship.TargetEntity)));
                    relative.Relationship = DataTypeConverter.ToFhirCodeableConcept(rel.LoadProperty <Concept>(nameof(EntityRelationship.RelationshipType)));
                    relative.Address      = DataTypeConverter.ToFhirAddress(rel.TargetEntity.Addresses.FirstOrDefault());
                    relative.Gender       = DataTypeConverter.ToFhirCodeableConcept((rel.TargetEntity as Core.Model.Roles.Patient)?.LoadProperty <Concept>(nameof(Core.Model.Roles.Patient.GenderConcept)));
                    relative.Identifier   = rel.TargetEntity.LoadCollection <EntityIdentifier>(nameof(Entity.Identifiers)).Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();
                    relative.Name         = DataTypeConverter.ToFhirHumanName(rel.TargetEntity.LoadCollection <EntityName>(nameof(Entity.Names)).FirstOrDefault());
                    if (rel.TargetEntity is Core.Model.Roles.Patient)
                    {
                        relative.Patient = DataTypeConverter.CreateReference <Patient>(rel.TargetEntity, restOperationContext);
                    }
                    relative.Telecom = rel.TargetEntity.LoadCollection <EntityTelecomAddress>(nameof(Entity.Telecoms)).Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();
                    retVal.Contained.Add(new ContainedResource()
                    {
                        Item = relative
                    });
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.HealthcareProvider)
                {
                    retVal.Provider = DataTypeConverter.CreateReference <Practitioner>(rel.LoadProperty <Entity>(nameof(EntityRelationship.TargetEntity)), restOperationContext);
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.Replaces)
                {
                    retVal.Link.Add(new PatientLink()
                    {
                        Type  = PatientLinkType.Replace,
                        Other = Reference.CreateLocalResourceReference(rel.LoadProperty <Patient>(nameof(EntityRelationship.TargetEntity)))
                    });
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.Duplicate)
                {
                    retVal.Link.Add(new PatientLink()
                    {
                        Type  = PatientLinkType.SeeAlso,
                        Other = Reference.CreateLocalResourceReference(rel.LoadProperty <Patient>(nameof(EntityRelationship.TargetEntity)))
                    });
                }
                else if (rel.RelationshipTypeKey?.ToString() == "97730a52-7e30-4dcd-94cd-fd532d111578") // MDM Master Record
                {
                    if (rel.SourceEntityKey != model.Key)
                    {
                        retVal.Link.Add(new PatientLink() // Is a master
                        {
                            Type  = PatientLinkType.SeeAlso,
                            Other = Reference.CreateLocalResourceReference(rel.LoadProperty <Patient>(nameof(EntityRelationship.SourceEntity)))
                        });
                    }
                    else // Is a local
                    {
                        retVal.Link.Add(new PatientLink()
                        {
                            Type  = PatientLinkType.Refer,
                            Other = Reference.CreateLocalResourceReference(rel.LoadProperty <Patient>(nameof(EntityRelationship.TargetEntity)))
                        });
                    }
                }
            }

            var photo = model.LoadCollection <EntityExtension>("Extensions").FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.JpegPhotoExtension);

            if (photo != null)
            {
                retVal.Photo = new List <Attachment>()
                {
                    new Attachment()
                    {
                        ContentType = "image/jpg",
                        Data        = photo.ExtensionValueXml
                    }
                }
            }
            ;

            // TODO: Links
            return(retVal);
        }
예제 #13
0
        /// <summary>
        /// Map the inbound place to a FHIR model
        /// </summary>
        protected override Location MapToFhir(Place model)
        {
            Location retVal = DataTypeConverter.CreateResource <Location>(model);

            retVal.Identifier = model.LoadCollection <EntityIdentifier>("Identifiers").Select(o => DataTypeConverter.ToFhirIdentifier <Entity>(o)).ToList();

            // Map status
            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.Active:
            case StatusKeyStrings.New:
                retVal.Status = Location.LocationStatus.Active;
                break;

            case StatusKeyStrings.Cancelled:
                retVal.Status = Location.LocationStatus.Suspended;
                break;

            case StatusKeyStrings.Nullified:
            case StatusKeyStrings.Obsolete:
            case StatusKeyStrings.Inactive:
                retVal.Status = Location.LocationStatus.Inactive;
                break;
            }

            retVal.Name  = model.LoadCollection <EntityName>("Names").FirstOrDefault(o => o.NameUseKey == NameUseKeys.OfficialRecord)?.LoadCollection <EntityNameComponent>("Component")?.FirstOrDefault()?.Value;
            retVal.Alias = model.LoadCollection <EntityName>("Names").Where(o => o.NameUseKey != NameUseKeys.OfficialRecord)?.Select(n => n.LoadCollection <EntityNameComponent>("Component")?.FirstOrDefault()?.Value).ToList();

            // Convert the determiner code
            if (model.DeterminerConceptKey == DeterminerKeys.Described)
            {
                retVal.Mode = Location.LocationMode.Kind;
            }
            else
            {
                retVal.Mode = Location.LocationMode.Instance;
            }

            retVal.Type = new List <CodeableConcept>()
            {
                DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey, "http://hl7.org/fhir/ValueSet/v3-ServiceDeliveryLocationRoleType")
            };
            retVal.Telecom = model.LoadCollection <EntityTelecomAddress>("Telecoms").Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();
            retVal.Address = DataTypeConverter.ToFhirAddress(model.LoadCollection <EntityAddress>("Addresses").FirstOrDefault());

            if (model.GeoTag != null)
            {
                retVal.Position = new Location.PositionComponent()
                {
                    Latitude  = (decimal)model.GeoTag.Lat,
                    Longitude = (decimal)model.GeoTag.Lng
                }
            }
            ;

            // Part of?
            var parent = model.LoadCollection <EntityRelationship>(nameof(Entity.Relationships)).FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Parent);

            if (parent != null)
            {
                retVal.PartOf = DataTypeConverter.CreateVersionedReference <Location>(parent.LoadProperty <Entity>(nameof(EntityRelationship.TargetEntity)));
            }

            return(retVal);
        }
        /// <summary>
        /// Map to FHIR
        /// </summary>
        protected override Observation MapToFhir(Core.Model.Acts.Observation model)
        {
            var retVal = DataTypeConverter.CreateResource <Observation>(model);

            retVal.Identifier = model.LoadCollection <ActIdentifier>(nameof(Act.Identifiers)).Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.New:
            case StatusKeyStrings.Active:
                retVal.Status = ObservationStatus.Preliminary;
                break;

            case StatusKeyStrings.Cancelled:
                retVal.Status = ObservationStatus.Cancelled;
                break;

            case StatusKeyStrings.Nullified:
                retVal.Status = ObservationStatus.EnteredInError;
                break;

            case StatusKeyStrings.Completed:
                if (model.LoadCollection <ActRelationship>(nameof(Act.Relationships)).Any(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.Replaces))    // was amended
                {
                    retVal.Status = ObservationStatus.Amended;
                }
                else
                {
                    retVal.Status = ObservationStatus.Final;
                }

                break;

            case StatusKeyStrings.Obsolete:
                retVal.Status = ObservationStatus.Unknown;
                break;
            }

            if (model.StartTime.HasValue || model.StopTime.HasValue)
            {
                retVal.Effective = DataTypeConverter.ToPeriod(model.StartTime, model.StopTime);
            }
            else
            {
                retVal.Effective = DataTypeConverter.ToFhirDateTime(model.ActTime);
            }

            retVal.Code = DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey);

            // RCT
            var rct = model.LoadCollection <ActParticipation>(nameof(Act.Participations)).FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (rct != null)
            {
                retVal.Subject = DataTypeConverter.CreateNonVersionedReference <Patient>(rct.LoadProperty <Entity>(nameof(ActParticipation.PlayerEntity)));
            }

            // Performer
            retVal.Performer = model.Participations.Where(o => o.ParticipationRoleKey == ActParticipationKey.Performer)
                               .Select(o => DataTypeConverter.CreateNonVersionedReference <Practitioner>(o.LoadProperty <Entity>(nameof(ActParticipation.PlayerEntity))))
                               .ToList();

            retVal.Issued = model.CreationTime;

            // Value
            switch (model.ValueType)
            {
            case "CD":
                retVal.Value = DataTypeConverter.ToFhirCodeableConcept((model as CodedObservation).ValueKey);
                break;

            case "PQ":
                var qty = model as QuantityObservation;
                retVal.Value = DataTypeConverter.ToQuantity(qty.Value, qty.UnitOfMeasureKey);
                break;

            case "ED":
            case "ST":
                retVal.Value = new FhirString((model as TextObservation).Value);
                break;
            }

            if (model.InterpretationConceptKey.HasValue)
            {
                retVal.Interpretation = new List <CodeableConcept>
                {
                    DataTypeConverter.ToFhirCodeableConcept(model.InterpretationConceptKey)
                };
            }

            return(retVal);
        }
예제 #15
0
        /// <summary>
        /// Maps the object to model to fhir
        /// </summary>
        protected override MedicationAdministration MapToFhir(SubstanceAdministration model, WebOperationContext webOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <MedicationAdministration>(model);

            retVal.Identifier = model.LoadCollection <ActIdentifier>("Identifiers").Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Status = MedicationAdministrationStatus.InProgress;
            }
            else if (model.StatusConceptKey == StatusKeys.Completed)
            {
                retVal.Status = MedicationAdministrationStatus.Completed;
            }
            else if (model.StatusConceptKey == StatusKeys.Nullified)
            {
                retVal.Status = MedicationAdministrationStatus.EnteredInError;
            }
            else if (model.StatusConceptKey == StatusKeys.Cancelled)
            {
                retVal.Status = MedicationAdministrationStatus.Stopped;
            }

            retVal.Category = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"), "http://hl7.org/fhir/medication-admin-category");

            var consumableRelationship = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Consumable);
            var productRelationship    = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Product);

            if (consumableRelationship != null)
            {
                retVal.Medication = DataTypeConverter.CreateReference <Medication>(consumableRelationship.LoadProperty <ManufacturedMaterial>("PlayerEntity"), webOperationContext);
            }
            else if (productRelationship != null)
            {
                retVal.Medication = DataTypeConverter.CreateReference <Substance>(productRelationship.LoadProperty <Material>("PlayerEntity"), webOperationContext);
                //retVal.Medication = DataTypeConverter.ToFhirCodeableConcept(productRelationship.LoadProperty<Material>("PlayerEntity").LoadProperty<Concept>("TypeConcept"));
            }

            var rct = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (rct != null)
            {
                retVal.Subject = DataTypeConverter.CreateReference <Patient>(rct.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            // Encounter
            var erService = ApplicationContext.Current.GetService <IDataPersistenceService <EntityRelationship> >();
            int tr        = 0;
            var enc       = erService.Query(o => o.TargetEntityKey == model.Key && o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent, 0, 1, AuthenticationContext.Current.Principal, out tr).FirstOrDefault();

            if (enc != null)
            {
                // TODO: Encounter
            }

            // Effective time
            retVal.EffectiveDate = model.ActTime.DateTime;

            // performer
            var performer = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Performer) ??
                            model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Authororiginator);

            if (performer != null)
            {
                retVal.Performer = new List <MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.MedicationPerformer>()
                {
                    new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.MedicationPerformer()
                    {
                        Actor = DataTypeConverter.CreateReference <Practitioner>(performer.LoadProperty <Entity>("PlayerEntity"), webOperationContext)
                    }
                }
            }
            ;

            // Not given
            retVal.NotGiven = model.IsNegated;
            if (model.ReasonConceptKey.HasValue && model.IsNegated)
            {
                retVal.ReasonNotGiven = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("ReasonConcept"));
            }
            else if (model.ReasonConceptKey.HasValue)
            {
                retVal.ReasonCode = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("ReasonConcept"));
            }

            retVal.Dosage = new MARC.HI.EHRS.SVC.Messaging.FHIR.Backbone.MedicationDosage()
            {
                Site  = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("Site")),
                Route = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("Route")),
                Dose  = new MARC.HI.EHRS.SVC.Messaging.FHIR.DataTypes.FhirQuantity()
                {
                    Value = model.DoseQuantity,
                    Units = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("DoseUnit"), "http://hl7.org/fhir/sid/ucum").GetPrimaryCode()?.Code?.Value
                }
            };

            return(retVal);
        }
예제 #16
0
        /// <summary>
        /// Maps the substance administration to FHIR.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override Immunization MapToFhir(SubstanceAdministration model, WebOperationContext webOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Immunization>(model);

            retVal.DoseQuantity = new FhirQuantity()
            {
                Units = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("DoseUnit"), "http://hl7.org/fhir/sid/ucum").GetPrimaryCode()?.Code?.Value,
                Value = new FhirDecimal(model.DoseQuantity)
            };
            retVal.Date   = (FhirDate)model.ActTime.DateTime;
            retVal.Route  = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>(nameof(SubstanceAdministration.Route)));
            retVal.Site   = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>(nameof(SubstanceAdministration.Site)));
            retVal.Status = "completed";
            //retVal.SelfReported = model.Tags.Any(o => o.TagKey == "selfReported" && Convert.ToBoolean(o.Value));
            retVal.WasNotGiven = model.IsNegated;

            // Material
            var matPtcpt = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Consumable) ??
                           model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Product);

            if (matPtcpt != null)
            {
                var matl = matPtcpt.LoadProperty <Material>(nameof(ActParticipation.PlayerEntity));
                retVal.VaccineCode    = DataTypeConverter.ToFhirCodeableConcept(matl.LoadProperty <Concept>(nameof(Act.TypeConcept)));
                retVal.ExpirationDate = matl.ExpiryDate.HasValue ? (FhirDate)matl.ExpiryDate : null;
                retVal.LotNumber      = (matl as ManufacturedMaterial)?.LotNumber;
            }
            else
            {
                retVal.ExpirationDate = null;
            }

            // RCT
            var rct = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (rct != null)
            {
                retVal.Patient = DataTypeConverter.CreateReference <Patient>(rct.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            // Performer
            var prf = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Performer);

            if (prf != null)
            {
                retVal.Performer = DataTypeConverter.CreateReference <Practitioner>(rct.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            // Protocol
            foreach (var itm in model.Protocols)
            {
                ImmunizationProtocol protocol = new ImmunizationProtocol();
                var dbProtocol = itm.LoadProperty <Protocol>(nameof(ActProtocol.Protocol));
                protocol.DoseSequence = new FhirInt((int)model.SequenceId);

                // Protocol lookup
                protocol.Series = dbProtocol?.Name;
                retVal.VaccinationProtocol.Add(protocol);
            }
            if (retVal.VaccinationProtocol.Count == 0)
            {
                retVal.VaccinationProtocol.Add(new ImmunizationProtocol()
                {
                    DoseSequence = (int)model.SequenceId
                });
            }

            var loc = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Location);

            if (loc != null)
            {
                retVal.Extension.Add(new Extension()
                {
                    Url   = "http://openiz.org/extensions/act/fhir/location",
                    Value = new FhirString(loc.PlayerEntityKey.ToString())
                });
            }

            return(retVal);
        }
        /// <summary>
        /// Map the specified patient encounter to a FHIR based encounter
        /// </summary>
        protected override Encounter MapToFhir(PatientEncounter model, RestOperationContext restOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Encounter>(model);

            // Map the identifier
            retVal.Identifier = model.LoadCollection <ActIdentifier>("Identifiers").Select(o => DataTypeConverter.ToFhirIdentifier <Act>(o)).ToList();

            // Map status keys
            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.Active:
                retVal.Status = EncounterStatus.InProgress;
                break;

            case StatusKeyStrings.Cancelled:
            case StatusKeyStrings.Nullified:
                retVal.Status = EncounterStatus.Cancelled;
                break;

            case StatusKeyStrings.Completed:
                retVal.Status = EncounterStatus.Finished;
                break;
            }

            if (model.StartTime.HasValue || model.StopTime.HasValue)
            {
                retVal.Period = new FhirPeriod()
                {
                    Start = model.StartTime?.DateTime,
                    Stop  = model.StopTime?.DateTime
                }
            }
            ;
            else
            {
                retVal.Period = new FhirPeriod()
                {
                    Start = model.ActTime.DateTime,
                    Stop  = model.ActTime.DateTime
                }
            };

            retVal.Reason = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("ReasonConcept"));
            retVal.Type   = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"));

            // Map associated
            var associated = model.LoadCollection <ActParticipation>("Participations");

            // Subject of encounter
            retVal.Subject = DataTypeConverter.CreateReference <SanteDB.Messaging.FHIR.Resources.Patient>(associated.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget)?.LoadProperty <Entity>("PlayerEntity"), restOperationContext);

            // Locations
            retVal.Location = associated.Where(o => o.LoadProperty <Entity>("PlayerEntity") is Place).Select(o => new EncounterLocation()
            {
                Period = new FhirPeriod()
                {
                    Start = model.CreationTime.DateTime
                },
                Location = DataTypeConverter.CreateReference <Location>(o.PlayerEntity, restOperationContext)
            }).ToList();

            // Service provider
            var cst = associated.FirstOrDefault(o => o.LoadProperty <Entity>("PlayerEntity") is Core.Model.Entities.Organization && o.ParticipationRoleKey == ActParticipationKey.Custodian);

            if (cst != null)
            {
                retVal.ServiceProvider = DataTypeConverter.CreateReference <SanteDB.Messaging.FHIR.Resources.Organization>(cst.PlayerEntity, restOperationContext);
            }

            // Participants
            retVal.Participant = associated.Where(o => o.LoadProperty <Entity>("PlayerEntity") is Provider || o.LoadProperty <Entity>("PlayerEntity") is UserEntity).Select(o => new EncounterParticipant()
            {
                Period = new FhirPeriod()
                {
                    Start = model.CreationTime.DateTime
                },
                Type = new List <FhirCodeableConcept>()
                {
                    DataTypeConverter.ToFhirCodeableConcept(o.LoadProperty <Concept>("ParticipationRole"))
                },
                Individual = DataTypeConverter.CreateReference <Practitioner>(o.PlayerEntity, restOperationContext)
            }).ToList();


            return(retVal);
        }
예제 #18
0
        /// <summary>
        /// Map to FHIR
        /// </summary>
        protected override Condition MapToFhir(CodedObservation model, WebOperationContext webOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Condition>(model);

            retVal.Identifier = model.LoadCollection <ActIdentifier>("Identifiers").Select(o => DataTypeConverter.ToFhirIdentifier <Act>(o)).ToList();

            // Clinical status of the condition
            if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.ClinicalStatus = ConditionClinicalStatus.Active;
            }
            else if (model.StatusConceptKey == StatusKeys.Completed)
            {
                retVal.ClinicalStatus = ConditionClinicalStatus.Resolved;
            }
            else if (model.StatusConceptKey == StatusKeys.Nullified)
            {
                retVal.VerificationStatus = ConditionVerificationStatus.EnteredInError;
            }
            else if (model.StatusConceptKey == StatusKeys.Obsolete)
            {
                retVal.ClinicalStatus = ConditionClinicalStatus.Inactive;
            }

            // Category
            retVal.Category.Add(new MARC.HI.EHRS.SVC.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/condition-category"), "encounter-diagnosis"));

            // Severity?
            var actRelationshipService = ApplicationContext.Current.GetService <IDataPersistenceService <ActRelationship> >();

            var severity = actRelationshipService.Query(o => o.SourceEntityKey == model.Key && o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent && o.TargetAct.TypeConceptKey == ObservationTypeKeys.Severity, AuthenticationContext.Current.Principal);

            if (severity == null)             // Perhaps we should get from neighbor if this is in an encounter
            {
                var contextAct = actRelationshipService.Query(o => o.TargetActKey == model.Key, AuthenticationContext.Current.Principal).FirstOrDefault();
                if (contextAct != null)
                {
                    severity = actRelationshipService.Query(o => o.SourceEntityKey == contextAct.SourceEntityKey && o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent && o.TargetAct.TypeConceptKey == ObservationTypeKeys.Severity, AuthenticationContext.Current.Principal);
                }
            }

            // Severity
            if (severity != null)
            {
                retVal.Severity = DataTypeConverter.ToFhirCodeableConcept((severity as CodedObservation).LoadProperty <Concept>("Value"));
            }

            retVal.Code = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("Value"));

            // body sites?
            var sites = actRelationshipService.Query(o => o.SourceEntityKey == model.Key && o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent && o.TargetAct.TypeConceptKey == ObservationTypeKeys.FindingSite, AuthenticationContext.Current.Principal);

            retVal.BodySite = sites.Select(o => DataTypeConverter.ToFhirCodeableConcept(o.LoadProperty <CodedObservation>("TargetAct").LoadProperty <Concept>("Value"))).ToList();

            // Subject
            var recordTarget = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (recordTarget != null)
            {
                this.traceSource.TraceInformation("RCT: {0}", recordTarget.PlayerEntityKey);
                retVal.Subject = DataTypeConverter.CreateReference <Patient>(recordTarget.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }
            // Onset
            if (model.StartTime.HasValue || model.StopTime.HasValue)
            {
                retVal.Onset = new FhirPeriod()
                {
                    Start = model.StartTime?.DateTime,
                    Stop  = model.StopTime?.DateTime
                }
            }
            ;
            else
            {
                retVal.Onset = new FhirDateTime(model.ActTime.DateTime);
            }

            retVal.AssertionDate = model.CreationTime.LocalDateTime;
            var author = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Authororiginator);

            if (author != null)
            {
                retVal.Asserter = DataTypeConverter.CreatePlainReference <Practitioner>(author.LoadProperty <Entity>("PlayerEntity"), webOperationContext);
            }

            return(retVal);
        }
예제 #19
0
        /// <summary>
        /// Map the specified patient encounter to a FHIR based encounter
        /// </summary>
        protected override Encounter MapToFhir(PatientEncounter model)
        {
            var retVal = DataTypeConverter.CreateResource <Encounter>(model);

            // Map the identifier
            retVal.Identifier = model.LoadCollection <ActIdentifier>("Identifiers").Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();

            // Map status keys
            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.Active:
            case StatusKeyStrings.New:
                switch (model.MoodConceptKey.ToString().ToUpper())
                {
                case MoodConceptKeyStrings.Eventoccurrence:
                case MoodConceptKeyStrings.Request:
                    retVal.Status = Encounter.EncounterStatus.InProgress;
                    break;

                case MoodConceptKeyStrings.Intent:
                case MoodConceptKeyStrings.Promise:
                    retVal.Status = Encounter.EncounterStatus.Planned;
                    break;
                }

                break;

            case StatusKeyStrings.Cancelled:
                retVal.Status = Encounter.EncounterStatus.Cancelled;
                break;

            case StatusKeyStrings.Nullified:
                retVal.Status = Encounter.EncounterStatus.EnteredInError;
                break;

            case StatusKeyStrings.Obsolete:
                retVal.Status = Encounter.EncounterStatus.Unknown;
                break;

            case StatusKeyStrings.Completed:
                retVal.Status = Encounter.EncounterStatus.Finished;
                break;
            }

            if (model.StartTime.HasValue || model.StopTime.HasValue)
            {
                retVal.Period = DataTypeConverter.ToPeriod(model.StartTime, model.StopTime);
            }
            else
            {
                retVal.Period = DataTypeConverter.ToPeriod(model.ActTime, model.ActTime);
            }

            retVal.ReasonCode = new List <CodeableConcept>
            {
                DataTypeConverter.ToFhirCodeableConcept(model.ReasonConceptKey)
            };

            retVal.Class = DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey).GetCoding();

            // Map associated
            var associated = model.LoadCollection <ActParticipation>("Participations").ToArray();

            // Subject of encounter
            retVal.Subject = DataTypeConverter.CreateNonVersionedReference <Patient>(associated.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget)?.LoadProperty <Entity>("PlayerEntity"));

            // Locations
            retVal.Location = associated.Where(o => o.LoadProperty <Entity>("PlayerEntity") is Place).Select(o => new Encounter.LocationComponent
            {
                Period   = DataTypeConverter.ToPeriod(model.CreationTime, null),
                Location = DataTypeConverter.CreateVersionedReference <Location>(o.PlayerEntity)
            }).ToList();

            // Service provider
            var cst = associated.FirstOrDefault(o => o.LoadProperty <Entity>("PlayerEntity") is Organization && o.ParticipationRoleKey == ActParticipationKey.Custodian);

            if (cst != null)
            {
                retVal.ServiceProvider = DataTypeConverter.CreateVersionedReference <Hl7.Fhir.Model.Organization>(cst.PlayerEntity);
            }

            // Participants
            retVal.Participant = associated.Where(o => o.LoadProperty <Entity>("PlayerEntity") is Provider || o.LoadProperty <Entity>("PlayerEntity") is UserEntity).Select(o => new Encounter.ParticipantComponent
            {
                Type = new List <CodeableConcept>
                {
                    DataTypeConverter.ToFhirCodeableConcept(o.ParticipationRoleKey)
                },
                Individual = DataTypeConverter.CreateVersionedReference <Practitioner>(o.PlayerEntity)
            }).ToList();

            return(retVal);
        }
        /// <inheritdoc/>
        protected override AdverseEvent MapToFhir(Act model)
        {
            var retVal = DataTypeConverter.CreateResource <AdverseEvent>(model);

            retVal.Identifier = DataTypeConverter.ToFhirIdentifier(model.Identifiers.FirstOrDefault());
            retVal.Category   = new List <CodeableConcept>
            {
                DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey)
            };

            var recordTarget = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (recordTarget != null)
            {
                retVal.Subject = DataTypeConverter.CreateVersionedReference <Patient>(recordTarget.LoadProperty <Entity>("PlayerEntity"));
            }

            // Main topic of the concern
            var subject = model.LoadCollection <ActRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.HasSubject)?.LoadProperty <Act>("TargetAct");

            if (subject == null)
            {
                throw new InvalidOperationException(this.m_localizationService.GetString("error.messaging.fhir.adverseEvent.act"));
            }

            retVal.DateElement = new FhirDateTime(subject.ActTime);

            // Reactions = HasManifestation
            var reactions = subject.LoadCollection <ActRelationship>("Relationships").Where(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.HasManifestation).FirstOrDefault();

            if (reactions != null)
            {
                retVal.Event = DataTypeConverter.ToFhirCodeableConcept(reactions.LoadProperty <CodedObservation>("TargetAct").ValueKey);
            }

            var location = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Location);

            if (location != null)
            {
                retVal.Location = DataTypeConverter.CreateVersionedReference <Location>(location.LoadProperty <Entity>("PlayerEntity"));
            }

            // Severity
            var severity = subject.LoadCollection <ActRelationship>("Relationships").First(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent && o.LoadProperty <Act>("TargetAct").TypeConceptKey == ObservationTypeKeys.Severity);

            if (severity != null)
            {
                retVal.Severity = DataTypeConverter.ToFhirCodeableConcept(severity.LoadProperty <CodedObservation>("TargetAct").ValueKey, "http://terminology.hl7.org/CodeSystem/adverse-event-severity");
            }

            // Did the patient die?
            var causeOfDeath = model.LoadCollection <ActRelationship>("Relationships").FirstOrDefault(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.IsCauseOf && o.LoadProperty <Act>("TargetAct").TypeConceptKey == ObservationTypeKeys.ClinicalState && (o.TargetAct as CodedObservation)?.ValueKey == Guid.Parse("6df3720b-857f-4ba2-826f-b7f1d3c3adbb"));

            if (causeOfDeath != null)
            {
                retVal.Outcome = new CodeableConcept("http://hl7.org/fhir/adverse-event-outcome", "fatal");
            }
            else if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Outcome = new CodeableConcept("http://hl7.org/fhir/adverse-event-outcome", "ongoing");
            }
            else if (model.StatusConceptKey == StatusKeys.Completed)
            {
                retVal.Outcome = new CodeableConcept("http://hl7.org/fhir/adverse-event-outcome", "resolved");
            }

            var author = model.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Authororiginator);

            if (author != null)
            {
                retVal.Recorder = DataTypeConverter.CreateNonVersionedReference <Practitioner>(author.LoadProperty <Entity>("PlayerEntity"));
            }

            // Suspect entities
            var refersTo = model.LoadCollection <ActRelationship>("Relationships").Where(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.RefersTo).ToArray();

            if (refersTo.Any())
            {
                retVal.SuspectEntity = refersTo.Select(o => o.LoadProperty <Act>("TargetAct")).OfType <SubstanceAdministration>().Select(o =>
                {
                    var consumable = o.LoadCollection <ActParticipation>("Participations").FirstOrDefault(x => x.ParticipationRoleKey == ActParticipationKey.Consumable)?.LoadProperty <ManufacturedMaterial>("PlayerEntity");
                    if (consumable == null)
                    {
                        var product = o.LoadCollection <ActParticipation>("Participations").FirstOrDefault(x => x.ParticipationRoleKey == ActParticipationKey.Product)?.LoadProperty <Material>("PlayerEntity");

                        return(new AdverseEvent.SuspectEntityComponent
                        {
                            Instance = DataTypeConverter.CreateNonVersionedReference <Substance>(product)
                        });
                    }

                    return(new AdverseEvent.SuspectEntityComponent
                    {
                        Instance = DataTypeConverter.CreateNonVersionedReference <Medication>(consumable)
                    });
                }).ToList();
            }

            return(retVal);
        }
예제 #21
0
        /// <summary>
        /// Map to FHIR
        /// </summary>
        protected override MARC.HI.EHRS.SVC.Messaging.FHIR.Resources.Observation MapToFhir(Core.Model.Acts.Observation model, WebOperationContext webOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <MARC.HI.EHRS.SVC.Messaging.FHIR.Resources.Observation>(model);

            retVal.EffectiveDateTime = (FhirDate)model.ActTime.DateTime;

            retVal.Code = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("TypeConcept"));
            if (model.StatusConceptKey == StatusKeys.Completed)
            {
                retVal.Status = new FhirCode <ObservationStatus>(ObservationStatus.Final);
            }
            else if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Status = new FhirCode <ObservationStatus>(ObservationStatus.Preliminary);
            }
            else if (model.StatusConceptKey == StatusKeys.Nullified)
            {
                retVal.Status = new FhirCode <ObservationStatus>(ObservationStatus.EnteredInError);
            }

            if (model.Relationships.Any(o => o.RelationshipTypeKey == ActRelationshipTypeKeys.Replaces))
            {
                retVal.Status = new FhirCode <ObservationStatus>(ObservationStatus.Corrected);
            }

            // RCT
            var rct = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (rct != null)
            {
                retVal.Subject = Reference.CreateResourceReference(new Patient()
                {
                    Id = rct.PlayerEntityKey.ToString()
                }, webOperationContext.IncomingRequest.UriTemplateMatch.BaseUri);
            }

            // Performer
            var prf = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Performer);

            if (prf != null)
            {
                retVal.Performer = Reference.CreateResourceReference(new Practitioner()
                {
                    Id = rct.PlayerEntityKey.ToString()
                }, webOperationContext.IncomingRequest.UriTemplateMatch.BaseUri);
            }

            retVal.Issued = new FhirInstant()
            {
                DateValue = model.CreationTime.DateTime
            };

            // Value
            switch (model.ValueType)
            {
            case "CD":
                retVal.Value = DataTypeConverter.ToFhirCodeableConcept((model as Core.Model.Acts.CodedObservation).Value);
                break;

            case "PQ":
                retVal.Value = new FhirQuantity()
                {
                    Value = (model as Core.Model.Acts.QuantityObservation).Value,
                    Units = DataTypeConverter.ToFhirCodeableConcept((model as Core.Model.Acts.QuantityObservation).LoadProperty <Concept>("UnitOfMeasure"), "http://hl7.org/fhir/sid/ucum").GetPrimaryCode()?.Code?.Value
                };
                break;

            case "ED":
            case "ST":
                retVal.Value = new FhirString((model as Core.Model.Acts.TextObservation).Value);
                break;
            }

            var loc = model.Participations.FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Location);

            if (loc != null)
            {
                retVal.Extension.Add(new Extension()
                {
                    Url   = "http://openiz.org/extensions/act/fhir/location",
                    Value = new FhirString(loc.PlayerEntityKey.ToString())
                });
            }

            return(retVal);
        }
        /// <summary>
        /// Maps the object to model to fhir
        /// </summary>
        protected override MedicationAdministration MapToFhir(SubstanceAdministration model)
        {
            var retVal = DataTypeConverter.CreateResource <MedicationAdministration>(model);

            retVal.Identifier   = model.LoadCollection <ActIdentifier>(nameof(Act.Identifiers)).Select(DataTypeConverter.ToFhirIdentifier).ToList();
            retVal.StatusReason = new List <CodeableConcept> {
                DataTypeConverter.ToFhirCodeableConcept(model.ReasonConceptKey)
            };

            switch (model.StatusConceptKey.ToString().ToUpper())
            {
            case StatusKeyStrings.Active:
                retVal.Status = MedicationAdministration.MedicationAdministrationStatusCodes.InProgress;
                break;

            case StatusKeyStrings.Cancelled:
                retVal.Status = MedicationAdministration.MedicationAdministrationStatusCodes.Stopped;
                break;

            case StatusKeyStrings.Nullified:
                retVal.Status = MedicationAdministration.MedicationAdministrationStatusCodes.EnteredInError;
                break;

            case StatusKeyStrings.Completed:
                retVal.Status = MedicationAdministration.MedicationAdministrationStatusCodes.Completed;
                break;

            case StatusKeyStrings.Obsolete:
                retVal.Status = MedicationAdministration.MedicationAdministrationStatusCodes.Unknown;
                break;
            }

            if (model.IsNegated)
            {
                retVal.Status = MedicationAdministration.MedicationAdministrationStatusCodes.NotDone;
            }

            retVal.Category = DataTypeConverter.ToFhirCodeableConcept(model.TypeConceptKey, "http://hl7.org/fhir/medication-admin-category");

            var consumableRelationship = model.LoadCollection <ActParticipation>(nameof(Act.Participations)).FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Consumable);
            var productRelationship    = model.LoadCollection <ActParticipation>(nameof(Act.Participations)).FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Product);

            if (consumableRelationship != null)
            {
                retVal.Medication = DataTypeConverter.CreateVersionedReference <Medication>(consumableRelationship.LoadProperty <ManufacturedMaterial>("PlayerEntity"));
            }
            else if (productRelationship != null)
            {
                retVal.Medication = DataTypeConverter.CreateVersionedReference <Substance>(productRelationship.LoadProperty <Material>("PlayerEntity"));
                //retVal.Medication = DataTypeConverter.ToFhirCodeableConcept(productRelationship.LoadProperty<Material>("PlayerEntity").LoadProperty<Concept>("TypeConcept"));
            }

            var rct = model.LoadCollection <ActParticipation>(nameof(Act.Participations)).FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.RecordTarget);

            if (rct != null)
            {
                retVal.Subject = DataTypeConverter.CreateVersionedReference <Patient>(rct.LoadProperty <Entity>("PlayerEntity"));
            }

            // Encounter
            var erService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <EntityRelationship> >();
            var tr        = 0;
            var enc       = erService.Query(o => o.TargetEntityKey == model.Key && o.RelationshipTypeKey == ActRelationshipTypeKeys.HasComponent && o.ObsoleteVersionSequenceId == null, 0, 10, out tr, AuthenticationContext.Current.Principal);

            if (enc != null)
            {
                retVal.EventHistory = enc.Select(o => DataTypeConverter.CreateNonVersionedReference <Encounter>(o.TargetEntityKey)).ToList();
                // TODO: Encounter
            }

            // Effective time
            retVal.Effective = DataTypeConverter.ToPeriod(model.StartTime ?? model.ActTime, model.StopTime);

            // performer
            var performer = model.LoadCollection <ActParticipation>(nameof(Act.Participations)).Where(o => o.ParticipationRoleKey == ActParticipationKey.Performer || o.ParticipationRoleKey == ActParticipationKey.Authororiginator);

            retVal.Performer = performer.Select(o => new MedicationAdministration.PerformerComponent
            {
                Actor = DataTypeConverter.CreateVersionedReference <Practitioner>(o.LoadProperty <Entity>(nameof(ActParticipation.PlayerEntity)))
            }).ToList();


            retVal.Dosage = new MedicationAdministration.DosageComponent
            {
                Site  = DataTypeConverter.ToFhirCodeableConcept(model.SiteKey),
                Route = DataTypeConverter.ToFhirCodeableConcept(model.RouteKey),
                Dose  = new Quantity
                {
                    Value = model.DoseQuantity,
                    Unit  = DataTypeConverter.ToFhirCodeableConcept(model.DoseUnitKey, "http://hl7.org/fhir/sid/ucum").GetCoding()?.Code
                }
            };

            return(retVal);
        }
예제 #23
0
        /// <summary>
        /// Map a patient object to FHIR.
        /// </summary>
        /// <param name="model">The patient to map to FHIR</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override Patient MapToFhir(Core.Model.Roles.Patient model)
        {
            // If the model is being constructed as part of a bundle, then the caller
            // should have included the bundle so we can add any related resources
            var partOfBundle = model.GetAnnotations <Bundle>().FirstOrDefault();

            var retVal = DataTypeConverter.CreateResource <Patient>(model);

            retVal.Active  = StatusKeys.ActiveStates.Contains(model.StatusConceptKey.Value);
            retVal.Address = model.GetAddresses().Select(DataTypeConverter.ToFhirAddress).ToList();

            if (model.DateOfBirth.HasValue)
            {
                switch (model.DateOfBirthPrecision.GetValueOrDefault())
                {
                case DatePrecision.Day:
                    retVal.BirthDate = model.DateOfBirth.Value.ToString("yyyy-MM-dd");
                    break;

                case DatePrecision.Month:
                    retVal.BirthDate = model.DateOfBirth.Value.ToString("yyyy-MM");
                    break;

                case DatePrecision.Year:
                    retVal.BirthDate = model.DateOfBirth.Value.ToString("yyyy");
                    break;
                }
            }

            // Deceased precision
            if (model.DeceasedDate.HasValue)
            {
                if (model.DeceasedDate == DateTime.MinValue)
                {
                    retVal.Deceased = new FhirBoolean(true);
                }
                else
                {
                    switch (model.DeceasedDatePrecision)
                    {
                    case DatePrecision.Day:
                        retVal.Deceased = new FhirDateTime(model.DeceasedDate.Value.Year, model.DeceasedDate.Value.Month, model.DeceasedDate.Value.Day);
                        break;

                    case DatePrecision.Month:
                        retVal.Deceased = new FhirDateTime(model.DeceasedDate.Value.Year, model.DeceasedDate.Value.Month);
                        break;

                    case DatePrecision.Year:
                        retVal.Deceased = new FhirDateTime(model.DeceasedDate.Value.Year);
                        break;

                    default:
                        retVal.Deceased = DataTypeConverter.ToFhirDateTime(model.DeceasedDate);
                        break;
                    }
                }
            }

            if (model.GenderConceptKey.HasValue)
            {
                retVal.Gender = DataTypeConverter.ToFhirEnumeration <AdministrativeGender>(model.GenderConceptKey, "http://hl7.org/fhir/administrative-gender", true);
            }

            retVal.Identifier    = model.Identifiers?.Select(DataTypeConverter.ToFhirIdentifier).ToList();
            retVal.MultipleBirth = model.MultipleBirthOrder == 0 ? (DataType) new FhirBoolean(true) : model.MultipleBirthOrder.HasValue ? new Integer(model.MultipleBirthOrder.Value) : null;
            retVal.Name          = model.GetNames().Select(DataTypeConverter.ToFhirHumanName).ToList();
            retVal.Telecom       = model.GetTelecoms().Select(DataTypeConverter.ToFhirTelecom).ToList();
            retVal.Communication = model.GetPersonLanguages().Select(DataTypeConverter.ToFhirCommunicationComponent).ToList();

            foreach (var rel in model.GetRelationships().Where(o => !o.InversionIndicator))
            {
                if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.Contact)
                {
                    var relEntity = rel.LoadProperty(o => o.TargetEntity);

                    if (relEntity is Core.Model.Entities.Person person)
                    {
                        var contact = new Patient.ContactComponent()
                        {
                            ElementId    = $"{person.Key}",
                            Address      = DataTypeConverter.ToFhirAddress(person.GetAddresses().FirstOrDefault()),
                            Relationship = new List <CodeableConcept>()
                            {
                                DataTypeConverter.ToFhirCodeableConcept(rel.RelationshipRoleKey, "http://terminology.hl7.org/CodeSystem/v2-0131"),
                                DataTypeConverter.ToFhirCodeableConcept(rel.RelationshipTypeKey, "http://terminology.hl7.org/CodeSystem/v2-0131")
                            }.OfType <CodeableConcept>().ToList(),
                            Name = DataTypeConverter.ToFhirHumanName(person.GetNames().FirstOrDefault()),
                            // TODO: Gender
                            Gender  = DataTypeConverter.ToFhirEnumeration <AdministrativeGender>(person.GenderConceptKey, "http://hl7.org/fhir/administrative-gender"),
                            Telecom = person.GetTelecoms().Select(t => DataTypeConverter.ToFhirTelecom(t)).ToList()
                        };

                        var scoper = person.LoadCollection(o => o.Relationships).FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Scoper);
                        if (scoper != null)
                        {
                            contact.Organization = DataTypeConverter.CreateNonVersionedReference <Hl7.Fhir.Model.Organization>(scoper.LoadProperty(o => o.TargetEntity));
                        }
                        DataTypeConverter.AddExtensions(person, contact);
                        retVal.Contact.Add(contact);
                    }
                    else if (relEntity is Core.Model.Entities.Organization org) // it *IS* an organization
                    {
                        var contact = new Patient.ContactComponent()
                        {
                            ElementId    = $"{org.Key}",
                            Relationship = new List <CodeableConcept>()
                            {
                                DataTypeConverter.ToFhirCodeableConcept(rel.RelationshipRoleKey, "http://terminology.hl7.org/CodeSystem/v2-0131"),
                                DataTypeConverter.ToFhirCodeableConcept(rel.RelationshipTypeKey, "http://terminology.hl7.org/CodeSystem/v2-0131")
                            }.OfType <CodeableConcept>().ToList(),
                            Organization = DataTypeConverter.CreateNonVersionedReference <Hl7.Fhir.Model.Organization>(org)
                        };
                        retVal.Contact.Add(contact);
                    }
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.Scoper)
                {
                    var scoper = rel.LoadProperty(o => o.TargetEntity);

                    retVal.ManagingOrganization = DataTypeConverter.CreateNonVersionedReference <Hl7.Fhir.Model.Organization>(scoper);

                    // If this is part of a bundle, include it
                    partOfBundle?.Entry.Add(new Bundle.EntryComponent
                    {
                        FullUrl  = $"{MessageUtil.GetBaseUri()}/Organization/{scoper.Key}",
                        Resource = FhirResourceHandlerUtil.GetMapperForInstance(scoper).MapToFhir(scoper)
                    });
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.HealthcareProvider)
                {
                    var practitioner = rel.LoadProperty(o => o.TargetEntity);

                    retVal.GeneralPractitioner.Add(DataTypeConverter.CreateVersionedReference <Practitioner>(practitioner));

                    // If this is part of a bundle, include it
                    partOfBundle?.Entry.Add(new Bundle.EntryComponent
                    {
                        FullUrl  = $"{MessageUtil.GetBaseUri()}/Practitioner/{practitioner.Key}",
                        Resource = FhirResourceHandlerUtil.GetMapperForInstance(practitioner).MapToFhir(practitioner)
                    });
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.Replaces)
                {
                    retVal.Link.Add(this.CreateLink <Patient>(rel.TargetEntityKey.Value, Patient.LinkType.Replaces));
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.Duplicate)
                {
                    retVal.Link.Add(this.CreateLink <Patient>(rel.TargetEntityKey.Value, Patient.LinkType.Seealso));
                }
                else if (rel.RelationshipTypeKey == MDM_MASTER_LINK) // HACK: MDM Master Record
                {
                    if (rel.SourceEntityKey.HasValue && rel.SourceEntityKey != model.Key)
                    {
                        retVal.Link.Add(this.CreateLink <Patient>(rel.SourceEntityKey.Value, Patient.LinkType.Seealso));
                    }
                    else // Is a local
                    {
                        retVal.Link.Add(this.CreateLink <Patient>(rel.TargetEntityKey.Value, Patient.LinkType.Refer));
                    }
                }
                else if (rel.ClassificationKey == EntityRelationshipTypeKeys.EquivalentEntity)
                {
                    retVal.Link.Add(this.CreateLink <Patient>(rel.TargetEntityKey.Value, Patient.LinkType.Refer));
                }
                else if (partOfBundle != null) // This is part of a bundle and we need to include it
                {
                    // HACK: This piece of code is used to add any RelatedPersons to the container bundle if it is part of a bundle
                    if (this.GetRelatedPersonConceptUuids().Contains(rel.RelationshipTypeKey.Value))
                    {
                        var relative = FhirResourceHandlerUtil.GetMapperForInstance(rel).MapToFhir(rel);
                        partOfBundle.Entry.Add(new Bundle.EntryComponent()
                        {
                            FullUrl  = $"{MessageUtil.GetBaseUri()}/RelatedPerson/{rel.Key}",
                            Resource = relative
                        });
                    }
                }
            }

            // Reverse relationships of family member?
            var uuids = model.Relationships.Where(r => r.RelationshipTypeKey == MDM_MASTER_LINK).Select(r => r.SourceEntityKey).Union(new Guid?[] { model.Key }).ToArray();
            var familyMemberConcepts = this.GetFamilyMemberUuids();
            var reverseRelationships = this.m_erRepository.Find(o => uuids.Contains(o.TargetEntityKey) && familyMemberConcepts.Contains(o.RelationshipTypeKey.Value) && o.ObsoleteVersionSequenceId == null);

            foreach (var rrv in reverseRelationships)
            {
                retVal.Link.Add(new Patient.LinkComponent
                {
                    Type  = Patient.LinkType.Seealso,
                    Other = DataTypeConverter.CreateNonVersionedReference <RelatedPerson>(rrv)
                });

                // If this is part of a bundle, include it
                partOfBundle?.Entry.Add(new Bundle.EntryComponent
                {
                    FullUrl  = $"{MessageUtil.GetBaseUri()}/RelatedPerson/{rrv.Key}",
                    Resource = FhirResourceHandlerUtil.GetMappersFor(ResourceType.RelatedPerson).First().MapToFhir(rrv)
                });
            }

            // Was this record replaced?
            if (!retVal.Active.GetValueOrDefault())
            {
                var replacedRelationships = this.m_erRepository.Find(o => uuids.Contains(o.TargetEntityKey) && o.RelationshipTypeKey == EntityRelationshipTypeKeys.Replaces && o.ObsoleteVersionSequenceId == null);

                foreach (var repl in replacedRelationships)
                {
                    retVal.Link.Add(new Patient.LinkComponent()
                    {
                        Type  = Patient.LinkType.ReplacedBy,
                        Other = DataTypeConverter.CreateNonVersionedReference <Patient>(repl.LoadProperty(o => o.SourceEntity)),
                    });
                }
            }

            var photo = model.LoadCollection(o => o.Extensions).FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.JpegPhotoExtension);

            if (photo != null)
            {
                retVal.Photo = new List <Attachment>
                {
                    new Attachment
                    {
                        ContentType = "image/jpg",
                        Data        = photo.ExtensionValueXml
                    }
                };
            }

            return(retVal);
        }
예제 #24
0
        /// <summary>
        /// Map a patient object to FHIR.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override Patient MapToFhir(Core.Model.Roles.Patient model, WebOperationContext webOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <Patient>(model);

            retVal.Active        = model.StatusConceptKey == StatusKeys.Active;
            retVal.Address       = model.Addresses.Select(o => DataTypeConverter.ToFhirAddress(o)).ToList();
            retVal.BirthDate     = model.DateOfBirth;
            retVal.Deceased      = model.DeceasedDate == DateTime.MinValue ? (object)new FhirBoolean(true) : model.DeceasedDate != null ? new FhirDate(model.DeceasedDate.Value) : null;
            retVal.Gender        = DataTypeConverter.ToFhirCodeableConcept(model.GenderConcept)?.GetPrimaryCode()?.Code;
            retVal.Identifier    = model.Identifiers?.Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();
            retVal.MultipleBirth = model.MultipleBirthOrder == 0 ? (FhirElement) new FhirBoolean(true) : model.MultipleBirthOrder.HasValue ? new FhirInt(model.MultipleBirthOrder.Value) : null;
            retVal.Name          = model.Names.Select(o => DataTypeConverter.ToFhirHumanName(o)).ToList();
            retVal.Timestamp     = model.ModifiedOn.DateTime;
            retVal.Telecom       = model.Telecoms.Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();

            // TODO: Relationships
            foreach (var rel in model.LoadCollection <EntityRelationship>("Relationships").Where(o => !o.InversionIndicator))
            {
                // Family member
                if (rel.LoadProperty <Concept>(nameof(EntityRelationship.RelationshipType)).ConceptSetsXml.Contains(ConceptSetKeys.FamilyMember))
                {
                    // Create the relative object
                    var relative = DataTypeConverter.CreateResource <RelatedPerson>(rel.LoadProperty <Person>(nameof(EntityRelationship.TargetEntity)));
                    relative.Relationship = DataTypeConverter.ToFhirCodeableConcept(rel.LoadProperty <Concept>(nameof(EntityRelationship.RelationshipType)));
                    relative.Address      = DataTypeConverter.ToFhirAddress(rel.TargetEntity.Addresses.FirstOrDefault());
                    relative.Gender       = DataTypeConverter.ToFhirCodeableConcept((rel.TargetEntity as Core.Model.Roles.Patient)?.LoadProperty <Concept>(nameof(Core.Model.Roles.Patient.GenderConcept)));
                    relative.Identifier   = rel.TargetEntity.LoadCollection <EntityIdentifier>(nameof(Entity.Identifiers)).Select(o => DataTypeConverter.ToFhirIdentifier(o)).ToList();
                    relative.Name         = DataTypeConverter.ToFhirHumanName(rel.TargetEntity.LoadCollection <EntityName>(nameof(Entity.Names)).FirstOrDefault());
                    if (rel.TargetEntity is Core.Model.Roles.Patient)
                    {
                        relative.Patient = DataTypeConverter.CreateReference <Patient>(rel.TargetEntity, webOperationContext);
                    }
                    relative.Telecom = rel.TargetEntity.LoadCollection <EntityTelecomAddress>(nameof(Entity.Telecoms)).Select(o => DataTypeConverter.ToFhirTelecom(o)).ToList();
                    retVal.Contained.Add(new ContainedResource()
                    {
                        Item = relative
                    });
                }
                else if (rel.RelationshipTypeKey == EntityRelationshipTypeKeys.HealthcareProvider)
                {
                    retVal.Provider = DataTypeConverter.CreateReference <Practitioner>(rel.LoadProperty <Entity>(nameof(EntityRelationship.TargetEntity)), webOperationContext);
                }
            }

            var photo = model.LoadCollection <EntityExtension>("Extensions").FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.JpegPhotoExtension);

            if (photo != null)
            {
                retVal.Photo = new List <Attachment>()
                {
                    new Attachment()
                    {
                        ContentType = "image/jpg",
                        Data        = photo.ExtensionValueXml
                    }
                }
            }
            ;

            // TODO: Links
            return(retVal);
        }