From c74a255a51d87ee7142dd92602547d7e0d89842f Mon Sep 17 00:00:00 2001 From: Siyasanga Date: Thu, 29 Aug 2024 16:47:56 +0200 Subject: [PATCH 1/2] Fix: merge location bundle into Record Bundle The event location information was missing in the bundle created when a new declaration is being submitted https://github.com/opencrvs/opencrvs-core/issues/7494 --- CHANGELOG.md | 1 + packages/workflow/src/records/fhir.ts | 24 +++++++++++++- .../workflow/src/records/handler/create.ts | 33 +++++++++++++++++-- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a907d6168f..247f150c16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ ## Bug fixes - On slow connections or in rare corner cases, it was possible that the same record got saved to the database twice. This was caused by a bug in how the unique technical identifier we generate were stored as FHIR. The backend now ensures every record is submitted only once. [#7477](https://github.com/opencrvs/opencrvs-core/issues/7477) +- When a declaration(birth/death) is created the event location information was not being parsed to ElasticSearch which caused the Advanced search feature to not work when searching for records by event location.[7494](https://github.com/opencrvs/opencrvs-core/issues/7494) ## 1.5.0 (TBD) diff --git a/packages/workflow/src/records/fhir.ts b/packages/workflow/src/records/fhir.ts index 38556a506a..78d714d1b9 100644 --- a/packages/workflow/src/records/fhir.ts +++ b/packages/workflow/src/records/fhir.ts @@ -51,7 +51,8 @@ import { RegistrationStatus, getResourceFromBundleById, TransactionResponse, - TaskIdentifierSystem + TaskIdentifierSystem, + Location } from '@opencrvs/commons/types' import { FHIR_URL } from '@workflow/constants' import fetch from 'node-fetch' @@ -1453,3 +1454,24 @@ export async function getTaskHistory(taskId: string): Promise> { return res.json() } + +export async function getLocationsById( + locationIds: Array +): Promise> { + const res = await fetch( + new URL(`/fhir/Location?_id=${locationIds.join(',')}`, FHIR_URL).href, + { + method: 'GET', + headers: { + 'Content-Type': 'application/fhir+json' + } + } + ) + if (!res.ok) { + throw new Error( + `Fetching locations from Hearth failed with [${res.status}] body: ${res.statusText}` + ) + } + + return res.json() +} diff --git a/packages/workflow/src/records/handler/create.ts b/packages/workflow/src/records/handler/create.ts index 202608d7ed..a754ff8aea 100644 --- a/packages/workflow/src/records/handler/create.ts +++ b/packages/workflow/src/records/handler/create.ts @@ -30,7 +30,10 @@ import { isValidated, isWaitingExternalValidation, isComposition, - getTaskFromSavedBundle + getTaskFromSavedBundle, + Encounter, + Location, + findEncounterFromRecord } from '@opencrvs/commons/types' import { getToken, @@ -39,6 +42,7 @@ import { } from '@workflow/utils/auth-utils' import { findTaskFromIdentifier, + getLocationsById, mergeBundles, sendBundleToHearth, toSavedBundle, @@ -137,6 +141,19 @@ function createInProgressOrReadyForReviewTask( } } +async function resolveLocationsForEncounter( + encounter: Encounter +): Promise | null> { + if (encounter.location == null) { + return null + } + const locationIds: Array = [] + for (const { location } of encounter.location) { + locationIds.push(location.reference.split('/')[1]) + } + return getLocationsById(locationIds) +} + async function createRecord( recordDetails: z.TypeOf['record'], event: z.TypeOf['event'], @@ -192,7 +209,19 @@ async function createRecord( ? changeState(savedBundle, 'IN_PROGRESS') : changeState(savedBundle, 'READY_FOR_REVIEW') - return mergeBundles(record, practitionerResourcesBundle) + const mergedBundle = mergeBundles(record, practitionerResourcesBundle) + + const encounter = findEncounterFromRecord(record) + if (encounter == null) { + return mergedBundle + } + const locationResourcesBundle = await resolveLocationsForEncounter(encounter) + + if (locationResourcesBundle == null) { + return mergedBundle + } + + return mergeBundles(mergedBundle, locationResourcesBundle) } type CreatedRecord = From 284d062f792e39384dc9c099098b931b99b95e15 Mon Sep 17 00:00:00 2001 From: Siyasanga Date: Mon, 2 Sep 2024 16:03:41 +0200 Subject: [PATCH 2/2] Only add location is it does not exist in bundle We were fetching the location information with checking if it already exists yet, this happens when an event location is a residential address. https://github.com/opencrvs/opencrvs-core/issues/7494 --- .../workflow/src/records/handler/create.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/workflow/src/records/handler/create.ts b/packages/workflow/src/records/handler/create.ts index a754ff8aea..b9891e85ea 100644 --- a/packages/workflow/src/records/handler/create.ts +++ b/packages/workflow/src/records/handler/create.ts @@ -33,7 +33,8 @@ import { getTaskFromSavedBundle, Encounter, Location, - findEncounterFromRecord + findEncounterFromRecord, + Saved } from '@opencrvs/commons/types' import { getToken, @@ -154,6 +155,18 @@ async function resolveLocationsForEncounter( return getLocationsById(locationIds) } +function bundleIncludesLocationResources(record: Saved) { + const encounter = findEncounterFromRecord(record) + const locationIds = + encounter?.location?.map( + ({ location }) => location.reference.split('/')[1] + ) || [] + + return record.entry + .filter(({ resource }) => resource.resourceType == 'Location') + .every(({ resource }) => locationIds?.includes(resource.id)) +} + async function createRecord( recordDetails: z.TypeOf['record'], event: z.TypeOf['event'], @@ -215,6 +228,11 @@ async function createRecord( if (encounter == null) { return mergedBundle } + + if (bundleIncludesLocationResources(record)) { + return mergedBundle + } + const locationResourcesBundle = await resolveLocationsForEncounter(encounter) if (locationResourcesBundle == null) {