// BundleToEventStream takes a bundle of resources and converts them to an EventStream. Currently only a // limited set of resource types are supported, with unsupported resource types resulting in an error. If // the bundle contains more than one patient, this is also considered an error. func BundleToEventStream(bundle *models.Bundle) (es *plugin.EventStream, err error) { var patient *models.Patient events := make([]plugin.Event, 0, len(bundle.Entry)) for _, entry := range bundle.Entry { switch r := entry.Resource.(type) { default: err = fmt.Errorf("Unsupported: Converting %s to Event", reflect.TypeOf(r).Elem().Name()) return case *models.Patient: if patient != nil { err = errors.New("Found more than one patient in resources") return } patient = r case *models.Condition: if r.VerificationStatus != "confirmed" { continue } if onset, err := findDate(false, r.OnsetDateTime, r.OnsetPeriod, r.DateRecorded); err == nil { events = append(events, plugin.Event{Date: onset, Type: "Condition", End: false, Value: r}) } if abatement, err := findDate(true, r.AbatementDateTime, r.AbatementPeriod); err == nil { events = append(events, plugin.Event{Date: abatement, Type: "Condition", End: true, Value: r}) } // TODO: What happens if there is no date at all? case *models.MedicationStatement: if r.Status == "" || r.Status == "entered-in-error" { continue } if active, err := findDate(false, r.EffectiveDateTime, r.EffectivePeriod, r.DateAsserted); err == nil { events = append(events, plugin.Event{Date: active, Type: "MedicationStatement", End: false, Value: r}) } if inactive, err := findDate(true, r.EffectivePeriod); err == nil { events = append(events, plugin.Event{Date: inactive, Type: "MedicationStatement", End: true, Value: r}) } // TODO: What happens if there is no date at all? case *models.Observation: if r.Status != "final" && r.Status != "amended" && r.Status != "preliminary" && r.Status != "registered" { continue } if effective, err := findDate(false, r.EffectiveDateTime, r.EffectivePeriod, r.Issued); err == nil { events = append(events, plugin.Event{Date: effective, Type: "Observation", End: false, Value: r}) } if ineffective, err := findDate(true, r.EffectivePeriod); err == nil { events = append(events, plugin.Event{Date: ineffective, Type: "Observation", End: true, Value: r}) } // TODO: What happens if there is no date at all? } } es = plugin.NewEventStream(patient) plugin.SortEventsByDate(events) es.Events = events return es, nil }
func addSignificantBirthdayEvents(es *plugin.EventStream, birthdays []int) { if len(birthdays) == 0 || es.Patient == nil || es.Patient.BirthDate == nil { return } for _, age := range birthdays { bd := es.Patient.BirthDate.Time.AddDate(age, 0, 0) if bd.Before(time.Now()) { es.Events = append(es.Events, plugin.Event{Date: bd, Type: "Age", End: false, Value: age}) } } plugin.SortEventsByDate(es.Events) }