From 5ab299e34f9a65cdab9322581be9b69328eb81bd Mon Sep 17 00:00:00 2001 From: Benjamin Mwalimu Mulyungi Date: Thu, 18 Aug 2022 21:12:25 +0000 Subject: [PATCH] :bug: Update the FP form to read from the config_forms.json file --- .../engine/task/FhirCarePlanGeneratorTest.kt | 88 +---- .../{ => sample}/plandefinition.json | 167 +++++---- .../questionnaire-response-register.json | 333 ++++++++---------- .../anc-visit/structure-map-register.txt | 71 ++-- .../profile/PatientProfileViewModel.kt | 2 +- 5 files changed, 280 insertions(+), 381 deletions(-) rename android/engine/src/test/resources/plans/anc-visit/{ => sample}/plandefinition.json (50%) diff --git a/android/engine/src/test/java/org/smartregister/fhircore/engine/task/FhirCarePlanGeneratorTest.kt b/android/engine/src/test/java/org/smartregister/fhircore/engine/task/FhirCarePlanGeneratorTest.kt index fe85ce84a4..e0eadf64e8 100644 --- a/android/engine/src/test/java/org/smartregister/fhircore/engine/task/FhirCarePlanGeneratorTest.kt +++ b/android/engine/src/test/java/org/smartregister/fhircore/engine/task/FhirCarePlanGeneratorTest.kt @@ -39,7 +39,6 @@ import org.hl7.fhir.r4.model.Bundle import org.hl7.fhir.r4.model.CanonicalType import org.hl7.fhir.r4.model.CarePlan import org.hl7.fhir.r4.model.DateTimeType -import org.hl7.fhir.r4.model.DateType import org.hl7.fhir.r4.model.Encounter import org.hl7.fhir.r4.model.Group import org.hl7.fhir.r4.model.Patient @@ -62,7 +61,6 @@ import org.smartregister.fhircore.engine.util.extension.asYyyyMmDd import org.smartregister.fhircore.engine.util.extension.decodeResourceFromString import org.smartregister.fhircore.engine.util.extension.encodeResourceToString import org.smartregister.fhircore.engine.util.extension.extractId -import org.smartregister.fhircore.engine.util.extension.find import org.smartregister.fhircore.engine.util.extension.lastDayOfMonth import org.smartregister.fhircore.engine.util.extension.makeItReadable import org.smartregister.fhircore.engine.util.extension.plusDays @@ -561,7 +559,9 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { @Test fun testGenerateCarePlanForANCVisit() = runTest { val plandefinition = - "plans/anc-visit/plandefinition.json".readFile().decodeResourceFromString() + "plans/anc-visit/sample/plandefinition.json" + .readFile() + .decodeResourceFromString() val patient = "plans/anc-visit/sample/patient.json".readFile().decodeResourceFromString() @@ -571,16 +571,11 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { .readFile() .decodeResourceFromString() - // start of plan is lmp date | set lmp date to 4 months , and 15th of month - val lmp = Date().plusMonths(-4).apply { date = 15 } - - questionnaireResponse.find("245679f2-6172-456e-8ff3-425f5cea3243")!!.answer.first().value = - DateType(lmp) val structureMapRegister = structureMapUtilities.parse( "plans/anc-visit/structure-map-register.txt".readFile(), - "ANCCarePlan" + "eCBIS Normal PNC Routine Visit" ) .also { println(it.encodeResourceToString()) } @@ -590,9 +585,9 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { coEvery { fhirEngine.create(any()) } returns emptyList() coEvery { fhirEngine.search(Search(ResourceType.CarePlan)) } returns listOf() - coEvery { fhirEngine.get("132156") } returns structureMapRegister - coEvery { fhirEngine.get("132067") } returns structureMapReferral - + coEvery { fhirEngine.get("9fcb7a6a-4809-4f26-a379-c92bb783e5e0") } returns structureMapRegister + coEvery { fhirEngine.get("2dc36363-a627-4fe6-b3c4-490f34389629") } returns structureMapReferral + fhirCarePlanGenerator.generateOrUpdateCarePlan( plandefinition, patient, @@ -604,9 +599,9 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { Assert.assertNotNull(UUID.fromString(carePlan.id)) Assert.assertEquals(CarePlan.CarePlanStatus.ACTIVE, carePlan.status) Assert.assertEquals(CarePlan.CarePlanIntent.PLAN, carePlan.intent) - Assert.assertEquals("ANC Follow Up Plan", carePlan.title) + Assert.assertEquals("PNC Follow Up visit", carePlan.title) Assert.assertEquals( - "This defines the schedule of care for pregnant women", + "This action will be performed on the patient's PNC Follow Up visit", carePlan.description ) Assert.assertEquals(patient.logicalId, carePlan.subject.extractId()) @@ -619,7 +614,7 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { carePlan.author.extractId() ) - Assert.assertEquals( + /* Assert.assertEquals( questionnaireResponse.find("245679f2-6172-456e-8ff3-425f5cea3243")!! .answer .first() @@ -631,10 +626,10 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { Assert.assertEquals( lmp.plusMonths(9).makeItReadable(), carePlan.period.end.makeItReadable() - ) + )*/ Assert.assertTrue(carePlan.activityFirstRep.outcomeReference.isNotEmpty()) Assert.assertEquals( - 6, + 5, carePlan.activityFirstRep.outcomeReference.size ) // 6 visits as 4th month is passing (15th day) as per lmp @@ -649,68 +644,11 @@ class FhirCarePlanGeneratorTest : RobolectricTest() { resourcesSlot .filter { res -> res.resourceType == ResourceType.Task } .map { it as Task } - .also { Assert.assertEquals(7, it.size) } // 6 for visit, 1 for referral + .also { Assert.assertEquals(5, it.size) } // 6 for visit, 1 for referral .also { Assert.assertTrue(it.all { it.status == Task.TaskStatus.READY }) Assert.assertTrue(it.all { it.`for`.reference == patient.asReference().reference }) } - .also { tasks -> - tasks.take(6).run { - Assert.assertTrue(this.all { it.reasonReference.reference == "Questionnaire/132155" }) - Assert.assertTrue( - this.all { - it.executionPeriod.end.asYyyyMmDd() == - it.executionPeriod.start.lastDayOfMonth().asYyyyMmDd() - } - ) - Assert.assertTrue( - this.all { it.basedOn.first().reference == careplan.asReference().reference } - ) - } - } - .also { - it.last().let { task -> - Assert.assertTrue(task.reasonReference.reference == "Questionnaire/132049") - Assert.assertTrue( - task.executionPeriod.end.asYyyyMmDd() == Date().plusMonths(1).asYyyyMmDd() - ) - } - } - .also { - it.elementAt(0).let { - Assert.assertTrue( - it.executionPeriod.start.asYyyyMmDd() == - Date().asYyyyMmDd() // first task is today | 4th month - ) - } - it.elementAt(1).let { - Assert.assertTrue( - it.executionPeriod.start.asYyyyMmDd() == - lmp.plusMonths(5, true).asYyyyMmDd() // 5th month - ) - } - it.elementAt(2).let { - Assert.assertTrue( - it.executionPeriod.start.asYyyyMmDd() == - lmp.plusMonths(6, true).asYyyyMmDd() // 6th month - ) - } - it.elementAt(3).let { - Assert.assertTrue( - it.executionPeriod.start.asYyyyMmDd() == lmp.plusMonths(7, true).asYyyyMmDd() - ) // 7th month - } - it.elementAt(4).let { - Assert.assertTrue( - it.executionPeriod.start.asYyyyMmDd() == lmp.plusMonths(8, true).asYyyyMmDd() - ) // 8th month - } - it.elementAt(5).let { - Assert.assertTrue( - it.executionPeriod.start.asYyyyMmDd() == lmp.plusMonths(9, true).asYyyyMmDd() - ) // 9th month - } - } } } } diff --git a/android/engine/src/test/resources/plans/anc-visit/plandefinition.json b/android/engine/src/test/resources/plans/anc-visit/sample/plandefinition.json similarity index 50% rename from android/engine/src/test/resources/plans/anc-visit/plandefinition.json rename to android/engine/src/test/resources/plans/anc-visit/sample/plandefinition.json index b058558413..6591da657a 100644 --- a/android/engine/src/test/resources/plans/anc-visit/plandefinition.json +++ b/android/engine/src/test/resources/plans/anc-visit/sample/plandefinition.json @@ -1,62 +1,10 @@ { "resourceType": "PlanDefinition", - "id": "132157", - "meta": { - "versionId": "1", - "lastUpdated": "2022-06-20T22:30:39.217+00:00" - }, - "contained": [ - { - "resourceType": "ActivityDefinition", - "id": "careplan-activity", - "title": "ANC Follow Up Plan", - "status": "active", - "description": "This action will performed every month for a pregnant woman", - "kind": "Task", - "timingTiming": { - "repeat": { - "countMax": 8, - "duration": 2, - "durationMax": 4, - "durationUnit": "h", - "frequency": 1, - "frequencyMax": 1, - "period": 1, - "periodMax": 1, - "periodUnit": "mo" - } - } - }, - { - "resourceType": "ActivityDefinition", - "id": "careplan-followup-activity", - "title": "Sick Child Follow Up Handler Activity", - "status": "active", - "description": "This action will assess careplan every time a followup happens on a task generated by plan", - "kind": "CarePlan", - "dynamicValue": [ - { - "path": "CarePlan.status", - "expression": { - "language": "text/fhirpath", - "expression": "'completed'" - } - } - ] - }, - { - "resourceType": "ActivityDefinition", - "id": "careplan-referral-activity", - "title": "ANC Referral Handler Activity", - "status": "active", - "description": "This action will assess careplan and generate referral task every time a followup happens on a task generated by plan", - "kind": "Task" - } - ], - "name": "ANC Follow Up Plan", - "title": "ANC Follow Up Plan", + "id": "07200c16-b2d6-4d7d-a53f-128115b0ab2f", + "name": "PNC Follow Up visit", + "title": "PNC Follow Up visit", "status": "active", - "description": "This defines the schedule of care for pregnant women", + "description": "This action will be performed on the patient's PNC Follow Up visit", "goal": [ { "category": { @@ -90,14 +38,14 @@ ], "action": [ { - "prefix": "1", + "prefix": "pnc-normal-weight-visit", "priority": "routine", "condition": [ { "kind": "applicability", "expression": { "language": "text/fhirpath", - "expression": "$this is Patient and %resource.entry.first().where(resource is QuestionnaireResponse).resource.where(questionnaire = 'Questionnaire/132152').exists()" + "expression": "$this is Patient and %resource.entry.where(resource is QuestionnaireResponse).resource.where(questionnaire = 'Questionnaire/132170').exists() and %resource.entry.where(resource is QuestionnaireResponse).resource.descendants().where((linkId='6cf13e80-af2f-40fe-f70d-00fbdc331ba8') and answer.value.code = 'normal').exists()" } } ], @@ -123,37 +71,122 @@ } ] }, - "definitionCanonical": "#careplan-activity", - "transform": "http://hl7.org/fhir/StructureMap/132156" + "definitionCanonical": "#pnc-visit-activity-definition", + "transform": "http://hl7.org/fhir/StructureMap/e71e7a6-194f-11ed-861d-0242ac120002" }, { - "prefix": "1", + "prefix": "pnc-underweight-weight-visit", "priority": "routine", "condition": [ { "kind": "applicability", "expression": { "language": "text/fhirpath", - "expression": "$this is Patient and %resource.entry.first().where(resource is QuestionnaireResponse).resource.questionnaire = 'Questionnaire/132170'" + "expression": "$this is Patient and %resource.entry.where(resource is QuestionnaireResponse).resource.where(questionnaire = 'Questionnaire/132170').exists() and %resource.entry.where(resource is QuestionnaireResponse).resource.descendants().where((linkId='6cf13e80-af2f-40fe-f70d-00fbdc331ba8') and answer.value.code = 'under-weight').exists()" } } ], - "definitionCanonical": "#careplan-followup-activity" + "participant": [ + { + "type": "practitioner", + "role": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/practitioner-role", + "code": "nurse", + "display": "Nurse" + } + ] + } + } + ], + "type": { + "coding": [ + { + "code": "clinical-protocol", + "display": "Clinical Protocol" + } + ] + }, + "definitionCanonical": "#pnc-visit-activity-definition", + "transform": "http://hl7.org/fhir/StructureMap/9fcb7a6a-4809-4f26-a379-c92bb783e5e0" }, { - "prefix": "1", + "prefix": "pnc-visit-completion", "priority": "routine", "condition": [ { "kind": "applicability", "expression": { "language": "text/fhirpath", - "expression": "$this is Patient and $this.birthDate < today() - 5 'years' and %resource.entry.first().where(resource is QuestionnaireResponse).resource.descendants().where((linkId='1b625d5c-d0bc-44d5-8eed-3efc37c51f84' or linkId='9b486fa3-5323-47db-c8eb-f725fb50e8d6') and answer.value.code='yes').exists()" + "expression": "$this is Patient and %resource.entry.where(resource is QuestionnaireResponse).resource.questionnaire = 'Questionnaire/8a1f9578-5b88-45ea-8120-8f8557e01d8c'" + } + } + ], + "definitionCanonical": "#careplan-visit-activity" + }, + { + "prefix": "pnc-referral-visit", + "priority": "routine", + "condition": [ + { + "kind": "applicability", + "expression": { + "language": "text/fhirpath", + "expression": "$this is Patient and %resource.entry.where(resource is QuestionnaireResponse).resource.descendants().where((linkId='9135d01c-aa0c-4be4-8dd8-71613ccea304') and answer.value.code='yes').exists()" } } ], "definitionCanonical": "#careplan-referral-activity", - "transform": "http://hl7.org/fhir/StructureMap/132067" + "transform": "http://hl7.org/fhir/StructureMap/2dc36363-a627-4fe6-b3c4-490f34389629" + } + ], + "contained": [ + { + "resourceType": "ActivityDefinition", + "id": "pnc-visit-activity-definition", + "title": "PNC Follow Up visit", + "status": "active", + "description": "This action will be performed on the patient's PNC Follow Up visit", + "kind": "Task", + "timingTiming": { + "repeat": { + "countMax": 5, + "duration": 2, + "durationMax": 4, + "durationUnit": "h", + "frequency": 1, + "frequencyMax": 1, + "period": 1, + "periodMax": 1, + "periodUnit": "d" + } + } + }, + { + "resourceType": "ActivityDefinition", + "id": "careplan-visit-activity", + "title": "PNC Follow Up visit Handler Activity", + "status": "active", + "description": "This action will assess CarePlan every time a followup happens on a task generated by plan", + "kind": "CarePlan", + "dynamicValue": [ + { + "path": "CarePlan.status", + "expression": { + "language": "text/fhirpath", + "expression": "'completed'" + } + } + ] + }, + { + "resourceType": "ActivityDefinition", + "id": "careplan-referral-activity", + "title": "PNC Referral Handler Activity", + "status": "active", + "description": "This action will assess CarePlan and generate referral task every time a followup happens on a task generated by plan", + "kind": "Task" } ] -} \ No newline at end of file +} diff --git a/android/engine/src/test/resources/plans/anc-visit/sample/questionnaire-response-register.json b/android/engine/src/test/resources/plans/anc-visit/sample/questionnaire-response-register.json index 3277a5d8f6..29c7ef9b33 100644 --- a/android/engine/src/test/resources/plans/anc-visit/sample/questionnaire-response-register.json +++ b/android/engine/src/test/resources/plans/anc-visit/sample/questionnaire-response-register.json @@ -1,242 +1,185 @@ { "resourceType": "QuestionnaireResponse", - "id": "88f6b8d7-ebb7-484e-809b-84d88767100b", + "id": "0e6d7938-b566-4d0e-b294-5771825e1a87", "meta": { - "lastUpdated": "2022-06-20T05:18:38.789+05:00", + "lastUpdated": "2022-08-18T16:19:35.823+00:00", "tag": [ { "system": "urn:oid:2.16.578.1.12.4.1.1.8655", - "display": "eCBIS New Pregnancy Registration" + "display": "eCBIS Pregnancy Outcome & Child Registration" } ] }, - "questionnaire": "Questionnaire/132152", + "contained": [ + { + "resourceType": "Condition", + "id": "f1d1c301-83ee-46ac-bbe2-f08b8c0b63aa", + "meta": {}, + "clinicalStatus": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/condition-clinical", + "code": "active" + } + ] + }, + "verificationStatus": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", + "code": "confirmed" + } + ] + }, + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/condition-category", + "code": "encounter-diagnosis" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "234234234" + } + ], + "text": "PNC" + }, + "subject": { + "reference": "Patient/2a18662d-a500-4457-8e1b-efd5eada1cda" + }, + "onsetDateTime": "2022-08-18T16:19:35+00:00", + "recordedDate": "2022-08-18T16:19:35+00:00" + }, + { + "resourceType": "Task", + "id": "adfca87c-c799-45ec-be1a-d2e1e3f8c9e0", + "meta": {}, + "identifier": [ + { + "use": "official", + "value": "4bbc7c86-d6da-4878-80c9-4045ddbd67a1" + } + ], + "status": "ready", + "intent": "plan", + "priority": "routine", + "description": "New Born registration task", + "for": { + "reference": "Patient/2a18662d-a500-4457-8e1b-efd5eada1cda" + }, + "executionPeriod": { + "start": "2022-08-18T00:00:00", + "end": "2022-08-20T00:00:00" + }, + "authoredOn": "2022-08-18T16:19:35+00:00", + "reasonReference": { + "reference": "Questionnaire/f0a04fc4-4179-4df4-b2dc-8b2eac444d0b" + } + } + ], + "questionnaire": "Questionnaire/132170", "subject": { - "reference": "Patient/21b5f74c-6fea-4998-bfc3-6b2c3670c88b" + "reference": "Patient/2a18662d-a500-4457-8e1b-efd5eada1cda" }, - "authored": "2022-06-20T05:18:38+05:00", + "authored": "2022-08-18T16:19:32+00:00", "item": [ { - "linkId": "1aa4d0b3-8c3e-47b7-8fa5-effcb5130fac", + "linkId": "dd90825d-c161-480a-8f9f-ab2921155be2", "answer": [ { "valueCoding": { - "id": "63c19222-b589-449f-b371-b85ba449fdd9", - "system": "urn:uuid:8dc97476-74cc-4c57-8cbf-f0799cfd2ba9", - "code": "no", - "display": "No" + "id": "a67a4c44-8505-4dfa-b026-41619e0f51a2", + "system": "urn:uuid:1329ec3a-f409-4a8b-cae0-8c0911dc3a0c", + "code": "live-birth", + "display": "Live birth" } } ] }, { - "linkId": "da999955-2174-4219-825e-8ae2b948b7e7", + "linkId": "5c9a5b34-04ed-4f41-8614-9fb42333871a", + "answer": [ + { + "valueDate": "2022-08-18" + } + ] + }, + { + "linkId": "91df4f8b-69ff-44f9-bd45-1648f326fd22", "answer": [ { "valueCoding": { - "id": "30862a15-03b0-42af-8703-857e579aa2b9", - "system": "urn:uuid:de9ef3e8-be6b-4639-b196-63905d15c8c6", - "code": "yes", - "display": "Yes" - }, - "item": [ - { - "linkId": "1b5d6e5e-dd55-4b30-8f77-79da15c53269", - "answer": [ - { - "valueCoding": { - "id": "6eb83dd3-178a-45e7-c6c9-96d9335d0072", - "system": "urn:uuid:1fcf2bfd-0bcb-4278-f86a-d403866a01cb", - "code": "yes", - "display": "Yes" - }, - "item": [ - { - "linkId": "008b354b-3f6f-4402-8d6d-4de27b6e2071", - "answer": [ - { - "valueCoding": { - "id": "997f9216-f310-4e8e-88f7-93fb783d5611", - "system": "urn:uuid:01dd5475-5280-42b2-87a5-6d9b7ec374c3", - "code": "add-location-hierachy", - "display": "Add location hierachy" - } - } - ] - }, - { - "linkId": "1272863d-8d9d-4167-86d1-38f5e074607e", - "answer": [ - { - "valueDate": "2022-05-02" - } - ] - }, - { - "linkId": "92e8f830-210a-49f6-8d1a-6d01f5bc72b9", - "answer": [ - { - "valueInteger": 2 - } - ] - } - ] - } - ] - } - ] + "id": "aaceba95-a2c2-43d1-e5ac-e2551fb2ce65", + "system": "urn:uuid:8c375172-d44b-42d4-e166-70c2157b3843", + "code": "home", + "display": "Home" + } } ] }, { - "linkId": "245679f2-6172-456e-8ff3-425f5cea3243", + "linkId": "a9e50fc1-8d74-42e2-8185-fae889afcb55", "answer": [ { - "valueDate": "2022-02-04", - "item": [ - { - "linkId": "b00a7b16-e9ef-446d-daf9-fca839bae7d6", - "answer": [ - { - "valueInteger": 3 - } - ] - }, - { - "linkId": "a887e708-85d8-4fb2-871a-9c9d90887a50", - "answer": [ - { - "valueInteger": 6 - } - ] - }, - { - "linkId": "4f04affb-22a8-4da5-88d8-78bc6d0454e7", - "answer": [ - { - "valueDate": "2022-08-31" - } - ] - } - ] + "valueInteger": 1 } ] }, { - "linkId": "84d77d0b-754d-48ed-800e-905cf47b9ba6", + "linkId": "6cf13e80-af2f-40fe-f70d-00fbdc331ba8", "answer": [ { "valueCoding": { - "id": "fff11283-6334-4b73-858e-34dd01e199b1", - "system": "urn:uuid:8711d963-b2bd-445b-8fb1-e19d999dbc81", - "code": "yes", - "display": "Yes" - }, - "item": [ - { - "linkId": "d065ac2c-31af-4bbb-8706-2c6a632c5e7a", - "answer": [ - { - "valueCoding": { - "id": "c65d215c-7809-4637-8932-c7b7788ef421", - "system": "urn:uuid:52bafe9a-870c-48c2-cdd5-e6d880d7206a", - "code": "fever/chill", - "display": "Fever/chill" - }, - "item": [ - { - "linkId": "1b625d5c-d0bc-44d5-8eed-3efc37c51f84", - "answer": [ - { - "valueCoding": { - "id": "90708b0f-de8f-4345-872e-61d9e1589047", - "system": "urn:uuid:5733187d-83d0-449c-e4a6-e60f1bbe26d7", - "code": "yes", - "display": "Yes" - } - } - ] - } - ] - } - ] - } - ] + "id": "f03a9990-3e6d-4498-8dca-c4135f30f1df", + "system": "urn:uuid:61d9d3d6-8832-494a-8f3a-5b97b88cfb79", + "code": "under-weight", + "display": "Normal (2kgs and above)" + } } ] }, { - "linkId": "31009ee0-a0c9-46f0-8ef6-e65b34777aa1", + "linkId": "b5de9ea9-b01b-4cde-8114-bea0759b84ee", "answer": [ { "valueCoding": { - "id": "0ac2b549-2300-46f4-9159-5178f9d81f85", - "system": "urn:uuid:11f0c610-8a18-41ef-814b-401aa71e9f0a", - "code": "yes", - "display": "Yes" - }, - "item": [ - { - "linkId": "ac9e4bf3-4691-45d1-93cd-d4d5b293661e", - "answer": [ - { - "valueCoding": { - "id": "03601957-24e3-49ef-82d7-9d5483401908", - "system": "urn:uuid:c952513f-6cf1-4866-a909-ff273045b4c9", - "code": "walking", - "display": "Walking" - } - } - ] - }, - { - "linkId": "1f94941a-616b-432b-dca6-a5bf12c475ef", - "answer": [ - { - "valueCoding": { - "id": "4b9a3cfe-3ba9-4e1b-e4c9-cf172d038864", - "system": "urn:uuid:345a5eae-ab81-4a0c-9e47-141d5d2b2b25", - "code": "yes", - "display": "Yes" - } - } - ] - }, - { - "linkId": "d79e1518-f96c-4268-884b-39f63950f578", - "answer": [ - { - "valueCoding": { - "id": "2f768bbb-f9b3-41b3-8347-97c42c1de5c5", - "system": "urn:uuid:3bc0f36f-ca18-44c0-8646-a8402e6e688a", - "code": "yes", - "display": "Yes" - } - } - ] - }, - { - "linkId": "07736486-4e2a-4c98-ea71-e351f279ff18", - "answer": [ - { - "valueCoding": { - "id": "ef2d6d4c-575d-43ac-8887-ee9dc0f9dc12", - "system": "urn:uuid:b6aa81ee-2a24-49fd-ee5a-8c3a1018e368", - "code": "yes", - "display": "Yes" - } - } - ] - }, - { - "linkId": "ec905b2f-7fa6-4f74-d7ae-a76539eb2632", - "answer": [ - { - "valueBoolean": true - } - ] - } - ] + "id": "7ec752f2-452d-4e08-c29e-c9b6d080a1a0", + "system": "urn:uuid:dbb08802-9aa9-4e41-b7b4-1c63eb713ef5", + "code": "no", + "display": "No" + } + } + ] + }, + { + "linkId": "8d52a178-2dba-45f7-9973-a56c94329f77", + "answer": [ + { + "valueCoding": { + "id": "7409195f-cdad-4126-bc3b-f5594bfbdf81", + "system": "urn:uuid:9e54da28-eefb-4f21-dce4-20123c2a4f3e", + "code": "no", + "display": "No" + } + } + ] + }, + { + "linkId": "d26cf25a-5811-47dc-bfe9-84899c0e9825", + "answer": [ + { + "valueCoding": { + "id": "29811a23-896f-4415-9a95-914e8ef464cf", + "system": "urn:uuid:b2cab913-6d12-4252-8a0f-3ae684122571", + "code": "none", + "display": "None" + } } ] } diff --git a/android/engine/src/test/resources/plans/anc-visit/structure-map-register.txt b/android/engine/src/test/resources/plans/anc-visit/structure-map-register.txt index 884efbb0ee..85fcb7c37a 100644 --- a/android/engine/src/test/resources/plans/anc-visit/structure-map-register.txt +++ b/android/engine/src/test/resources/plans/anc-visit/structure-map-register.txt @@ -1,47 +1,37 @@ -map "http://hl7.org/fhir/StructureMap/132156" = 'ANCCarePlan' +map "http://hl7.org/fhir/StructureMap/e71e7a6-194f-11ed-861d-0242ac120002" = 'eCBIS Normal PNC Routine Visit' uses "http://hl7.org/fhir/StructureDefinition/Parameters" as source uses "http://hl7.org/fhir/StructureDefinition/CarePlan" as target -group ANCCarePlan(source src : Parameters, target tgt: CarePlan) { +group eCBISNormalWeightPNCRoutineVisit(source src : Parameters, target tgt: CarePlan) { src -> evaluate(src, $this.parameter.where(name='subject').resource) as subject, - evaluate(src, $this.parameter.where(name='definition').resource) as definition, - evaluate(src, $this.parameter.where(name='depends-on').resource.entry.resource) as questionnaireResponse, - evaluate(questionnaireResponse, $this.descendants().where(linkId='245679f2-6172-456e-8ff3-425f5cea3243').answer.value) as lmp - then ExtractCarePlan(lmp, subject, definition, questionnaireResponse, tgt), ExtractActivityDetail(lmp, subject, definition, tgt) "r_careplan"; + evaluate(src, $this.parameter.where(name='definition').resource) as definition, + evaluate(src, $this.parameter.where(name='depends-on').resource.entry.where(resource is QuestionnaireResponse).resource) as questionnaireResponse + then ExtractCarePlan(subject, definition, questionnaireResponse, tgt), ExtractActivityDetail(subject, definition, questionnaireResponse, tgt) "rule_careplan_generation"; } -group ExtractCarePlan(source lmp: DateType, source subject: Patient, source definition: ActivityDefinition, source questionnaireResponse: QuestionnaireResponse, target careplan : CarePlan) { +group ExtractCarePlan(source subject: Patient, source definition: ActivityDefinition, source questionnaireResponse: QuestionnaireResponse, target careplan : CarePlan) { subject -> careplan.id = uuid() , careplan.identifier = create('Identifier') as iden, iden.value = uuid(), iden.use = 'official', careplan.status = 'active', careplan.intent = 'plan', careplan.subject = create('Reference') as ref, ref.reference = evaluate(subject, $this.id.replaceMatches('/_history/.*', '')), careplan.created = evaluate(subject, now()), - careplan.author = evaluate(subject, $this.generalPractitioner.first()), - careplan.period = create('Period') as period, - lmp as offset - then ExtractPeriod_9m(offset, period) "r_cp_data"; + careplan.author = evaluate(subject, $this.generalPractitioner.first()), evaluate(subject, now()) as offset, create('Period') as period then ExtractPncPeriod(offset, period) "rule_careplan_period_data"; } -group ExtractActivityDetail(source lmp: DateType, source subject : Patient, - source definition: ActivityDefinition, target careplan : CarePlan){ +group ExtractActivityDetail(source subject : Patient, source definition: ActivityDefinition, source questionnaireResponse: QuestionnaireResponse, target careplan : CarePlan){ subject -> careplan.activity = create('CarePlan_Activity') as activity then { subject -> activity.detail = create('CarePlan_ActivityDetail') as det then { - subject -> det.kind = 'Task', - det.status = 'in-progress', - det.description = evaluate(definition, $this.title), - det.performer = evaluate(subject, $this.generalPractitioner.first()), - det.code = create('CodeableConcept') as concept then ExtractTimingCode(subject, concept) "r_act_det_data"; + subject -> det.kind = 'Task', det.status = 'in-progress', det.description = evaluate(definition, $this.title), det.performer = evaluate(subject, $this.generalPractitioner.first()), det.code = create('CodeableConcept') as concept then ExtractTimingCode(subject, concept) "r_act_det_data"; - subject -> det.scheduled = evaluate(definition, $this.timing) as timing, - evaluate(timing, $this.repeat) as repeat then { + subject -> det.scheduled = evaluate(definition, $this.timing) as timing, evaluate(timing, $this.repeat) as repeat then { - subject -> evaluate(subject, today()) as dueDate, - evaluate(lmp, $this + '9 \'months\''.toQuantity()) as edd - then ExtractTasks(dueDate, edd, repeat, subject, careplan, activity, timing) "r_tasks"; + subject -> evaluate(subject, today()) as dayOneDueDate, evaluate(dayOneDueDate , $this + '1 \'days\''.toQuantity()) as dayOneEnd then ExtractTasks(dayOneDueDate, dayOneEnd, subject, careplan, activity, timing) "rule_day_one_tasks"; + subject -> evaluate(subject, today() + '3 \'days\''.toQuantity()) as dayThreeDueDate, evaluate(dayThreeDueDate , $this + '1 \'days\''.toQuantity()) as dayThreeEnd then ExtractTasks(dayThreeDueDate, dayThreeEnd, subject, careplan, activity, timing) "rule_day_three_tasks"; + subject -> evaluate(subject, today() + '7 \'days\''.toQuantity()) as daySevenDueDate, evaluate(daySevenDueDate , $this + '1 \'days\''.toQuantity()) as daySevenEnd then ExtractTasks(daySevenDueDate, daySevenEnd, subject, careplan, activity, timing) "rule_day_seven_tasks"; - subject -> repeat.count = create('positiveInt') as c, c.value = evaluate(activity, $this.outcomeReference.count().value) "r_task_rep_count"; + subject -> repeat.count = create('positiveInt') as c, c.value = evaluate(activity, $this.outcomeReference.count().value) "r_task_rep_count"; } "r_tim_repeat"; } "r_act_det"; @@ -52,22 +42,14 @@ group ExtractActivityDetail(source lmp: DateType, source subject : Patient, group ExtractTasks( source dueDate: DateType, source maxDate: DateType, - source repeat: TimingRepeat, source subject : Patient, target careplan: CarePlan, target activity : CarePlan_Activity, target timing: Timing){ - // today + total * gap - repeat where(dueDate <= maxDate and (today() + ((countMax.toDecimal() * period).toString()+' \'months\'').toQuantity()) >= dueDate) -> - // start of task is today OR first date of every month if future month | end is last day of given month - create('date') as startOfMonth, startOfMonth.value = evaluate(dueDate, $this.value.substring(0,7) + '-01'), - create('date') as start, start.value = evaluate(dueDate, iif($this = today(), $this, startOfMonth).value ), - evaluate(startOfMonth, ($this + '1 \'months\''.toQuantity()) - '1 \'days\''.toQuantity()) as end, - create('Period') as period, - careplan.contained = create('Task') as task then { + subject -> create('Period') as period, careplan.contained = create('Task') as task then { - subject then ExtractPeriod(start, end, period) "r_task_period_extr"; + subject then ExtractPeriod(dueDate, maxDate, period) "r_task_period_extr"; subject -> task.id = uuid(), task.identifier = create('Identifier') as iden, iden.value = uuid(), iden.use = 'official', @@ -75,22 +57,20 @@ group ExtractTasks( task.intent = 'plan', task.executionPeriod = period, task.priority = 'routine', - task.description = 'ANC Follow Up Task', + task.description = 'PNC Follow Up visit', task.for = create('Reference') as ref, ref.reference = evaluate(subject, $this.id.replaceMatches('/_history/.*', '')), task.basedOn = reference(careplan), task.authoredOn = evaluate(subject, now()), task.requester = evaluate(subject, $this.generalPractitioner.first()), - task.owner = evaluate(subject, $this.generalPractitioner.first()) "r_task_data"; + task.owner = evaluate(subject, $this.generalPractitioner.first()) "rule_task_data"; - // anc followup form - subject -> task.reasonReference = create('Reference') as ref, ref.reference = 'Questionnaire/132155' "r_task_reason_ref"; + // pnc followup form + subject -> task.reasonReference = create('Reference') as ref, ref.reference = 'Questionnaire/8a1f9578-5b88-45ea-8120-8f8557e01d8c' "r_task_reason_ref"; subject -> activity.outcomeReference = reference(task) "r_cp_task_ref"; subject -> timing.event = evaluate(period, $this.start) "r_activity_timing"; - repeat -> evaluate(period, $this.start + (repeat.period.toString() + ' \'months\'').toQuantity()) as nextDueDate - then ExtractTasks(nextDueDate, maxDate, repeat, subject, careplan, activity, timing) "r_task_repeat"; - } "r_cp_acti_outcome"; + } "rule_careplan_task_outcome"; } group ExtractTimingCode(source subject : Patient, target concept: CodeableConcept){ @@ -100,9 +80,9 @@ group ExtractTimingCode(source subject : Patient, target concept: CodeableConcep subject -> concept.text = 'QD' "r_cp_cc_txt"; } -group ExtractPeriod_9m(source offset: DateType, target period: Period){ +group ExtractPncPeriod(source offset: DateType, target period: Period){ offset -> offset as start, - evaluate(offset, $this + '9 \'months\''.toQuantity()) as end then + evaluate(offset, $this + '28 \'days\''.toQuantity()) as end then ExtractPeriod(start, end, period) "r_period"; } @@ -113,3 +93,8 @@ group ExtractPeriod(source start: DateType, source end: DateType, target period: end -> period.end = create('dateTime') as dt, dt.value = evaluate(end, $this.value.substring(0,10) + 'T00:00:00') "r_per_end"; } + +group ExtractSubject(source subject: Patient, target ref: Reference) { + subject -> ref.reference = evaluate(subject, $this.id.replaceMatches('/_history/.*', '')) "r_patient_ref"; + subject -> ref.display = evaluate(subject, $this.name.given + " " + $this.name.text + " " + $this.name.family) "r_patient_display"; +} diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/profile/PatientProfileViewModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/profile/PatientProfileViewModel.kt index 3529b2e2d0..1ba298fbc2 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/profile/PatientProfileViewModel.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/profile/PatientProfileViewModel.kt @@ -196,6 +196,6 @@ constructor( const val PREGNANCY_OUTCOME_FORM = "pregnancy-outcome" const val SICK_CHILD_UNDER_2M_FORM = "sick-child-under-2m" const val SICK_CHILD_ABOVE_2M_FORM = "sick-child-above-2m" - const val FAMILY_PLANNING = "137649" + const val FAMILY_PLANNING = "family-planning" } }