コード例 #1
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);
        }
コード例 #2
0
        /// <summary>
        /// Map to FHIR
        /// </summary>
        protected override SanteDB.Messaging.FHIR.Resources.Observation MapToFhir(Core.Model.Acts.Observation model, RestOperationContext restOperationContext)
        {
            var retVal = DataTypeConverter.CreateResource <SanteDB.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()
                }, restOperationContext.IncomingRequest.Url);
            }

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

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

            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.LoadCollection <ActParticipation>("Participations").FirstOrDefault(o => o.ParticipationRoleKey == ActParticipationKey.Location);

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

            if (model.InterpretationConceptKey.HasValue)
            {
                retVal.Interpretation = DataTypeConverter.ToFhirCodeableConcept(model.LoadProperty <Concept>("InterpretationConcept"));
            }


            return(retVal);
        }
コード例 #3
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);
        }
コード例 #4
0
 /// <summary>
 /// Maps the specified <paramref name="resource"/> to the model type <see cref="ManufacturedMaterial"/>
 /// </summary>
 /// <param name="resource">The model resource to be mapped</param>
 /// <param name="restOperationContext">The operation context this request is executing on</param>
 /// <returns>The converted <see cref="ManufacturedMaterial"/></returns>
 protected override ManufacturedMaterial MapToModel(Medication resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #5
0
 /// <summary>
 /// Maps a OpenIZ bundle as FHIR
 /// </summary>
 protected override SanteDB.Messaging.FHIR.Resources.Bundle MapToFhir(Core.Model.Collection.Bundle model, RestOperationContext webOperationContext)
 {
     return(new SanteDB.Messaging.FHIR.Resources.Bundle()
     {
         Type = BundleType.Collection,
         // TODO: Actually construct a response bundle
     });
 }
コード例 #6
0
 /// <summary>
 /// Map adverse events to the model
 /// </summary>
 protected override Act MapToModel(AdverseEvent resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #7
0
 /// <summary>
 /// Map to FHIR
 /// </summary>
 protected override SanteDB.Messaging.FHIR.Resources.Organization MapToFhir(Core.Model.Entities.Organization model, RestOperationContext webOperationContext)
 {
     return(DataTypeConverter.CreateResource <SanteDB.Messaging.FHIR.Resources.Organization>(model));
 }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
 /// <summary>
 /// Maps a model instance to a FHIR instance.
 /// </summary>
 /// <param name="model">The model.</param>
 /// <param name="restOperationContext">The operation context the method is being called on</param>
 /// <returns>Returns the mapped FHIR resource.</returns>
 protected abstract TFhirResource MapToFhir(TModel model, RestOperationContext restOperationContext);
コード例 #10
0
        /// <summary>
        /// Map to FHIR
        /// </summary>
        protected override Condition MapToFhir(CodedObservation model, RestOperationContext restOperationContext)
        {
            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 SanteDB.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/condition-category"), "encounter-diagnosis"));

            // Severity?
            var actRelationshipService = ApplicationServiceContext.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.TraceInfo("RCT: {0}", recordTarget.PlayerEntityKey);
                retVal.Subject = DataTypeConverter.CreateReference <Patient>(recordTarget.LoadProperty <Entity>("PlayerEntity"), restOperationContext);
            }
            // 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"), restOperationContext);
            }

            return(retVal);
        }
コード例 #11
0
 /// <summary>
 /// Maps a FHIR condition to a model
 /// </summary>
 /// <param name="resource">The FHIR condition to be mapped</param>
 /// <param name="restOperationContext">The REST operation context under which this method is called</param>
 /// <returns>The constructed model instance</returns>
 protected override CodedObservation MapToModel(Condition resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #12
0
 /// <summary>
 /// Map allergy intolerance from FHIR to a coded observation
 /// </summary>
 protected override CodedObservation MapToModel(AllergyIntolerance resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #13
0
 /// <summary>
 /// Map coded allergy intolerance resource to FHIR
 /// </summary>
 protected override AllergyIntolerance MapToFhir(CodedObservation model, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #14
0
        /// <summary>
        /// Maps the substance administration to FHIR.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="restOperationContext">The operation context in which this method is being called</param>
        /// <returns>Returns the mapped FHIR resource.</returns>
        protected override Immunization MapToFhir(SubstanceAdministration model, RestOperationContext restOperationContext)
        {
            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"), restOperationContext);
            }

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

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

            // 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://santedb.org/extensions/act/fhir/location",
                    Value = new FhirString(loc.PlayerEntityKey.ToString())
                });
            }

            return(retVal);
        }
コード例 #15
0
        /// <summary>
        /// Map an immunization FHIR resource to a substance administration.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <param name="restOperationContext">The operation context in which this method is being called</param>
        /// <returns>Returns the mapped model.</returns>
        protected override SubstanceAdministration MapToModel(Immunization resource, RestOperationContext restOperationContext)
        {
            var substanceAdministration = new SubstanceAdministration
            {
                ActTime      = resource.Date.DateValue.Value,
                DoseQuantity = resource.DoseQuantity?.Value.Value ?? 0,
                DoseUnit     = resource.DoseQuantity != null?DataTypeConverter.ToConcept <String>(resource.DoseQuantity.Units.Value, "http://hl7.org/fhir/sid/ucum") : null,
                                   Extensions       = resource.Extension?.Select(DataTypeConverter.ToActExtension).ToList(),
                                   Identifiers      = resource.Identifier?.Select(DataTypeConverter.ToActIdentifier).ToList(),
                                   Key              = Guid.NewGuid(),
                                   MoodConceptKey   = ActMoodKeys.Eventoccurrence,
                                   StatusConceptKey = resource.Status == "completed" ? StatusKeys.Completed : StatusKeys.Nullified,
                                   RouteKey         = DataTypeConverter.ToConcept(resource.Route)?.Key,
                                   SiteKey          = DataTypeConverter.ToConcept(resource.Site)?.Key,
            };


            Guid key;

            if (Guid.TryParse(resource.Id, out key))
            {
                substanceAdministration.Key = key;
            }

            // Was not given
            if (resource.WasNotGiven?.Value == true)
            {
                substanceAdministration.IsNegated = true;
            }

            // Patient
            if (resource.Patient != null)
            {
                // Is the subject a uuid
                if (resource.Patient.ReferenceUrl.Value.StartsWith("urn:uuid:"))
                {
                    substanceAdministration.Participations.Add(new ActParticipation(ActParticipationKey.RecordTarget, Guid.Parse(resource.Patient.ReferenceUrl.Value.Substring(9))));
                }
                else
                {
                    throw new NotSupportedException("Only UUID references are supported");
                }
            }

            // Encounter
            if (resource.Encounter != null)
            {
                // Is the subject a uuid
                if (resource.Encounter.ReferenceUrl.Value.StartsWith("urn:uuid:"))
                {
                    substanceAdministration.Relationships.Add(new ActRelationship(ActRelationshipTypeKeys.HasComponent, substanceAdministration.Key)
                    {
                        SourceEntityKey = Guid.Parse(resource.Encounter.ReferenceUrl.Value.Substring(9))
                    });
                }
                else
                {
                    throw new NotSupportedException("Only UUID references are supported");
                }
            }

            // Find the material that was issued
            if (resource.VaccineCode != null)
            {
                var concept = DataTypeConverter.ToConcept(resource.VaccineCode);
                if (concept == null)
                {
                    this.traceSource.TraceWarning("Ignoring administration {0} don't have concept mapped", resource.VaccineCode);
                    return(null);
                }
                // Get the material
                int t        = 0;
                var material = ApplicationServiceContext.Current.GetService <IRepositoryService <Material> >().Find(m => m.TypeConceptKey == concept.Key, 0, 1, out t).FirstOrDefault();
                if (material == null)
                {
                    this.traceSource.TraceWarning("Ignoring administration {0} don't have material registered for {1}", resource.VaccineCode, concept?.Mnemonic);
                    return(null);
                }
                else
                {
                    substanceAdministration.Participations.Add(new ActParticipation(ActParticipationKey.Product, material.Key));
                    if (resource.LotNumber != null)
                    {
                        // TODO: Need to also find where the GTIN is kept
                        var mmaterial = ApplicationServiceContext.Current.GetService <IRepositoryService <ManufacturedMaterial> >().Find(o => o.LotNumber == resource.LotNumber && o.Relationships.Any(r => r.SourceEntityKey == material.Key && r.RelationshipTypeKey == EntityRelationshipTypeKeys.Instance));
                        substanceAdministration.Participations.Add(new ActParticipation(ActParticipationKey.Consumable, material.Key)
                        {
                            Quantity = 1
                        });
                    }

                    // Get dose units
                    if (substanceAdministration.DoseQuantity == 0)
                    {
                        substanceAdministration.DoseQuantity = 1;
                        substanceAdministration.DoseUnitKey  = material.QuantityConceptKey;
                    }
                }
            }

            return(substanceAdministration);
        }
コード例 #16
0
        /// <summary>
        /// Map to model the encounter
        /// </summary>
        protected override PatientEncounter MapToModel(Encounter resource, RestOperationContext webOperationContext)
        {
            // Organization
            var status = resource.Status?.Value;
            var retVal = new PatientEncounter()
            {
                TypeConcept = DataTypeConverter.ToConcept(resource.Class, new Uri("http://openiz.org/conceptset/v3-ActEncounterCode")),
                StartTime   = resource.Period?.Start?.DateValue,
                StopTime    = resource.Period?.Stop?.DateValue,
                // TODO: Extensions
                Extensions       = resource.Extension.Select(DataTypeConverter.ToActExtension).OfType <ActExtension>().ToList(),
                Identifiers      = resource.Identifier.Select(DataTypeConverter.ToActIdentifier).ToList(),
                Key              = Guid.NewGuid(),
                StatusConceptKey = status == EncounterStatus.Finished ? StatusKeys.Completed :
                                   status == EncounterStatus.Cancelled ? StatusKeys.Cancelled :
                                   status == EncounterStatus.InProgress || status == EncounterStatus.Arrived ? StatusKeys.Active :
                                   status == EncounterStatus.Planned ? StatusKeys.Active : StatusKeys.Obsolete,
                MoodConceptKey = status == EncounterStatus.Planned ? ActMoodKeys.Intent : ActMoodKeys.Eventoccurrence,
                ReasonConcept  = DataTypeConverter.ToConcept(resource.Reason)
            };

            // Parse key
            Guid key;

            if (!Guid.TryParse(resource.Id, out key))
            {
                key = Guid.NewGuid();
            }
            retVal.Key = key;

            // Attempt to resolve relationships
            if (resource.Subject != null)
            {
                // Is the subject a uuid
                if (resource.Subject.ReferenceUrl.Value.StartsWith("urn:uuid:"))
                {
                    retVal.Participations.Add(new ActParticipation(ActParticipationKey.RecordTarget, Guid.Parse(resource.Subject.ReferenceUrl.Value.Substring(9))));
                }
                else
                {
                    throw new NotSupportedException("Only UUID references are supported");
                }
            }

            // Attempt to resolve organiztaion
            if (resource.ServiceProvider != null)
            {
                // Is the subject a uuid
                if (resource.ServiceProvider.ReferenceUrl.Value.StartsWith("urn:uuid:"))
                {
                    retVal.Participations.Add(new ActParticipation(ActParticipationKey.Custodian, Guid.Parse(resource.ServiceProvider.ReferenceUrl.Value.Substring(9))));
                }
                else
                {
                    throw new NotSupportedException("Only UUID references are supported");
                }
            }

            // TODO : Other Participations
            return(retVal);
        }
コード例 #17
0
 /// <summary>
 /// Map to model
 /// </summary>
 public IdentifiedData MapToModel(BundleEntry bundleResource, RestOperationContext context, Bundle bundle)
 {
     return(this.MapToModel(bundleResource.Resource.Resource as Encounter, context));
 }
コード例 #18
0
 /// <summary>
 /// Maps a FHIR resource to a model instance.
 /// </summary>
 /// <param name="resource">The resource.</param>
 /// <param name="restOperationContext">The operation context on which the operation is being called.</param>
 /// <returns>Returns the mapped model.</returns>
 protected abstract TModel MapToModel(TFhirResource resource, RestOperationContext restOperationContext);
コード例 #19
0
 /// <summary>
 /// Map to model
 /// </summary>
 public IdentifiedData MapToModel(BundleEntry bundleResource, RestOperationContext context, Bundle bundle)
 {
     return(this.MapToModel(bundleResource.Resource.Resource as SanteDB.Messaging.FHIR.Resources.Organization, context));
 }
コード例 #20
0
 /// <summary>
 /// Map a practitioner to a user entity
 /// </summary>
 protected override UserEntity MapToModel(Practitioner resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #21
0
        /// <summary>
        /// Map to Model
        /// </summary>
        protected override Core.Model.Entities.Organization MapToModel(SanteDB.Messaging.FHIR.Resources.Organization resource, RestOperationContext webOperationContext)
        {
            // Organization
            var retVal = new Core.Model.Entities.Organization()
            {
                TypeConcept  = DataTypeConverter.ToConcept(resource.Type),
                Addresses    = resource.Address.Select(DataTypeConverter.ToEntityAddress).ToList(),
                CreationTime = DateTimeOffset.Now,
                // TODO: Extensions
                Extensions  = resource.Extension.Select(DataTypeConverter.ToEntityExtension).OfType <EntityExtension>().ToList(),
                Identifiers = resource.Identifier.Select(DataTypeConverter.ToEntityIdentifier).ToList(),
                Key         = Guid.NewGuid(),
                Names       = new List <EntityName>()
                {
                    new EntityName(NameUseKeys.OfficialRecord, resource.Name)
                },
                StatusConceptKey = resource.Active?.Value == true ? StatusKeys.Active : StatusKeys.Obsolete,
                Telecoms         = resource.Telecom.Select(DataTypeConverter.ToEntityTelecomAddress).ToList()
            };

            Guid key;

            if (!Guid.TryParse(resource.Id, out key))
            {
                key = Guid.NewGuid();
            }

            retVal.Key = key;

            return(retVal);
        }
コード例 #22
0
 /// <summary>
 /// Maps a FHIR resource to a model instance.
 /// </summary>
 /// <param name="resource">The resource.</param>
 /// <returns>Returns the mapped model.</returns>
 /// <exception cref="System.NotImplementedException"></exception>
 protected override SubstanceAdministration MapToModel(ImmunizationRecommendation resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #23
0
        /// <summary>
        /// Maps the specified act to an adverse event
        /// </summary>
        protected override AdverseEvent MapToFhir(Act model, RestOperationContext restOperationContext)
        {
            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"), restOperationContext);
            }

            // 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"), restOperationContext)).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"), restOperationContext);
            }

            // 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 SanteDB.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/adverse-event-outcome"), "fatal");
            }
            else if (model.StatusConceptKey == StatusKeys.Active)
            {
                retVal.Outcome = new SanteDB.Messaging.FHIR.DataTypes.FhirCodeableConcept(new Uri("http://hl7.org/fhir/adverse-event-outcome"), "ongoing");
            }
            else if (model.StatusConceptKey == StatusKeys.Completed)
            {
                retVal.Outcome = new SanteDB.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"), restOperationContext);
            }

            // 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, restOperationContext)
                        });
                    }
                    else
                    {
                        return new AdverseEventSuspectEntity()
                        {
                            Instance = DataTypeConverter.CreatePlainReference <Medication>(consumable, restOperationContext)
                        }
                    };
                }).ToList();
            }

            return(retVal);
        }
コード例 #24
0
        /// <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, RestOperationContext restOperationContext)
        {
            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()
                }, RestOperationContext.Current.IncomingRequest.Url);
            }

            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 SanteDB.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 <SanteDB.Messaging.FHIR.Backbone.ImmunizationRecommendationDateCriterion>()
                {
                    new SanteDB.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 SanteDB.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 SanteDB.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 <SanteDB.Messaging.FHIR.Backbone.ImmunizationRecommendation>()
            {
                recommendation
            };
            return(retVal);
        }
コード例 #25
0
        /// <summary>
        /// Map FHIR resource to our bundle
        /// </summary>
        protected override Core.Model.Collection.Bundle MapToModel(SanteDB.Messaging.FHIR.Resources.Bundle resource, RestOperationContext webOperationContext)
        {
            var retVal = new Core.Model.Collection.Bundle();

            foreach (var entry in resource.Entry)
            {
                var entryType = entry.Resource.Resource?.GetType();
                if (entryType == null)
                {
                    continue;
                }
                var handler = FhirResourceHandlerUtil.GetResourceHandler(entryType.GetCustomAttribute <XmlRootAttribute>().ElementName) as IBundleResourceHandler;
                if (handler == null)
                {
                    this.traceSource.TraceWarning("Can't find bundle handler for {0}...", entryType.Name);
                    continue;
                }
                retVal.Add(handler.MapToModel(entry, webOperationContext, resource));
            }
            retVal.Item.RemoveAll(o => o == null);
            return(retVal);
        }
コード例 #26
0
        /// <summary>
        /// Creates a FHIR reference.
        /// </summary>
        /// <typeparam name="TResource">The type of the t resource.</typeparam>
        /// <param name="targetEntity">The target entity.</param>
        /// <returns>Returns a reference instance.</returns>
        public static Reference <TResource> CreateReference <TResource>(IVersionedEntity targetEntity, RestOperationContext context) where TResource : DomainResourceBase, new()
        {
            if (targetEntity == null)
            {
                throw new ArgumentNullException(nameof(targetEntity));
            }
            else if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var refer = Reference.CreateResourceReference(DataTypeConverter.CreateResource <TResource>(targetEntity), context.IncomingRequest.Url);

            refer.Display = (targetEntity as Entity)?.Names?.FirstOrDefault()?.ToString();
            return(refer);
        }
コード例 #27
0
 /// <summary>
 /// Map the incoming FHIR reosurce to a MODEL resource
 /// </summary>
 /// <param name="resource">The resource to be mapped</param>
 /// <param name="restOperationContext">The operation context under which this method is being called</param>
 /// <returns></returns>
 protected override Place MapToModel(Location resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #28
0
        /// <summary>
        /// Creates a FHIR reference.
        /// </summary>
        /// <typeparam name="TResource">The type of the t resource.</typeparam>
        /// <param name="targetEntity">The target entity.</param>
        /// <returns>Returns a reference instance.</returns>
        public static Reference CreatePlainReference <TResource>(IVersionedEntity targetEntity, RestOperationContext context) where TResource : DomainResourceBase, new()
        {
            var refer = Reference.CreateResourceReference((DomainResourceBase)DataTypeConverter.CreateResource <TResource>(targetEntity), context.IncomingRequest.Url);

            refer.Display = (targetEntity as Entity)?.Names?.FirstOrDefault()?.ToString();
            return(refer);
        }
コード例 #29
0
 /// <summary>
 /// Maps a FHIR based resource to a model based resource
 /// </summary>
 /// <param name="resource">The resource to be mapped</param>
 /// <param name="restOperationContext">The operation context under which this method is being called</param>
 /// <returns>The mapped material</returns>
 protected override Material MapToModel(Substance resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }
コード例 #30
0
 /// <summary>
 /// Map to model
 /// </summary>
 protected override Core.Model.Acts.Observation MapToModel(SanteDB.Messaging.FHIR.Resources.Observation resource, RestOperationContext restOperationContext)
 {
     throw new NotImplementedException();
 }