package observation import ( "os" "time" "service/internal/interfaces/satusehat" ) func MapRequestToFHIR(req ObservationRequest) satusehat.FHIRPayload { payload := satusehat.NewFHIRPayload("Observation") orgID := os.Getenv("SATUSEHAT_ORG_ID") if orgID == "" { orgID = req.OrganizationID } if req.ObservationID != "" { payload.Set("identifier", []map[string]interface{}{ { "system": "http://sys-ids.kemkes.go.id/observation/" + orgID, "value": req.ObservationID, }, }) } status := req.Status if status == "" { status = "final" } payload.Set("status", status) if len(req.Category) > 0 { var categories []map[string]interface{} for _, c := range req.Category { if c != nil { sys := c.System if sys == "" { sys = "http://terminology.hl7.org/CodeSystem/observation-category" } coding := map[string]interface{}{"system": sys, "code": c.Code} if c.Display != "" { coding["display"] = c.Display } categories = append(categories, map[string]interface{}{"coding": []map[string]interface{}{coding}}) } } payload.Set("category", categories) } if req.Code != nil { sys := req.Code.System if sys == "" { sys = "http://loinc.org" } coding := map[string]interface{}{"system": sys, "code": req.Code.Code} if req.Code.Display != "" { coding["display"] = req.Code.Display } codeConcept := map[string]interface{}{"coding": []map[string]interface{}{coding}} if req.Code.Text != "" { codeConcept["text"] = req.Code.Text } payload.Set("code", codeConcept) } if req.Subject != nil { subj := map[string]interface{}{"reference": req.Subject.Reference} if req.Subject.Display != "" { subj["display"] = req.Subject.Display } payload.Set("subject", subj) } if req.Encounter != nil { enc := map[string]interface{}{"reference": req.Encounter.Reference} if req.Encounter.Display != "" { enc["display"] = req.Encounter.Display } payload.Set("encounter", enc) } if req.EffectiveDateTime != nil && !req.EffectiveDateTime.IsZero() { payload.Set("effectiveDateTime", req.EffectiveDateTime.Format(time.RFC3339)) } if req.Issued != nil && !req.Issued.IsZero() { payload.Set("issued", req.Issued.Format(time.RFC3339)) } if len(req.Performer) > 0 { var performers []map[string]interface{} for _, p := range req.Performer { perf := map[string]interface{}{"reference": p.Reference} if p.Display != "" { perf["display"] = p.Display } performers = append(performers, perf) } payload.Set("performer", performers) } if len(req.BasedOn) > 0 { var refs []map[string]interface{} for _, r := range req.BasedOn { refs = append(refs, map[string]interface{}{"reference": r.Reference}) } payload.Set("basedOn", refs) } if len(req.PartOf) > 0 { var refs []map[string]interface{} for _, r := range req.PartOf { refs = append(refs, map[string]interface{}{"reference": r.Reference}) } payload.Set("partOf", refs) } if len(req.DerivedFrom) > 0 { var refs []map[string]interface{} for _, r := range req.DerivedFrom { refs = append(refs, map[string]interface{}{"reference": r.Reference}) } payload.Set("derivedFrom", refs) } if req.Specimen != nil { spec := map[string]interface{}{"reference": req.Specimen.Reference} if req.Specimen.Display != "" { spec["display"] = req.Specimen.Display } payload.Set("specimen", spec) } if req.BodySite != nil { sys := req.BodySite.System if sys == "" { sys = "http://snomed.info/sct" } coding := map[string]interface{}{"system": sys, "code": req.BodySite.Code} if req.BodySite.Display != "" { coding["display"] = req.BodySite.Display } payload.Set("bodySite", map[string]interface{}{"coding": []map[string]interface{}{coding}}) } if req.ValueQuantity != nil { sys := req.ValueQuantity.System if sys == "" { sys = "http://unitsofmeasure.org" } payload.Set("valueQuantity", map[string]interface{}{ "value": req.ValueQuantity.Value, "unit": req.ValueQuantity.Unit, "system": sys, "code": req.ValueQuantity.Code, }) } else if req.ValueCodeableConcept != nil { sys := req.ValueCodeableConcept.System if sys == "" { sys = "http://snomed.info/sct" } coding := map[string]interface{}{"system": sys, "code": req.ValueCodeableConcept.Code} if req.ValueCodeableConcept.Display != "" { coding["display"] = req.ValueCodeableConcept.Display } payload.Set("valueCodeableConcept", map[string]interface{}{"coding": []map[string]interface{}{coding}}) } else if req.ValueString != "" { payload.Set("valueString", req.ValueString) } else if req.ValueBoolean != nil { payload.Set("valueBoolean", *req.ValueBoolean) } if len(req.Interpretation) > 0 { var interps []map[string]interface{} for _, interp := range req.Interpretation { if interp != nil { sys := interp.System if sys == "" { sys = "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation" } coding := map[string]interface{}{"system": sys, "code": interp.Code} if interp.Display != "" { coding["display"] = interp.Display } interps = append(interps, map[string]interface{}{"coding": []map[string]interface{}{coding}}) } } payload.Set("interpretation", interps) } if len(req.ReferenceRange) > 0 { var ranges []map[string]interface{} for _, r := range req.ReferenceRange { rng := map[string]interface{}{} if r.Low != nil { sys := r.Low.System if sys == "" { sys = "http://unitsofmeasure.org" } rng["low"] = map[string]interface{}{"value": r.Low.Value, "unit": r.Low.Unit, "system": sys, "code": r.Low.Code} } if r.High != nil { sys := r.High.System if sys == "" { sys = "http://unitsofmeasure.org" } rng["high"] = map[string]interface{}{"value": r.High.Value, "unit": r.High.Unit, "system": sys, "code": r.High.Code} } if r.Text != "" { rng["text"] = r.Text } ranges = append(ranges, rng) } payload.Set("referenceRange", ranges) } if len(req.Components) > 0 { var components []map[string]interface{} for _, comp := range req.Components { c := make(map[string]interface{}) if comp.Code != nil { sys := comp.Code.System if sys == "" { sys = "http://loinc.org" } coding := map[string]interface{}{"system": sys, "code": comp.Code.Code} if comp.Code.Display != "" { coding["display"] = comp.Code.Display } c["code"] = map[string]interface{}{"coding": []map[string]interface{}{coding}} } if comp.ValueQuantity != nil { sysVQ := comp.ValueQuantity.System if sysVQ == "" { sysVQ = "http://unitsofmeasure.org" } c["valueQuantity"] = map[string]interface{}{"value": comp.ValueQuantity.Value, "unit": comp.ValueQuantity.Unit, "system": sysVQ, "code": comp.ValueQuantity.Code} } else if comp.ValueCodeableConcept != nil { sysVCC := comp.ValueCodeableConcept.System if sysVCC == "" { sysVCC = "http://snomed.info/sct" } coding := map[string]interface{}{"system": sysVCC, "code": comp.ValueCodeableConcept.Code} if comp.ValueCodeableConcept.Display != "" { coding["display"] = comp.ValueCodeableConcept.Display } c["valueCodeableConcept"] = map[string]interface{}{"coding": []map[string]interface{}{coding}} } else if comp.ValueString != "" { c["valueString"] = comp.ValueString } else if comp.ValueBoolean != nil { c["valueBoolean"] = *comp.ValueBoolean } components = append(components, c) } payload.Set("component", components) } return payload }