diff --git a/opensrp-chw/build.gradle b/opensrp-chw/build.gradle index 27964ae232..f6e95d1cf1 100644 --- a/opensrp-chw/build.gradle +++ b/opensrp-chw/build.gradle @@ -180,7 +180,7 @@ dependencies { exclude group: 'com.android.support', module: 'appcompat-v7' } - implementation('org.smartregister:opensrp-client-chw-anc:0.0.1-SNAPSHOT@aar') { + implementation('org.smartregister:opensrp-client-chw-anc:0.0.4-SNAPSHOT@aar') { transitive = true exclude group: 'org.smartregister', module: 'opensrp-client-core' exclude group: 'com.android.support', module: 'appcompat-v7' diff --git a/opensrp-chw/src/ba/assets/ec_client_classification.json b/opensrp-chw/src/ba/assets/ec_client_classification.json index c087f7c146..eed82bb1ac 100644 --- a/opensrp-chw/src/ba/assets/ec_client_classification.json +++ b/opensrp-chw/src/ba/assets/ec_client_classification.json @@ -99,6 +99,13 @@ "creates_case": [ "ec_anc_register" ] + }, + { + "field": "eventType", + "field_value": "ANC Home Visit", + "creates_case": [ + "ec_anc_register" + ] } ] } diff --git a/opensrp-chw/src/ba/assets/ec_client_fields.json b/opensrp-chw/src/ba/assets/ec_client_fields.json index 2df86a546e..2b22160b4d 100644 --- a/opensrp-chw/src/ba/assets/ec_client_fields.json +++ b/opensrp-chw/src/ba/assets/ec_client_fields.json @@ -677,6 +677,22 @@ "field": "obs.fieldCode", "concept": "1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" } + }, + { + "column_name": "last_home_visit", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "anc_visit_date" + } + }, + { + "column_name": "visit_not_done", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "anc_visit_not_done_date" + } } ] } diff --git a/opensrp-chw/src/ba/assets/json.form/anc_member_registration.json b/opensrp-chw/src/ba/assets/json.form/anc_member_registration.json index 4b648b506c..ddca8c5a76 100644 --- a/opensrp-chw/src/ba/assets/json.form/anc_member_registration.json +++ b/opensrp-chw/src/ba/assets/json.form/anc_member_registration.json @@ -55,9 +55,9 @@ "openmrs_entity": "concept", "openmrs_entity_id": "1427AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "type": "date_picker", - "label_info_title": "LMP", - "label_info_text": "First day of Last Menstrual Period. If the exact date is unknown, but the period of the month is known, use day 5 for beginning of the month, day 15 for middle of the month and day 25 for end of the month.", "hint": "Last Menstrual Period (LMP)", + "label_info_title": "LMP", + "label_info_text": "LMP = first day of Last Menstrual Period. If the exact date is unknown, but the period of the month is known, use day 5 for beginning of the month, day 15 for middle of the month and day 25 for end of the month.", "expanded": false, "duration": { "label": "lmp" @@ -68,6 +68,22 @@ "err": "LMP required" } }, + { + "key": "gest_age_note", + "openmrs_entity_parent": "", + "openmrs_entity": "", + "openmrs_entity_id": "", + "type": "edit_text", + "hint": "Gestational Age (GA)", + "read_only": true, + "calculation": { + "rules-engine": { + "ex-rules": { + "rules-file": "anc_member_registration_calculation.yml" + } + } + } + }, { "key": "gest_age", "openmrs_entity_parent": "", @@ -87,7 +103,9 @@ "openmrs_entity_parent": "", "openmrs_entity": "concept", "openmrs_entity_id": "5596AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "type": "hidden", + "type": "edit_text", + "hint": "Expected Date of Delivery (EDD)", + "read_only": true, "calculation": { "rules-engine": { "ex-rules": { @@ -99,8 +117,8 @@ { "key": "no_prev_preg", "openmrs_entity_parent": "", - "openmrs_entity": "", - "openmrs_entity_id": "", + "openmrs_entity": "concept", + "openmrs_entity_id": "no_prev_preg", "type": "edit_text", "edit_type": "number", "hint": "No. of previous pregnancies", @@ -114,7 +132,7 @@ }, "v_min": { "value": "0", - "err": "Age must be equal or greater than 0" + "err": "Number must be equal or greater than 0" } }, { @@ -131,6 +149,27 @@ } } }, + { + "key": "delivery_method", + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_entity_id": "5630AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "openmrs_data_type": "select one", + "type": "spinner", + "hint": "Have you delivered your child(ren) vaginally or by ceasarian section?", + "v_required": { + "value": "true", + "err": "Please select one option" + }, + "values": [ + "Vaginally", + "Caesarian section" + ], + "openmrs_choice_ids": { + "Vaginally": "1170AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Caesarian section": "1171AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, { "key": "no_surv_children", "openmrs_entity_parent": "", @@ -152,6 +191,29 @@ "err": "Age must be equal or greater than 0" } }, + { + "key": "marital_status", + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_entity_id": "1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "openmrs_data_type": "select one", + "type": "spinner", + "hint": "Marital status", + "v_required": { + "value": "true", + "err": "Please select one option" + }, + "values": [ + "Married", + "Co-habiting", + "Single" + ], + "openmrs_choice_ids": { + "Married": "5555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Co-habiting": "1060AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Single": "5615AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, { "key": "phone_number", "openmrs_entity_parent": "", @@ -159,6 +221,10 @@ "openmrs_entity_id": "159635AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "type": "edit_text", "hint": "Phone number", + "v_required": { + "value": true, + "err": "Please specify the phone number" + }, "v_numeric": { "value": "true", "err": "Number must be a total of 10 digits in length" @@ -170,36 +236,74 @@ "v_required": { "value": false, "err": "Please specify the phone number" + } + }, + { + "key": "person_assist", + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_entity_id": "159771AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "openmrs_data_type": "select one", + "type": "spinner", + "hint": "Does the mother have anyone, 18 years or older, who would be able to assist her during her pregnancy?", + "v_required": { + "value": "true", + "err": "Please select one option" }, + "values": [ + "Yes", + "No" + ], + "openmrs_choice_ids": { + "Yes": "1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "No": "1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "key": "name_person_assist", + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_entity_id": "160638AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "type": "edit_text", + "hint": "Name of close person/relative who lives with her and is 18 years or olders", + "edit_type": "name", "relevance": { "rules-engine": { "ex-rules": { - "rules-file": "family_member_relevance.yml" + "rules-file": "anc_member_registration_relevance.yml" } } + }, + "v_required": { + "value": "true", + "err": "Please enter the family name" } }, { - "key": "marital_status", + "key": "phone_person_assist", "openmrs_entity_parent": "", "openmrs_entity": "concept", - "openmrs_entity_id": "1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "openmrs_data_type": "select one", - "type": "spinner", - "hint": "Marital status", - "values": [ - "Married", - "Co-habiting", - "Single" - ], - "openmrs_choice_ids": { - "Married": "5555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "Co-habiting": "1060AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "Single": "5615AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "v_required": { - "value": "true", - "err": "Please select one option" + "openmrs_entity_id": "159635AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "type": "edit_text", + "hint": "Phone number", + "v_required": { + "value": true, + "err": "Please specify the phone number" + }, + "relevance": { + "rules-engine": { + "ex-rules": { + "rules-file": "anc_member_registration_relevance.yml" + } } + }, + "v_numeric": { + "value": "true", + "err": "Number must be a total of 10 digits in length" + }, + "v_regex": { + "value": "(0[0-9]{9})|\\s*", + "err": "Number must be 10 digits and must start with 0." } } ] diff --git a/opensrp-chw/src/ba/assets/rule/anc-home-visit-rules.yml b/opensrp-chw/src/ba/assets/rule/anc-home-visit-rules.yml new file mode 100644 index 0000000000..82f39f0c80 --- /dev/null +++ b/opensrp-chw/src/ba/assets/rule/anc-home-visit-rules.yml @@ -0,0 +1,44 @@ +--- +name: expiry +description: expire lmp greter than 1 yr +priority: 1 +condition: "ancVisitAlertRule.isExpiry()" +actions: + - "ancVisitAlertRule.buttonStatus = 'EXPIRY'" +--- +name: visit_not_done +description: press visit not done in this month +priority: 1 +condition: "ancVisitAlertRule.isVisitNotDone()" +actions: + - "ancVisitAlertRule.buttonStatus = 'NOT_VISIT_THIS_MONTH'" +--- +name: visit_twenty_four +description: visit within twenty four hours +priority: 2 +condition: "ancVisitAlertRule.isVisitWithinTwentyFour()" +actions: + - "ancVisitAlertRule.buttonStatus = 'LESS_TWENTY_FOUR'" +--- +name: visit_this_month +description: visit grether than 24 hours but within this month +priority: 3 +condition: "ancVisitAlertRule.isVisitWithinThisMonth()" +actions: + - "ancVisitAlertRule.buttonStatus = 'VISIT_THIS_MONTH'" +--- +name: overdue +description: previous month not visited +priority: 2 +condition: "ancVisitAlertRule.isOverdueWithinMonth(1)" +actions: + - "ancVisitAlertRule.buttonStatus = 'OVERDUE'" +--- +name: due +description: due first day of month and same month +priority: 3 +condition: "ancVisitAlertRule.isDueWithinMonth()" +actions: + - "ancVisitAlertRule.buttonStatus = 'DUE'" + + diff --git a/opensrp-chw/src/ba/assets/rule/anc_member_registration_calculation.yml b/opensrp-chw/src/ba/assets/rule/anc_member_registration_calculation.yml index cf554c2682..2338f68ede 100644 --- a/opensrp-chw/src/ba/assets/rule/anc_member_registration_calculation.yml +++ b/opensrp-chw/src/ba/assets/rule/anc_member_registration_calculation.yml @@ -6,6 +6,14 @@ condition: "true" actions: - "calculation = (helper.getDifferenceDays(step1_last_menstrual_period)-helper.getDifferenceDays(helper.getDateToday())) /7" +--- +name: step1_gest_age_note +description: Gestational age calculated +priority: 1 +condition: "true" +actions: + - "calculation = step1_gest_age + ' weeks'" + --- name: step1_edd description: Edd calculated diff --git a/opensrp-chw/src/ba/assets/rule/anc_member_registration_relevance.yml b/opensrp-chw/src/ba/assets/rule/anc_member_registration_relevance.yml new file mode 100644 index 0000000000..dd97d0df11 --- /dev/null +++ b/opensrp-chw/src/ba/assets/rule/anc_member_registration_relevance.yml @@ -0,0 +1,14 @@ +--- +name: step1_name_person_assist +description: assist person relevance +priority: 1 +condition: "step1_person_assist == 'Yes'" +actions: + - "isRelevant = true" +--- +name: step1_phone_person_assist +description: assist person phone number relevance +priority: 1 +condition: "step1_person_assist == 'Yes'" +actions: + - "isRelevant = true" \ No newline at end of file diff --git a/opensrp-chw/src/ba/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java b/opensrp-chw/src/ba/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java index ef894f15d7..11149aa093 100644 --- a/opensrp-chw/src/ba/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java +++ b/opensrp-chw/src/ba/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java @@ -2,6 +2,7 @@ import android.content.Context; +import org.json.JSONObject; import org.smartregister.chw.R; import org.smartregister.chw.anc.contract.BaseAncHomeVisitContract; import org.smartregister.chw.anc.model.BaseAncHomeVisitAction; @@ -10,6 +11,10 @@ import java.text.MessageFormat; import java.util.LinkedHashMap; +import timber.log.Timber; + +import static org.smartregister.chw.util.JsonFormUtils.getValue; + public class AncHomeVisitInteractorFlv implements AncHomeVisitInteractor.Flavor { @Override public LinkedHashMap calculateActions(BaseAncHomeVisitContract.View view, String memberID, BaseAncHomeVisitContract.InteractorCallBack callBack) throws BaseAncHomeVisitAction.ValidationException { @@ -17,16 +22,11 @@ public LinkedHashMap calculateActions(BaseAncHom Context context = view.getContext(); + evaluateDangerSigns(actionList, context); - actionList.put(context.getString(R.string.anc_home_visit_danger_signs), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_danger_signs), "", false, null, - ANC_HOME_VISIT.DANGER_SIGNS)); + evaluateHealthFacilityVisit(actionList, context); - String hf_visit = MessageFormat.format(context.getString(R.string.anc_home_visit_facility_visit), 1); - actionList.put(hf_visit, new BaseAncHomeVisitAction(hf_visit, "", false, null, - ANC_HOME_VISIT.HEALTH_FACILITY_VISIT)); - - actionList.put(context.getString(R.string.anc_home_visit_family_planning), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_family_planning), "", false, null, - ANC_HOME_VISIT.FAMILY_PLANNING)); + evaluateFamilyPlanning(actionList, context); actionList.put(context.getString(R.string.anc_home_visit_nutrition_status), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_nutrition_status), "", false, null, ANC_HOME_VISIT.NUTRITION_STATUS)); @@ -34,8 +34,7 @@ public LinkedHashMap calculateActions(BaseAncHom actionList.put(context.getString(R.string.anc_home_visit_counselling_task), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_counselling_task), "", false, null, ANC_HOME_VISIT.COUNSELLING)); - actionList.put(context.getString(R.string.anc_home_visit_malaria_prevention), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_malaria_prevention), "", false, null, - ANC_HOME_VISIT.MALARIA)); + evaluateMalaria(actionList, context); actionList.put(context.getString(R.string.anc_home_visit_observations_n_illnes), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_observations_n_illnes), "", true, null, ANC_HOME_VISIT.OBSERVATION_AND_ILLNESS)); @@ -45,4 +44,124 @@ public LinkedHashMap calculateActions(BaseAncHom return actionList; } + + private void evaluateDangerSigns(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_danger_signs), "", false, null, + ANC_HOME_VISIT.DANGER_SIGNS); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "danger_signs_counseling"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else if (value.equalsIgnoreCase("No")) { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PENDING; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_danger_signs), ba); + } + + private void evaluateHealthFacilityVisit(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + + String visit = MessageFormat.format(context.getString(R.string.anc_home_visit_facility_visit), 1); + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(visit, "", false, null, ANC_HOME_VISIT.HEALTH_FACILITY_VISIT); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "anc_hf_visit"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else if (value.equalsIgnoreCase("No")) { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PENDING; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(visit, ba); + } + + private void evaluateFamilyPlanning(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_family_planning), "", false, null, + ANC_HOME_VISIT.FAMILY_PLANNING); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "fam_planning"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_family_planning), ba); + } + + private void evaluateMalaria(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_malaria_prevention), "", false, null, + ANC_HOME_VISIT.MALARIA); + + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value1 = getValue(jsonObject, "fam_llin"); + String value2 = getValue(jsonObject, "llin_2days"); + String value3 = getValue(jsonObject, "llin_condition"); + + if (value1.equalsIgnoreCase("Yes") && value2.equalsIgnoreCase("Yes") && value3.equalsIgnoreCase("Okay")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_malaria_prevention), ba); + } } diff --git a/opensrp-chw/src/main/AndroidManifest.xml b/opensrp-chw/src/main/AndroidManifest.xml index fd8e5cea37..813d94d94f 100644 --- a/opensrp-chw/src/main/AndroidManifest.xml +++ b/opensrp-chw/src/main/AndroidManifest.xml @@ -26,6 +26,9 @@ + getViewIdentifiers() { public void startFormActivity(JSONObject jsonForm) { - Intent intent = new Intent(this, Utils.metadata().familyMemberFormActivity); - intent.putExtra(org.smartregister.family.util.Constants.JSON_FORM_EXTRA.JSON, jsonForm.toString()); - - Form form = new Form(); - form.setActionBarBackground(R.color.family_actionbar); - form.setWizard(false); - intent.putExtra(JsonFormConstants.JSON_FORM_KEY.FORM, form); + try { + JSONObject stepOne = jsonForm.getJSONObject(JsonFormUtils.STEP1); + JSONArray jsonArray = stepOne.getJSONArray(JsonFormUtils.FIELDS); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if (jsonObject.getString(org.smartregister.chw.util.JsonFormUtils.KEY).equalsIgnoreCase(Constants.JsonAssets.FAMILY_MEMBER.PHONE_NUMBER)) { + jsonObject.put(JsonFormUtils.VALUE, phone_number); + } + } + Intent intent = new Intent(this, Utils.metadata().familyMemberFormActivity); + intent.putExtra(org.smartregister.family.util.Constants.JSON_FORM_EXTRA.JSON, jsonForm.toString()); + + Form form = new Form(); + form.setActionBarBackground(R.color.family_actionbar); + form.setWizard(false); + intent.putExtra(JsonFormConstants.JSON_FORM_KEY.FORM, form); + + startActivityForResult(intent, JsonFormUtils.REQUEST_CODE_GET_JSON); + } catch (JSONException e) { + e.printStackTrace(); + } - startActivityForResult(intent, JsonFormUtils.REQUEST_CODE_GET_JSON); } @Override diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/activity/FamilyOtherMemberProfileActivity.java b/opensrp-chw/src/main/java/org/smartregister/chw/activity/FamilyOtherMemberProfileActivity.java index 82d2d40643..c876ef2768 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/activity/FamilyOtherMemberProfileActivity.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/activity/FamilyOtherMemberProfileActivity.java @@ -54,6 +54,7 @@ public class FamilyOtherMemberProfileActivity extends BaseFamilyOtherMemberProfi private String primaryCaregiver; private String villageTown; private String familyName; + private String PhoneNumber; private CommonPersonObjectClient commonPersonObject; private FamilyMemberFloatingMenu familyFloatingMenu; private TextView textViewFamilyHas; @@ -93,6 +94,7 @@ protected void initializePresenter() { primaryCaregiver = getIntent().getStringExtra(Constants.INTENT_KEY.PRIMARY_CAREGIVER); villageTown = getIntent().getStringExtra(Constants.INTENT_KEY.VILLAGE_TOWN); familyName = getIntent().getStringExtra(Constants.INTENT_KEY.FAMILY_NAME); + PhoneNumber = commonPersonObject.getColumnmaps().get(org.smartregister.chw.util.Constants.JsonAssets.FAMILY_MEMBER.PHONE_NUMBER); presenter = new FamilyOtherMemberActivityPresenter(this, new BaseFamilyOtherMemberProfileActivityModel(), null, familyBaseEntityId, baseEntityId, familyHead, primaryCaregiver, villageTown, familyName); onClickFloatingMenu = flavor.getOnClickFloatingMenu(this, familyBaseEntityId); @@ -187,11 +189,10 @@ public boolean onOptionsItemSelected(MenuItem item) { onBackPressed(); return true; case R.id.action_anc_registration: - startFormForEdit(R.string.edit_member_form_title); - AncRegisterActivity.startAncRegistrationActivity(FamilyOtherMemberProfileActivity.this, baseEntityId); + AncRegisterActivity.startAncRegistrationActivity(FamilyOtherMemberProfileActivity.this, baseEntityId, PhoneNumber); return true; case R.id.action_registration: - startFormForEdit(R.string.edit_member_form_title); + startFormForEdit(R.string.anc_registration_form_title); return true; case R.id.action_remove_member: IndividualProfileRemoveActivity.startIndividualProfileActivity(FamilyOtherMemberProfileActivity.this, commonPersonObject, familyBaseEntityId, familyHead, primaryCaregiver); @@ -248,9 +249,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case org.smartregister.chw.util.Constants.ProfileActivityResults.CHANGE_COMPLETED: if (resultCode == Activity.RESULT_OK) { - //TODO need to refresh FamilyProfileActivity -// Intent intent = getIntent(); -// setResult(RESULT_OK, intent); Intent intent = new Intent(FamilyOtherMemberProfileActivity.this, FamilyProfileActivity.class); intent.putExtras(getIntent().getExtras()); startActivity(intent); @@ -261,7 +259,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { try { String jsonString = data.getStringExtra(Constants.JSON_FORM_EXTRA.JSON); - JSONObject form = new JSONObject(jsonString); if (form.getString(JsonFormUtils.ENCOUNTER_TYPE).equals(Utils.metadata().familyMemberRegister.updateEventType)) { presenter().updateFamilyMember(jsonString); @@ -273,7 +270,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { break; default: break; - } } @@ -309,7 +305,6 @@ private void refreshList(Fragment fragment) { } } - @Override public void onClick(View view) { diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/fragment/AncRegisterFragment.java b/opensrp-chw/src/main/java/org/smartregister/chw/fragment/AncRegisterFragment.java index 26a462ef74..2b588be320 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/fragment/AncRegisterFragment.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/fragment/AncRegisterFragment.java @@ -11,24 +11,32 @@ import android.widget.TextView; import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.Days; +import org.joda.time.format.DateTimeFormat; import org.smartregister.chw.R; import org.smartregister.chw.activity.AncHomeVisitActivity; +import org.smartregister.chw.activity.AncMemberProfileActivity; import org.smartregister.chw.anc.fragment.BaseAncRegisterFragment; import org.smartregister.chw.anc.util.DBConstants; +import org.smartregister.chw.anc.domain.MemberObject; import org.smartregister.chw.custom_view.NavigationMenu; import org.smartregister.chw.model.AncRegisterFragmentModel; import org.smartregister.chw.presenter.AncRegisterFragmentPresenter; +import org.smartregister.chw.provider.ChwAncRegisterProvider; import org.smartregister.chw.util.Constants; import org.smartregister.chw.util.QueryBuilder; import org.smartregister.chw.util.Utils; import org.smartregister.commonregistry.CommonFtsObject; import org.smartregister.commonregistry.CommonPersonObjectClient; import org.smartregister.commonregistry.CommonRepository; +import org.smartregister.cursoradapter.RecyclerViewPaginatedAdapter; import org.smartregister.cursoradapter.SmartRegisterQueryBuilder; import org.smartregister.view.customcontrols.CustomFontTextView; import java.text.MessageFormat; import java.util.List; +import java.util.Set; public class AncRegisterFragment extends BaseAncRegisterFragment { @@ -89,6 +97,14 @@ public void setupViews(View view) { NavigationMenu.getInstance(getActivity(), null, toolbar); } + @Override + public void initializeAdapter(Set visibleColumns) { + ChwAncRegisterProvider ancRegisterProvider = new ChwAncRegisterProvider(getActivity(), commonRepository(), visibleColumns, registerActionHandler, paginationViewHandler); + clientAdapter = new RecyclerViewPaginatedAdapter(null, ancRegisterProvider, context().commonrepository(this.tablename)); + clientAdapter.setCurrentlimit(20); + clientsView.setAdapter(clientAdapter); + } + @Override protected void onViewClicked(View view) { @@ -140,6 +156,33 @@ protected void openHomeVisit(CommonPersonObjectClient client) { AncHomeVisitActivity.startMe(getActivity(), baseEntityId); } + @Override + protected void openProfile(CommonPersonObjectClient client) { + String lmp = client.getColumnmaps().get(DBConstants.KEY.LAST_MENSTRUAL_PERIOD); + int ga = Days.daysBetween(DateTimeFormat.forPattern("dd-MM-yyyy").parseDateTime(lmp), new DateTime()).getDays() / 7; + String uniqueId = String.format(getString(R.string.unique_id_text), client.getColumnmaps().get(DBConstants.KEY.UNIQUE_ID)); + String gest_age = String.format(getString(R.string.gest_age), String.valueOf(ga)) + " " + getString(R.string.gest_age_weeks); + + String memberName = Utils.getAncMemberNameAndAge( + client.getColumnmaps().get(DBConstants.KEY.FIRST_NAME), + client.getColumnmaps().get(DBConstants.KEY.MIDDLE_NAME), + client.getColumnmaps().get(DBConstants.KEY.LAST_NAME), + client.getColumnmaps().get(DBConstants.KEY.DOB)); + + MemberObject memberObject = new MemberObject(memberName, + gest_age, + client.getColumnmaps().get(DBConstants.KEY.VILLAGE_TOWN), + uniqueId, + client.getCaseId(), + client.getColumnmaps().get(DBConstants.KEY.RELATIONAL_ID), + client.getColumnmaps().get(DBConstants.KEY.FAMILY_HEAD), + client.getColumnmaps().get(DBConstants.KEY.PRIMARY_CAREGIVER), + client.getColumnmaps().get(DBConstants.KEY.FIRST_NAME) + ); + + AncMemberProfileActivity.startMe(getActivity(), memberObject); + } + private void switchViews(View dueOnlyLayout, boolean isPress) { TextView dueOnlyTextView = dueOnlyLayout.findViewById(R.id.due_only_text_view); if (isPress) { @@ -149,6 +192,7 @@ private void switchViews(View dueOnlyLayout, boolean isPress) { } } + @Override public void onResume() { super.onResume(); @@ -189,7 +233,7 @@ private String dueFilterAndSortQuery() { .searchQueryFts(tablename, joinTable, mainCondition, filters, Sortqueries, clientAdapter.getCurrentlimit(), clientAdapter.getCurrentoffset()); sql = sql.replace(CommonFtsObject.idColumn, CommonFtsObject.relationalIdColumn); - sql = sql.replace(CommonFtsObject.searchTableName(Constants.TABLE_NAME.FAMILY), CommonFtsObject.searchTableName(Constants.TABLE_NAME.CHILD)); + sql = sql.replace(CommonFtsObject.searchTableName(Constants.TABLE_NAME.FAMILY), CommonFtsObject.searchTableName(Constants.TABLE_NAME.ANC_MEMBER)); List ids = commonRepository().findSearchIds(sql); query = sqb.toStringFts(ids, tablename, CommonRepository.ID_COLUMN, Sortqueries); @@ -213,10 +257,14 @@ private String defaultFilterAndSortQuery() { String query = ""; StringBuilder customFilter = new StringBuilder(); if (StringUtils.isNotBlank(filters)) { - customFilter.append(MessageFormat.format(" where {0}.{1} like ''%{2}%'' ", Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.FIRST_NAME, filters)); + customFilter.append(MessageFormat.format(" where ( {0}.{1} like ''%{2}%'' ", Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.FIRST_NAME, filters)); customFilter.append(MessageFormat.format(" or {0}.{1} like ''%{2}%'' ", Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.LAST_NAME, filters)); customFilter.append(MessageFormat.format(" or {0}.{1} like ''%{2}%'' ", Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.MIDDLE_NAME, filters)); - customFilter.append(MessageFormat.format(" or {0}.{1} = ''{2}'' ", Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.UNIQUE_ID, filters)); + customFilter.append(MessageFormat.format(" or {0}.{1} = ''{2}'' ) ", Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.UNIQUE_ID, filters)); + + if (dueFilterActive) { + customFilter.append(MessageFormat.format(" and ( {0}) ", presenter().getDueFilterCondition())); + } } try { if (isValidFilterForFts(commonRepository())) { @@ -262,4 +310,41 @@ public Cursor loadInBackground() { protected String getMainCondition() { return presenter().getMainCondition(); } + + @Override + public void countExecute() { + + Cursor c = null; + try { + + String query = "select count(*) from " + presenter().getMainTable() + " inner join " + Constants.TABLE_NAME.FAMILY_MEMBER + + " on " + presenter().getMainTable() + "." + DBConstants.KEY.BASE_ENTITY_ID + " = " + + Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.BASE_ENTITY_ID + + " where " + presenter().getMainCondition(); + + if (StringUtils.isNotBlank(filters)) { + query = query + " and ( " + filters + " ) "; + } + + if (dueFilterActive) { + query = query + " and ( " + presenter().getDueFilterCondition() + " ) "; + } + + c = commonRepository().rawCustomQueryForAdapter(query); + c.moveToFirst(); + clientAdapter.setTotalcount(c.getInt(0)); + Log.v("total count here", "" + clientAdapter.getTotalcount()); + + clientAdapter.setCurrentlimit(20); + clientAdapter.setCurrentoffset(0); + + + } catch (Exception e) { + Log.e(getClass().getName(), e.toString(), e); + } finally { + if (c != null) { + c.close(); + } + } + } } diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/fragment/IndividualProfileRemoveFragment.java b/opensrp-chw/src/main/java/org/smartregister/chw/fragment/IndividualProfileRemoveFragment.java index 67f8c4555b..cc28e542e5 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/fragment/IndividualProfileRemoveFragment.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/fragment/IndividualProfileRemoveFragment.java @@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; import org.smartregister.chw.R; +import org.smartregister.chw.activity.AncRegisterActivity; import org.smartregister.chw.activity.FamilyRegisterActivity; import org.smartregister.chw.activity.IndividualProfileRemoveActivity; import org.smartregister.chw.contract.FamilyRemoveMemberContract; @@ -104,6 +105,9 @@ public void confirmRemove(final JSONObject form) { @Override public void run() { getPresenter().processRemoveForm(form); + Intent intent = new Intent(getActivity(), AncRegisterActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); } }); dialog.setOnRemoveActivity(new Runnable() { diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/fragment/JobAidsDashboardFragment.java b/opensrp-chw/src/main/java/org/smartregister/chw/fragment/JobAidsDashboardFragment.java index 2036c8d7ce..c995180e57 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/fragment/JobAidsDashboardFragment.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/fragment/JobAidsDashboardFragment.java @@ -110,6 +110,7 @@ private void buildVisualisations() { Map children_0_24_UpToDateVaccinations = new HashMap<>(); Map children_0_24_OverdueVaccinations = new HashMap<>(); + for (Map indicatorTallyMap : indicatorTallies) { for (String key : indicatorTallyMap.keySet()) { switch (key) { @@ -321,7 +322,7 @@ public void onLoadFinished(@NonNull Loader>> lo @Override public void onLoaderReset(@NonNull Loader>> loader) { - // Clean up or release resources + // Clean up or release resources } @Override @@ -350,4 +351,4 @@ public void handleOnSelectEvent(PieChartSlice sliceValue) { } } -} +} \ No newline at end of file diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/helper/RulesEngineHelper.java b/opensrp-chw/src/main/java/org/smartregister/chw/helper/RulesEngineHelper.java index 4b661dbd73..5afb2da3f1 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/helper/RulesEngineHelper.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/helper/RulesEngineHelper.java @@ -9,6 +9,7 @@ import org.jeasy.rules.core.InferenceRulesEngine; import org.jeasy.rules.core.RulesEngineParameters; import org.jeasy.rules.mvel.MVELRuleFactory; +import org.smartregister.chw.rule.AncVisitAlertRule; import org.smartregister.chw.rule.HomeAlertRule; import org.smartregister.chw.rule.ICommonRule; @@ -86,6 +87,20 @@ public String getButtonAlertStatus(HomeAlertRule alertRule, Rules rules) { return alertRule.getButtonStatus(); } + public String getButtonAlertStatus(AncVisitAlertRule alertRule, Rules rules) { + + if (rules == null) { + return null; + } + + Facts facts = new Facts(); + facts.put(alertRule.getRuleKey(), alertRule); + + processDefaultRules(rules, facts); + + return alertRule.getButtonStatus(); + } + public Rules rules(String rulesFile) { return getRulesFromAsset(RULE_FOLDER_PATH + rulesFile); diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/interactor/NavigationInteractor.java b/opensrp-chw/src/main/java/org/smartregister/chw/interactor/NavigationInteractor.java index 33d06e56cf..14d58846d7 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/interactor/NavigationInteractor.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/interactor/NavigationInteractor.java @@ -12,6 +12,7 @@ import org.smartregister.family.util.AppExecutors; import org.smartregister.family.util.DBConstants; +import java.text.MessageFormat; import java.util.Date; import timber.log.Timber; @@ -56,6 +57,12 @@ private int getCount(String tableName) { mainCondition = String.format(" %s is null AND %s", DBConstants.KEY.DATE_REMOVED, ChildDBConstants.childAgeLimitFilter()); } else if (tableName.equalsIgnoreCase(Constants.TABLE_NAME.FAMILY)) { mainCondition = String.format(" %s is null ", DBConstants.KEY.DATE_REMOVED); + } else if (tableName.equalsIgnoreCase(Constants.TABLE_NAME.ANC_MEMBER)) { + mainCondition = MessageFormat.format(" inner join {0} on {1}.{2} = {3}.{4} where {5}.{6} is null ", + Constants.TABLE_NAME.FAMILY_MEMBER, + Constants.TABLE_NAME.FAMILY_MEMBER, DBConstants.KEY.BASE_ENTITY_ID, + Constants.TABLE_NAME.ANC_MEMBER, DBConstants.KEY.BASE_ENTITY_ID, + DBConstants.KEY.DATE_REMOVED); // String.format(" %s is null ", DBConstants.KEY.DATE_REMOVED); } else { mainCondition = " 1 = 1 "; } diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/model/AncRegisterFragmentModel.java b/opensrp-chw/src/main/java/org/smartregister/chw/model/AncRegisterFragmentModel.java index 34efa0f838..3e6337f155 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/model/AncRegisterFragmentModel.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/model/AncRegisterFragmentModel.java @@ -2,6 +2,7 @@ import org.smartregister.chw.anc.model.BaseAncRegisterFragmentModel; import org.smartregister.chw.util.ChildDBConstants; +import org.smartregister.chw.util.ChwDBConstants; import org.smartregister.chw.util.Constants; import org.smartregister.cursoradapter.SmartRegisterQueryBuilder; import org.smartregister.family.util.DBConstants; @@ -27,13 +28,21 @@ protected String[] mainColumns(String tableName) { columnList.add(tableName + "." + DBConstants.KEY.LAST_INTERACTED_WITH); columnList.add(tableName + "." + DBConstants.KEY.BASE_ENTITY_ID); + columnList.add(tableName + "." + ChwDBConstants.LMP); + columnList.add(tableName + "." + ChildDBConstants.KEY.LAST_HOME_VISIT); + columnList.add(tableName + "." + ChwDBConstants.VISIT_NOT_DONE); columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.RELATIONAL_ID + " as " + ChildDBConstants.KEY.RELATIONAL_ID); columnList.add(tableName + "." + org.smartregister.chw.anc.util.DBConstants.KEY.LAST_MENSTRUAL_PERIOD); columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.FIRST_NAME); columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.MIDDLE_NAME); columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.LAST_NAME); columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.DOB); + columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.UNIQUE_ID); + columnList.add(Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.RELATIONAL_ID); columnList.add(Constants.TABLE_NAME.FAMILY + "." + DBConstants.KEY.VILLAGE_TOWN); + columnList.add(Constants.TABLE_NAME.FAMILY + "." + DBConstants.KEY.FAMILY_HEAD); + columnList.add(Constants.TABLE_NAME.FAMILY + "." + DBConstants.KEY.PRIMARY_CAREGIVER); + columnList.add(Constants.TABLE_NAME.FAMILY + "." + DBConstants.KEY.FIRST_NAME); return columnList.toArray(new String[columnList.size()]); } diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/model/FamilyProfileMemberModel.java b/opensrp-chw/src/main/java/org/smartregister/chw/model/FamilyProfileMemberModel.java index bee92b1294..393de7409a 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/model/FamilyProfileMemberModel.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/model/FamilyProfileMemberModel.java @@ -10,7 +10,8 @@ public class FamilyProfileMemberModel extends BaseFamilyProfileMemberModel { protected String[] mainColumns(String tableName) { String[] columns = super.mainColumns(tableName); String[] newColumns = new String[]{ - tableName + "." + ChildDBConstants.KEY.ENTITY_TYPE + tableName + "." + ChildDBConstants.KEY.ENTITY_TYPE, + tableName + "." + org.smartregister.chw.util.Constants.JsonAssets.FAMILY_MEMBER.PHONE_NUMBER }; return ArrayUtils.addAll(columns, newColumns); diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncMemberProfilePresenter.java b/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncMemberProfilePresenter.java new file mode 100644 index 0000000000..14a4c7fc47 --- /dev/null +++ b/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncMemberProfilePresenter.java @@ -0,0 +1,56 @@ +package org.smartregister.chw.presenter; + +import android.util.Log; + +import org.apache.commons.lang3.tuple.Triple; +import org.smartregister.chw.anc.contract.AncMemberProfileContract; +import org.smartregister.chw.anc.presenter.BaseAncMemberProfilePresenter; +import org.smartregister.chw.anc.domain.MemberObject; +import org.smartregister.commonregistry.CommonPersonObjectClient; +import org.smartregister.family.contract.FamilyProfileContract; + +public class AncMemberProfilePresenter extends BaseAncMemberProfilePresenter implements FamilyProfileContract.InteractorCallBack { + + private static final String TAG = AncMemberProfilePresenter.class.getCanonicalName(); + + public AncMemberProfilePresenter(AncMemberProfileContract.View view, MemberObject memberObject) { + super(view, memberObject); + } + + public void startFormForEdit(CommonPersonObjectClient commonPersonObject) { +// TODO Implement + } + + @Override + public void refreshProfileTopSection(CommonPersonObjectClient client) { +// TODO Implement + } + + @Override + public void onUniqueIdFetched(Triple triple, String entityId) { +// TODO Implement + Log.d(TAG, "onUniqueIdFetched unimplemented"); + } + + @Override + public void onNoUniqueId() { +// TODO Implement + Log.d(TAG, "onNoUniqueId unimplemented"); + } + + @Override + public void onRegistrationSaved(boolean isEditMode) { +// TODO Implement + Log.d(TAG, "onRegistrationSaved unimplemented"); + } + + public AncMemberProfileContract.View getView() { + if (view != null) { + return view.get(); + } else { + return null; + } + } +} + + diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncRegisterFragmentPresenter.java b/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncRegisterFragmentPresenter.java index 58ca02651d..606ce61cd0 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncRegisterFragmentPresenter.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/presenter/AncRegisterFragmentPresenter.java @@ -3,6 +3,7 @@ import org.smartregister.chw.R; import org.smartregister.chw.anc.contract.AncRegisterFragmentContract; import org.smartregister.chw.anc.presenter.BaseAncRegisterFragmentPresenter; +import org.smartregister.chw.anc.util.DBConstants; import org.smartregister.chw.util.Constants; public class AncRegisterFragmentPresenter extends BaseAncRegisterFragmentPresenter { @@ -23,4 +24,8 @@ public String getMainTable() { return Constants.TABLE_NAME.ANC_MEMBER; } + @Override + public String getMainCondition() { + return " " + Constants.TABLE_NAME.FAMILY_MEMBER + "." + DBConstants.KEY.DATE_REMOVED + " is null "; + } } diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/presenter/FamilyOtherMemberActivityPresenter.java b/opensrp-chw/src/main/java/org/smartregister/chw/presenter/FamilyOtherMemberActivityPresenter.java index 1c61b7988a..f255fb7005 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/presenter/FamilyOtherMemberActivityPresenter.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/presenter/FamilyOtherMemberActivityPresenter.java @@ -95,7 +95,6 @@ public void updateFamilyMember(String jsonString) { if (familyEventClient == null) { return; } - profileInteractor.saveRegistration(familyEventClient, jsonString, true, this); } catch (Exception e) { getView().hideProgressDialog(); diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/provider/ChwAncRegisterProvider.java b/opensrp-chw/src/main/java/org/smartregister/chw/provider/ChwAncRegisterProvider.java new file mode 100644 index 0000000000..58e8c7e231 --- /dev/null +++ b/opensrp-chw/src/main/java/org/smartregister/chw/provider/ChwAncRegisterProvider.java @@ -0,0 +1,133 @@ +package org.smartregister.chw.provider; + +import android.content.Context; +import android.database.Cursor; +import android.os.AsyncTask; +import android.text.TextUtils; +import android.view.View; +import android.widget.Button; + +import org.jeasy.rules.api.Rules; +import org.smartregister.chw.R; +import org.smartregister.chw.anc.provider.AncRegisterProvider; +import org.smartregister.chw.application.ChwApplication; +import org.smartregister.chw.interactor.ChildProfileInteractor; +import org.smartregister.chw.util.AncHomeVisitUtil; +import org.smartregister.chw.util.AncVisit; +import org.smartregister.chw.util.ChildDBConstants; +import org.smartregister.chw.util.ChwDBConstants; +import org.smartregister.chw.util.Constants; +import org.smartregister.chw.util.Utils; +import org.smartregister.commonregistry.CommonPersonObjectClient; +import org.smartregister.commonregistry.CommonRepository; +import org.smartregister.view.contract.SmartRegisterClient; + +import java.util.Set; + +public class ChwAncRegisterProvider extends AncRegisterProvider { + + private Context context; + private View.OnClickListener onClickListener; + + public ChwAncRegisterProvider(Context context, CommonRepository commonRepository, Set visibleColumns, View.OnClickListener onClickListener, View.OnClickListener paginationClickListener) { + super(context, commonRepository, visibleColumns, onClickListener, paginationClickListener); + this.context = context; + this.onClickListener = onClickListener; + } + + @Override + public void getView(Cursor cursor, SmartRegisterClient client, RegisterViewHolder viewHolder) { + super.getView(cursor, client, viewHolder); + + CommonPersonObjectClient pc = (CommonPersonObjectClient) client; + Utils.startAsyncTask(new UpdateAsyncTask(context, viewHolder, pc), null); + } + + private void setVisitButtonDueStatus(Context context, Button dueButton) { + dueButton.setTextColor(context.getResources().getColor(R.color.alert_in_progress_blue)); + dueButton.setText(context.getString(R.string.record_home_visit)); + dueButton.setBackgroundResource(R.drawable.blue_btn_selector); + dueButton.setOnClickListener(onClickListener); + } + + private void setVisitButtonOverdueStatus(Context context, Button dueButton, String lastVisitDays) { + dueButton.setTextColor(context.getResources().getColor(R.color.white)); + if (TextUtils.isEmpty(lastVisitDays)) { + dueButton.setText(context.getString(R.string.record_visit)); + } else { + dueButton.setText(context.getString(R.string.due_visit, lastVisitDays)); + } + dueButton.setBackgroundResource(R.drawable.overdue_red_btn_selector); + dueButton.setOnClickListener(onClickListener); + } + + private void setVisitAboveTwentyFourView(Context context, Button dueButton) { + dueButton.setTextColor(context.getResources().getColor(R.color.alert_complete_green)); + dueButton.setText(context.getString(R.string.visit_done)); + dueButton.setBackgroundColor(context.getResources().getColor(R.color.transparent)); + dueButton.setOnClickListener(null); + } + + private void setVisitLessTwentyFourView(Context context, Button dueButton) { + setVisitAboveTwentyFourView(context, dueButton); + } + + private void setVisitNotDone(Context context, Button dueButton) { + dueButton.setTextColor(context.getResources().getColor(R.color.progress_orange)); + dueButton.setText(context.getString(R.string.visit_not_done)); + dueButton.setBackgroundColor(context.getResources().getColor(R.color.transparent)); + dueButton.setOnClickListener(null); + } + + private void updateDueColumn(Context context, RegisterViewHolder viewHolder, AncVisit ancVisit) { + viewHolder.dueButton.setVisibility(View.VISIBLE); + if (ancVisit.getVisitStatus().equalsIgnoreCase(ChildProfileInteractor.VisitType.DUE.name())) { + setVisitButtonDueStatus(context, viewHolder.dueButton); + } else if (ancVisit.getVisitStatus().equalsIgnoreCase(ChildProfileInteractor.VisitType.OVERDUE.name())) { + setVisitButtonOverdueStatus(context, viewHolder.dueButton, ancVisit.getNoOfMonthDue()); + } else if (ancVisit.getVisitStatus().equalsIgnoreCase(ChildProfileInteractor.VisitType.LESS_TWENTY_FOUR.name())) { + setVisitLessTwentyFourView(context, viewHolder.dueButton); + } else if (ancVisit.getVisitStatus().equalsIgnoreCase(ChildProfileInteractor.VisitType.VISIT_THIS_MONTH.name())) { + setVisitAboveTwentyFourView(context, viewHolder.dueButton); + } else if (ancVisit.getVisitStatus().equalsIgnoreCase(ChildProfileInteractor.VisitType.NOT_VISIT_THIS_MONTH.name())) { + setVisitNotDone(context, viewHolder.dueButton); + } + } + + private class UpdateAsyncTask extends AsyncTask { + private final RegisterViewHolder viewHolder; + private final CommonPersonObjectClient pc; + private final Context context; + + private final Rules rules; + private AncVisit ancVisit; + + private UpdateAsyncTask(Context context, RegisterViewHolder viewHolder, CommonPersonObjectClient pc) { + this.context = context; + this.viewHolder = viewHolder; + this.pc = pc; + this.rules = ChwApplication.getInstance().getRulesEngineHelper().rules(Constants.RULE_FILE.ANC_HOME_VISIT); + } + + @Override + protected Void doInBackground(Void... params) { + //map = getChildDetails(pc.getCaseId()); + + String lmpDate = org.smartregister.util.Utils.getValue(pc.getColumnmaps(), ChwDBConstants.LMP, false); + String visitDate = org.smartregister.util.Utils.getValue(pc.getColumnmaps(), ChildDBConstants.KEY.LAST_HOME_VISIT, false); + String lastVisitNotDone = org.smartregister.util.Utils.getValue(pc.getColumnmaps(), ChwDBConstants.VISIT_NOT_DONE, false); + + ancVisit = AncHomeVisitUtil.getVisitStatus(context, rules, lmpDate, visitDate, lastVisitNotDone); + return null; + } + + @Override + protected void onPostExecute(Void param) { + // Update status column + if (ancVisit != null && !ancVisit.getVisitStatus().equalsIgnoreCase(ChildProfileInteractor.VisitType.EXPIRY.name())) { + updateDueColumn(context, viewHolder, ancVisit); + } + } + } + +} diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/rule/AncVisitAlertRule.java b/opensrp-chw/src/main/java/org/smartregister/chw/rule/AncVisitAlertRule.java new file mode 100644 index 0000000000..9076903a6f --- /dev/null +++ b/opensrp-chw/src/main/java/org/smartregister/chw/rule/AncVisitAlertRule.java @@ -0,0 +1,113 @@ +package org.smartregister.chw.rule; + +import android.content.Context; + +import org.apache.commons.lang3.StringUtils; +import org.joda.time.Days; +import org.joda.time.LocalDate; +import org.joda.time.Months; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.smartregister.chw.R; +import org.smartregister.chw.interactor.ChildProfileInteractor; + +public class AncVisitAlertRule implements ICommonRule { + + public String buttonStatus = ChildProfileInteractor.VisitType.DUE.name(); + private final int[] monthNames = {R.string.january, R.string.february, R.string.march, R.string.april, R.string.may, R.string.june, R.string.july, R.string.august, R.string.september, R.string.october, R.string.november, R.string.december}; + + private LocalDate todayDate; + private LocalDate lastVisitDate; + private LocalDate visitNotDoneDate; + + public String noOfMonthDue; + public String noOfDayDue; + public String visitMonthName; + private Context context; + private LocalDate lmpDate; + + public AncVisitAlertRule(Context context, String lmpDate, String visitDate, String visitNotDoneDate) { + this.context = context; + + DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-yyyy"); + this.lmpDate = formatter.parseDateTime(lmpDate).toLocalDate(); + + this.todayDate = new LocalDate(); + if (StringUtils.isNotBlank(visitDate)) { + this.lastVisitDate = formatter.parseDateTime(visitDate).toLocalDate(); + } else { + this.lastVisitDate = formatter.parseDateTime(lmpDate).toLocalDate(); + } + noOfDayDue = dayDifference(this.lastVisitDate, todayDate) + " days"; + + if (StringUtils.isNotBlank(visitNotDoneDate)) { + this.visitNotDoneDate = formatter.parseDateTime(visitNotDoneDate).toLocalDate(); + } + } + + public String getButtonStatus() { + return buttonStatus; + } + + public boolean isVisitNotDone() { + return (visitNotDoneDate != null && getMonthsDifference(visitNotDoneDate, todayDate) < 1); + } + + // if lmp is greater than 1 year + public boolean isExpiry() { + return (lmpDate != null) && Months.monthsBetween(lmpDate, todayDate).getMonths() > 11; + } + + public boolean isOverdueWithinMonth(Integer value) { + int diff = getMonthsDifference((lastVisitDate != null ? lastVisitDate : lmpDate), todayDate); + if (diff >= value) { + noOfMonthDue = diff + "M"; + return true; + } + return false; + } + + public boolean isDueWithinMonth() { + if (todayDate.getDayOfMonth() == 1) { + return true; + } + if (lastVisitDate == null) { + return !isVisitThisMonth(lmpDate, todayDate); + } + + return !isVisitThisMonth(lastVisitDate, todayDate); + } + + public boolean isVisitWithinTwentyFour() { + visitMonthName = theMonth(todayDate.getMonthOfYear() - 1); + noOfDayDue = context.getString(R.string.less_than_twenty_four); + return (lastVisitDate != null) && !(lastVisitDate.isBefore(todayDate.minusDays(1)) && lastVisitDate.isBefore(todayDate)); + } + + public boolean isVisitWithinThisMonth() { + return (lastVisitDate != null) && isVisitThisMonth(lastVisitDate, todayDate); + } + + private boolean isVisitThisMonth(LocalDate lastVisit, LocalDate todayDate) { + return getMonthsDifference(lastVisit, todayDate) < 1; + } + + private int dayDifference(LocalDate date1, LocalDate date2) { + return Days.daysBetween(date1, date2).getDays(); + } + + private String theMonth(int month) { + return context.getResources().getString(monthNames[month]); + } + + private int getMonthsDifference(LocalDate date1, LocalDate date2) { + return Months.monthsBetween( + date1.withDayOfMonth(1), + date2.withDayOfMonth(1)).getMonths(); + } + + @Override + public String getRuleKey() { + return "ancVisitAlertRule"; + } +} diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/util/AncHomeVisitUtil.java b/opensrp-chw/src/main/java/org/smartregister/chw/util/AncHomeVisitUtil.java new file mode 100644 index 0000000000..38f54b7c7c --- /dev/null +++ b/opensrp-chw/src/main/java/org/smartregister/chw/util/AncHomeVisitUtil.java @@ -0,0 +1,30 @@ +package org.smartregister.chw.util; + +import android.content.Context; + +import org.apache.commons.lang3.StringUtils; +import org.jeasy.rules.api.Rules; +import org.joda.time.format.DateTimeFormat; +import org.smartregister.chw.application.ChwApplication; +import org.smartregister.chw.rule.AncVisitAlertRule; + +public class AncHomeVisitUtil { + + public static AncVisit getVisitStatus(Context context, Rules rules, String lmpDate, String visitDate, String visitNotDate) { + AncVisitAlertRule ancVisitAlertRule = new AncVisitAlertRule(context, lmpDate, visitDate, visitNotDate); + ChwApplication.getInstance().getRulesEngineHelper().getButtonAlertStatus(ancVisitAlertRule, rules); + return getVisitStatus(ancVisitAlertRule, visitDate); + } + + public static AncVisit getVisitStatus(AncVisitAlertRule homeAlertRule, String visitDate) { + AncVisit ancVisit = new AncVisit(); + ancVisit.setVisitStatus(homeAlertRule.buttonStatus); + ancVisit.setNoOfMonthDue(homeAlertRule.noOfMonthDue); + ancVisit.setLastVisitDays(homeAlertRule.noOfDayDue); + ancVisit.setLastVisitMonthName(homeAlertRule.visitMonthName); + if (StringUtils.isNotBlank(visitDate)) { + ancVisit.setLastVisitTime(DateTimeFormat.forPattern("dd-MM-yyyy").parseDateTime(visitDate).getMillis()); + } + return ancVisit; + } +} diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/util/AncVisit.java b/opensrp-chw/src/main/java/org/smartregister/chw/util/AncVisit.java new file mode 100644 index 0000000000..c56ad6b0fb --- /dev/null +++ b/opensrp-chw/src/main/java/org/smartregister/chw/util/AncVisit.java @@ -0,0 +1,4 @@ +package org.smartregister.chw.util; + +public class AncVisit extends ChildVisit { +} diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/util/ChwDBConstants.java b/opensrp-chw/src/main/java/org/smartregister/chw/util/ChwDBConstants.java index 4c0ff1faa7..6526133a3a 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/util/ChwDBConstants.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/util/ChwDBConstants.java @@ -15,5 +15,8 @@ public interface ChwDBConstants { String LEADER = "leader"; String OTHER_LEADER = "leader_other"; String WRA = "wra"; + String LMP = "last_menstrual_period"; + String VISIT_NOT_DONE = "visit_not_done"; + String PHONE_NUMBER = "phone_number"; } \ No newline at end of file diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/util/Constants.java b/opensrp-chw/src/main/java/org/smartregister/chw/util/Constants.java index 36fa74b852..4d175b7a10 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/util/Constants.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/util/Constants.java @@ -35,6 +35,8 @@ public static final class EventType { public static final String REMOVE_FAMILY = "Remove Family"; public static final String ANC_REGISTRATION = "ANC Registration"; + public static final String ANC_HOME_VISIT = "ANC Home Visit"; + public static final String UPDATE_ANC_REGISTRATION = "Update ANC Registration"; } public static class JSON_FORM { @@ -58,6 +60,8 @@ public static class ANC_HOME_VISIT { public static final String ANC_COUNSELING = "anc_hv_counseling"; public static final String SLEEPING_UNDER_LLITN = "anc_hv_sleeping_under_llitn"; public static final String ANC_CARD_RECEIVED = "anc_hv_anc_card_received"; + public static final String TT_IMMUNIZATION = "anc_hv_tt_immunization"; + public static final String IPTP_SP = "anc_hv_anc_iptp_sp"; public static final String HEALTH_FACILITY_VISIT = "anc_hv_health_facility_visit"; @@ -112,11 +116,12 @@ public static final class DrawerMenu { public static final String LD = "L&D"; public static final String PNC = "PNC"; public static final String FAMILY_PLANNING = "Family Planning"; - public static final String MALARIA = "MALARIA"; + public static final String MALARIA = "Malaria"; } public static final class RULE_FILE { public static final String HOME_VISIT = "home-visit-rules.yml"; + public static final String ANC_HOME_VISIT = "anc-home-visit-rules.yml"; public static final String BIRTH_CERT = "birth-cert-rules.yml"; public static final String SERVICE = "service-rules.yml"; } diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/util/JsonFormUtils.java b/opensrp-chw/src/main/java/org/smartregister/chw/util/JsonFormUtils.java index a44a3ed072..c98a53d63d 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/util/JsonFormUtils.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/util/JsonFormUtils.java @@ -1,11 +1,14 @@ package org.smartregister.chw.util; import android.content.Context; +import android.database.Cursor; import android.graphics.Bitmap; import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import com.vijay.jsonwizard.constants.JsonFormConstants; + import net.sqlcipher.database.SQLiteDatabase; import org.apache.commons.lang3.StringUtils; @@ -59,7 +62,10 @@ import java.util.Map; import java.util.UUID; +import timber.log.Timber; + import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.smartregister.util.AssetHandler.jsonStringToJava; /** * Created by keyman on 13/11/2018. @@ -118,58 +124,6 @@ public static JSONObject getOnsIllnessFormAsJson(JSONObject form, String baseEnt } - public static Pair processAncRegistrationForm(AllSharedPreferences allSharedPreferences, String jsonString){ - Triple ancFormParams = validateParameters(jsonString); - if(!ancFormParams.getLeft()){ - return null; - } - - JSONObject jsonForm = ancFormParams.getMiddle(); - JSONArray fields = ancFormParams.getRight(); - String entityId = getString(jsonForm, ENTITY_ID); - lastInteractedWith(fields); - - - Event baseEvent = org.smartregister.util.JsonFormUtils.createEvent(fields, getJSONObject(jsonForm, METADATA), formTag(allSharedPreferences), entityId, - getString(jsonForm, ENCOUNTER_TYPE), org.smartregister.chw.util.Constants.TABLE_NAME.ANC_MEMBER); - - Client baseClient = org.smartregister.util.JsonFormUtils.createBaseClient(fields, formTag(allSharedPreferences), entityId); - tagSyncMetadata(allSharedPreferences, baseEvent); - - - return Pair.create(baseClient, baseEvent); - - } - - - public static Pair processCounselingForm(AllSharedPreferences allSharedPreferences, String jsonString) { - try { - - Triple registrationFormParams = validateParameters(jsonString); - if (!registrationFormParams.getLeft()) { - return null; - } - - JSONObject jsonForm = registrationFormParams.getMiddle(); - JSONArray fields = registrationFormParams.getRight(); - - String entityId = getString(jsonForm, ENTITY_ID); - - lastInteractedWith(fields); - - Client baseClient = org.smartregister.util.JsonFormUtils.createBaseClient(fields, formTag(allSharedPreferences), entityId); - Event baseEvent = org.smartregister.util.JsonFormUtils.createEvent(fields, getJSONObject(jsonForm, METADATA), formTag(allSharedPreferences), entityId, - getString(jsonForm, ENCOUNTER_TYPE), org.smartregister.chw.util.Constants.TABLE_NAME.CHILD); - - - tagSyncMetadata(allSharedPreferences, baseEvent);// tag docs - - return Pair.create(baseClient, baseEvent); - } catch (Exception e) { - return null; - } - } - public static Pair processBirthAndIllnessForm(AllSharedPreferences allSharedPreferences, String jsonString) { try { @@ -218,6 +172,7 @@ private static HashMap actionMap() { } return actionMap; } + public static HashMap getChoice(Context context) { HashMap choices = new HashMap<>(); choices.put(context.getResources().getString(R.string.yes), "1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); @@ -877,9 +832,112 @@ private static HashMap getEducationLevels(Context context) { return educationLevels; } + /** + * Returns a value from json form field + * + * @param jsonObject native forms jsonObject + * @param key field object key + * @return value + */ + public static String getValue(JSONObject jsonObject, String key) { + try { + JSONArray jsonArray = jsonObject.getJSONObject(JsonFormConstants.STEP1).getJSONArray(JsonFormConstants.FIELDS); + int x = 0; + while (jsonArray.length() > x) { + JSONObject jo = jsonArray.getJSONObject(x); + if (jo.getString(JsonFormConstants.KEY).equalsIgnoreCase(key)) { + return jo.getString(JsonFormConstants.VALUE); + } + x++; + } + } catch (Exception e) { + Timber.e(e); + } + return ""; + } + public interface Flavor { JSONObject getAutoJsonEditMemberFormString(String title, String formName, Context context, CommonPersonObjectClient client, String eventType, String familyName, boolean isPrimaryCaregiver); void processFieldsForMemberEdit(CommonPersonObjectClient client, JSONObject jsonObject, JSONArray jsonArray, String familyName, boolean isPrimaryCaregiver, Event ecEvent, Client ecClient) throws JSONException; } + + private static Event getEditAncLatestProperties(String baseEntityID) { + + Event ecEvent = null; + + String query_event = String.format("select json from event where baseEntityId = '%s' and eventType in ('%s','%s') order by updatedAt desc limit 1;", + baseEntityID, org.smartregister.chw.util.Constants.EventType.UPDATE_ANC_REGISTRATION, org.smartregister.chw.util.Constants.EventType.ANC_REGISTRATION); + + Cursor cursor = ChwApplication.getInstance().getRepository().getReadableDatabase().rawQuery(query_event, new String[]{}); + try { + cursor.moveToFirst(); + + while (!cursor.isAfterLast()) { + ecEvent = jsonStringToJava(cursor.getString(0), Event.class); + cursor.moveToNext(); + } + } catch (Exception e) { + Timber.e(e, e.toString()); + } finally { + cursor.close(); + } + return ecEvent; + } + + public static JSONObject getAutoJsonEditAncFormString(String baseEntityID, Context context, String formName, String eventType, String title) { + try { + + Event event = getEditAncLatestProperties(baseEntityID); + final List observations = event.getObs(); + JSONObject form = FormUtils.getInstance(context).getFormJson(formName); + LocationPickerView lpv = new LocationPickerView(context); + lpv.init(); + if (form != null) { + form.put(org.smartregister.family.util.JsonFormUtils.ENTITY_ID, baseEntityID); + form.put(org.smartregister.family.util.JsonFormUtils.ENCOUNTER_TYPE, eventType); + + JSONObject metadata = form.getJSONObject(org.smartregister.family.util.JsonFormUtils.METADATA); + String lastLocationId = LocationHelper.getInstance().getOpenMrsLocationId(lpv.getSelectedItem()); + + metadata.put(org.smartregister.family.util.JsonFormUtils.ENCOUNTER_LOCATION, lastLocationId); + JSONObject stepOne = form.getJSONObject(org.smartregister.family.util.JsonFormUtils.STEP1); + + if (StringUtils.isNotBlank(title)) { + stepOne.put(TITLE, title); + } + JSONArray jsonArray = stepOne.getJSONArray(org.smartregister.family.util.JsonFormUtils.FIELDS); + + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if (jsonObject.getString(JsonFormUtils.KEY).equalsIgnoreCase("last_menstrual_period") || + jsonObject.getString(JsonFormUtils.KEY).equalsIgnoreCase("delivery_method")) { + jsonObject.put(JsonFormUtils.READ_ONLY, true); + } + + try { + for (Obs obs : observations) { + if (obs.getFormSubmissionField().equalsIgnoreCase(jsonObject.getString("key"))) { + if (jsonObject.getString("type").equals("spinner")) + jsonObject.put(org.smartregister.family.util.JsonFormUtils.VALUE, obs.getHumanReadableValues().get(0)); + else + jsonObject.put(org.smartregister.family.util.JsonFormUtils.VALUE, obs.getValue()); + } + } + + } catch (Exception e) { + Timber.e(Log.getStackTraceString(e)); + } + } + + return form; + } + } catch (Exception e) { + Timber.e(Log.getStackTraceString(e)); + } + + return null; + } + + } diff --git a/opensrp-chw/src/main/java/org/smartregister/chw/util/Utils.java b/opensrp-chw/src/main/java/org/smartregister/chw/util/Utils.java index aec375fcbf..4f24916240 100644 --- a/opensrp-chw/src/main/java/org/smartregister/chw/util/Utils.java +++ b/opensrp-chw/src/main/java/org/smartregister/chw/util/Utils.java @@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.Days; +import org.joda.time.Period; import org.smartregister.chw.BuildConfig; import org.smartregister.chw.R; import org.smartregister.chw.contract.FamilyCallDialogContract; @@ -220,4 +221,16 @@ public static String getLocalForm(String jsonForm) { String suffix = Locale.getDefault().getLanguage().equals("fr") ? "_fr" : ""; return MessageFormat.format("{0}{1}", jsonForm, suffix); } + + public static String getAncMemberNameAndAge(String firstName, String middleName, String surName, String age) { + int integerAge = new Period(new DateTime(age), new DateTime()).getYears(); + String first_name = firstName.trim(); + String middle_name = middleName.trim(); + String sur_name = surName != null ? surName.trim() : ""; + + if (StringUtils.isNotBlank(firstName) && StringUtils.isNotBlank(middleName) && StringUtils.isNotBlank(age)) { + return (first_name + " " + middle_name + " " + sur_name).trim() + ", " + integerAge; + } + return ""; + } } diff --git a/opensrp-chw/src/main/res/menu/anc_member_profile_menu.xml b/opensrp-chw/src/main/res/menu/anc_member_profile_menu.xml new file mode 100644 index 0000000000..59f20451b2 --- /dev/null +++ b/opensrp-chw/src/main/res/menu/anc_member_profile_menu.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-chw/src/main/res/values/strings.xml b/opensrp-chw/src/main/res/values/strings.xml index 25ed98c2a0..cb13b7d977 100644 --- a/opensrp-chw/src/main/res/values/strings.xml +++ b/opensrp-chw/src/main/res/values/strings.xml @@ -169,9 +169,12 @@ REMOVE Birth Date Age + registration When was %s immunization done? No vaccines were done Edit Family Member + Edit ANC Registration + ANC Registration LAST VISIT Edit Child Under 5 @@ -203,6 +206,8 @@ Remove this person Registration info ANC Registration + ANC Registration info + Pregnancy outcome Log out as Job Aids Refresh indicators @@ -215,13 +220,15 @@ Children (12–59 months) who were not dewormed in the last 6 months Children (6–59 months) who received Vitamin A in the last 6 months Children (6–59 months) who did not receive Vitamin A in the last 6 months - Children (0–5 months) exclusively breastfeeding Children (0–5 months) not exclusively breastfeeding + + Children (0–5 months) exclusively breastfeeding Children (6–23 months) up to date on MNP supplementation Children (6–23 months) overdue on MNP supplementation Children (0–23 months) up to date on immunizations Children (6–23 months) who are currently overdue for at least one or more vaccinations OPV 0 not included + Yes No Powered by @@ -235,7 +242,7 @@ ANC PNC FP - MALARIA + Malaria Refer to facility Due only @@ -281,4 +288,10 @@ ANC Card Received Sleeping under a LLITN ANC Counseling + TT {0} Immunization + IPTp-SP dose {0} + GA: %1$s + weeks + + diff --git a/opensrp-chw/src/wcaro/assets/ec_client_classification.json b/opensrp-chw/src/wcaro/assets/ec_client_classification.json index c087f7c146..eed82bb1ac 100644 --- a/opensrp-chw/src/wcaro/assets/ec_client_classification.json +++ b/opensrp-chw/src/wcaro/assets/ec_client_classification.json @@ -99,6 +99,13 @@ "creates_case": [ "ec_anc_register" ] + }, + { + "field": "eventType", + "field_value": "ANC Home Visit", + "creates_case": [ + "ec_anc_register" + ] } ] } diff --git a/opensrp-chw/src/wcaro/assets/ec_client_fields.json b/opensrp-chw/src/wcaro/assets/ec_client_fields.json index dbc0213880..caa8c435b3 100644 --- a/opensrp-chw/src/wcaro/assets/ec_client_fields.json +++ b/opensrp-chw/src/wcaro/assets/ec_client_fields.json @@ -574,6 +574,30 @@ "field": "obs.fieldCode", "concept": "1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" } + }, + { + "column_name": "last_home_visit", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "anc_visit_date" + } + }, + { + "column_name": "visit_not_done", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "anc_visit_not_done_date" + } + }, + { + "column_name": "anc_card", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "1719AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } } ] } diff --git a/opensrp-chw/src/wcaro/assets/json.form/anc_hv_anc_iptp_sp.json b/opensrp-chw/src/wcaro/assets/json.form/anc_hv_anc_iptp_sp.json new file mode 100644 index 0000000000..df0a030413 --- /dev/null +++ b/opensrp-chw/src/wcaro/assets/json.form/anc_hv_anc_iptp_sp.json @@ -0,0 +1,69 @@ +{ + "count": "1", + "encounter_type": "ANC Registration", + "entity_id": "", + "metadata": { + "start": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "start", + "openmrs_entity_id": "163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "end": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "end", + "openmrs_entity_id": "163138AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "today": { + "openmrs_entity_parent": "", + "openmrs_entity": "encounter", + "openmrs_entity_id": "encounter_date" + }, + "deviceid": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "deviceid", + "openmrs_entity_id": "163149AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "subscriberid": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "subscriberid", + "openmrs_entity_id": "163150AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "simserial": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "simserial", + "openmrs_entity_id": "163151AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "phonenumber": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "phonenumber", + "openmrs_entity_id": "163152AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "encounter_location": "" + }, + "step1": { + "title": "IPTp-SP 1st dose", + "fields": [ + { + "key": "iptp1_date", + "openmrs_entity_parent": "", + "openmrs_entity": "", + "openmrs_entity_id": "", + "type": "date_picker", + "image": "form_iptp_sp", + "hint": "When was IPTp-SP 1st dose given?", + "min_date": "today-120y", + "max_date": "today", + "v_required": { + "value": "true", + "err": "Please enter the date of birth" + } + } + ] + } +} \ No newline at end of file diff --git a/opensrp-chw/src/wcaro/assets/json.form/anc_hv_observations.json b/opensrp-chw/src/wcaro/assets/json.form/anc_hv_observations.json index 52471ec5b8..b590478f22 100644 --- a/opensrp-chw/src/wcaro/assets/json.form/anc_hv_observations.json +++ b/opensrp-chw/src/wcaro/assets/json.form/anc_hv_observations.json @@ -1,6 +1,6 @@ { "count": "1", - "encounter_type": "Observations Illness", + "encounter_type": "Home Visit - Observations Illness", "entity_id": "", "metadata": { "start": { @@ -97,7 +97,7 @@ "openmrs_choice_ids": { "Managed": "140959AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "Referred": "1648AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "No action taken" : "1107AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "No action taken": "1107AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" } } ] diff --git a/opensrp-chw/src/wcaro/assets/json.form/anc_hv_tt_immunization.json b/opensrp-chw/src/wcaro/assets/json.form/anc_hv_tt_immunization.json new file mode 100644 index 0000000000..8321688d0d --- /dev/null +++ b/opensrp-chw/src/wcaro/assets/json.form/anc_hv_tt_immunization.json @@ -0,0 +1,69 @@ +{ + "count": "1", + "encounter_type": "ANC Registration", + "entity_id": "", + "metadata": { + "start": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "start", + "openmrs_entity_id": "163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "end": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "end", + "openmrs_entity_id": "163138AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "today": { + "openmrs_entity_parent": "", + "openmrs_entity": "encounter", + "openmrs_entity_id": "encounter_date" + }, + "deviceid": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "deviceid", + "openmrs_entity_id": "163149AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "subscriberid": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "subscriberid", + "openmrs_entity_id": "163150AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "simserial": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "simserial", + "openmrs_entity_id": "163151AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "phonenumber": { + "openmrs_entity_parent": "", + "openmrs_entity": "concept", + "openmrs_data_type": "phonenumber", + "openmrs_entity_id": "163152AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "encounter_location": "" + }, + "step1": { + "title": "TT 1 immunization", + "fields": [ + { + "key": "tt1_date", + "openmrs_entity_parent": "", + "openmrs_entity": "", + "openmrs_entity_id": "", + "type": "date_picker", + "image": "form_immunization", + "hint": "When was TT 1 immunization done?", + "min_date": "today-120y", + "max_date": "today", + "v_required": { + "value": "true", + "err": "Please enter the date of birth" + } + } + ] + } +} \ No newline at end of file diff --git a/opensrp-chw/src/wcaro/assets/json.form/anc_member_registration.json b/opensrp-chw/src/wcaro/assets/json.form/anc_member_registration.json index d2f76935f8..e4bb7a0576 100644 --- a/opensrp-chw/src/wcaro/assets/json.form/anc_member_registration.json +++ b/opensrp-chw/src/wcaro/assets/json.form/anc_member_registration.json @@ -56,6 +56,8 @@ "openmrs_entity_id": "1427AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "type": "date_picker", "hint": "Last Menstrual Period (LMP)", + "label_info_title": "LMP", + "label_info_text": "LMP = first day of Last Menstrual Period. If the exact date is unknown, but the period of the month is known, use day 5 for beginning of the month, day 15 for middle of the month and day 25 for end of the month.", "expanded": false, "duration": { "label": "lmp" @@ -66,6 +68,22 @@ "err": "LMP required" } }, + { + "key": "gest_age_note", + "openmrs_entity_parent": "", + "openmrs_entity": "", + "openmrs_entity_id": "", + "type": "edit_text", + "hint": "Gestational Age (GA)", + "read_only": true, + "calculation": { + "rules-engine": { + "ex-rules": { + "rules-file": "anc_member_registration_calculation.yml" + } + } + } + }, { "key": "gest_age", "openmrs_entity_parent": "", @@ -85,7 +103,9 @@ "openmrs_entity_parent": "", "openmrs_entity": "concept", "openmrs_entity_id": "5596AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "type": "hidden", + "type": "edit_text", + "hint": "Expected Date of Delivery (EDD)", + "read_only": true, "calculation": { "rules-engine": { "ex-rules": { @@ -97,8 +117,8 @@ { "key": "no_prev_preg", "openmrs_entity_parent": "", - "openmrs_entity": "", - "openmrs_entity_id": "", + "openmrs_entity": "concept", + "openmrs_entity_id": "no_prev_preg", "type": "edit_text", "edit_type": "number", "hint": "No. of previous pregnancies", @@ -147,7 +167,7 @@ }, "v_min": { "value": "0", - "err": "Age must be equal or greater than 0" + "err": "Number must be equal or greater than 0" } }, { @@ -168,13 +188,6 @@ "v_required": { "value": false, "err": "Please specify the phone number" - }, - "relevance": { - "rules-engine": { - "ex-rules": { - "rules-file": "family_member_relevance.yml" - } - } } }, { @@ -185,6 +198,10 @@ "openmrs_data_type": "select one", "type": "spinner", "hint": "Marital status", + "v_required": { + "value": "true", + "err": "Please select one option" + }, "values": [ "Married", "Co-habiting", @@ -193,11 +210,7 @@ "openmrs_choice_ids": { "Married": "5555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "Co-habiting": "1060AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "Single": "5615AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "v_required": { - "value": "true", - "err": "Please select one option" - } + "Single": "5615AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" } } ] diff --git a/opensrp-chw/src/wcaro/assets/rule/anc-home-visit-rules.yml b/opensrp-chw/src/wcaro/assets/rule/anc-home-visit-rules.yml new file mode 100644 index 0000000000..82f39f0c80 --- /dev/null +++ b/opensrp-chw/src/wcaro/assets/rule/anc-home-visit-rules.yml @@ -0,0 +1,44 @@ +--- +name: expiry +description: expire lmp greter than 1 yr +priority: 1 +condition: "ancVisitAlertRule.isExpiry()" +actions: + - "ancVisitAlertRule.buttonStatus = 'EXPIRY'" +--- +name: visit_not_done +description: press visit not done in this month +priority: 1 +condition: "ancVisitAlertRule.isVisitNotDone()" +actions: + - "ancVisitAlertRule.buttonStatus = 'NOT_VISIT_THIS_MONTH'" +--- +name: visit_twenty_four +description: visit within twenty four hours +priority: 2 +condition: "ancVisitAlertRule.isVisitWithinTwentyFour()" +actions: + - "ancVisitAlertRule.buttonStatus = 'LESS_TWENTY_FOUR'" +--- +name: visit_this_month +description: visit grether than 24 hours but within this month +priority: 3 +condition: "ancVisitAlertRule.isVisitWithinThisMonth()" +actions: + - "ancVisitAlertRule.buttonStatus = 'VISIT_THIS_MONTH'" +--- +name: overdue +description: previous month not visited +priority: 2 +condition: "ancVisitAlertRule.isOverdueWithinMonth(1)" +actions: + - "ancVisitAlertRule.buttonStatus = 'OVERDUE'" +--- +name: due +description: due first day of month and same month +priority: 3 +condition: "ancVisitAlertRule.isDueWithinMonth()" +actions: + - "ancVisitAlertRule.buttonStatus = 'DUE'" + + diff --git a/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_calculation.yml b/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_calculation.yml index cf554c2682..2338f68ede 100644 --- a/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_calculation.yml +++ b/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_calculation.yml @@ -6,6 +6,14 @@ condition: "true" actions: - "calculation = (helper.getDifferenceDays(step1_last_menstrual_period)-helper.getDifferenceDays(helper.getDateToday())) /7" +--- +name: step1_gest_age_note +description: Gestational age calculated +priority: 1 +condition: "true" +actions: + - "calculation = step1_gest_age + ' weeks'" + --- name: step1_edd description: Edd calculated diff --git a/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_relevance.yml b/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_relevance.yml new file mode 100644 index 0000000000..dd97d0df11 --- /dev/null +++ b/opensrp-chw/src/wcaro/assets/rule/anc_member_registration_relevance.yml @@ -0,0 +1,14 @@ +--- +name: step1_name_person_assist +description: assist person relevance +priority: 1 +condition: "step1_person_assist == 'Yes'" +actions: + - "isRelevant = true" +--- +name: step1_phone_person_assist +description: assist person phone number relevance +priority: 1 +condition: "step1_person_assist == 'Yes'" +actions: + - "isRelevant = true" \ No newline at end of file diff --git a/opensrp-chw/src/wcaro/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java b/opensrp-chw/src/wcaro/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java index 62aec3cd06..a5cb03b266 100644 --- a/opensrp-chw/src/wcaro/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java +++ b/opensrp-chw/src/wcaro/java/org/smartregister/chw/interactor/AncHomeVisitInteractorFlv.java @@ -2,6 +2,7 @@ import android.content.Context; +import org.json.JSONObject; import org.smartregister.chw.R; import org.smartregister.chw.anc.contract.BaseAncHomeVisitContract; import org.smartregister.chw.anc.fragment.BaseAncHomeVisitFragment; @@ -9,7 +10,13 @@ import org.smartregister.chw.util.Constants.JSON_FORM.ANC_HOME_VISIT; import java.text.MessageFormat; +import java.text.SimpleDateFormat; import java.util.LinkedHashMap; +import java.util.Locale; + +import timber.log.Timber; + +import static org.smartregister.chw.util.JsonFormUtils.getValue; public class AncHomeVisitInteractorFlv implements AncHomeVisitInteractor.Flavor { @@ -19,30 +26,243 @@ public LinkedHashMap calculateActions(BaseAncHom Context context = view.getContext(); - actionList.put(context.getString(R.string.anc_home_visit_danger_signs), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_danger_signs), "", false, null, - ANC_HOME_VISIT.DANGER_SIGNS)); + evaluateDangerSigns(actionList, context); - actionList.put(context.getString(R.string.anc_home_visit_counseling), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_counseling), "", false, null, - ANC_HOME_VISIT.ANC_COUNSELING)); + evaluateANCCounseling(actionList, context); + evaluateSleepingUnderLLITN(view, actionList, context); - actionList.put(context.getString(R.string.anc_home_visit_sleeping_under_llitn_net), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_sleeping_under_llitn_net), "", false, - BaseAncHomeVisitFragment.getInstance(view, ANC_HOME_VISIT.SLEEPING_UNDER_LLITN, null), - null)); + evaluateANCCard(view, actionList, context); - actionList.put(context.getString(R.string.anc_home_visit_anc_card_received), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_anc_card_received), "", false, - BaseAncHomeVisitFragment.getInstance(view, ANC_HOME_VISIT.ANC_CARD_RECEIVED, null), - null)); + evaluateHealthFacilityVisit(actionList, context); - String visit = MessageFormat.format(context.getString(R.string.anc_home_visit_facility_visit), 1); - actionList.put(visit, new BaseAncHomeVisitAction(visit, "", false, null, ANC_HOME_VISIT.HEALTH_FACILITY_VISIT)); + evaluateImmunization(view, actionList, context); + + evaluateIPTP(view, actionList, context); - actionList.put("TT 1 Immunization", new BaseAncHomeVisitAction("TT 1 Immunization", "", false, null, "anc")); - actionList.put("IPTp-SP dose 1", new BaseAncHomeVisitAction("IPTp-SP dose 1", "", false, null, "anc")); actionList.put(context.getString(R.string.anc_home_visit_observations_n_illnes), new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_observations_n_illnes), "", true, null, ANC_HOME_VISIT.OBSERVATION_AND_ILLNESS)); return actionList; } + private void evaluateDangerSigns(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_danger_signs), "", false, null, + ANC_HOME_VISIT.DANGER_SIGNS); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "danger_signs_counseling"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else if (value.equalsIgnoreCase("No")) { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PENDING; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_danger_signs), ba); + } + + private void evaluateANCCounseling(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_counseling), "", false, null, + ANC_HOME_VISIT.ANC_COUNSELING); + + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value1 = getValue(jsonObject, "anc_counseling"); + String value2 = getValue(jsonObject, "birth_hf_counseling"); + String value3 = getValue(jsonObject, "nutrition_counseling"); + + if (value1.equalsIgnoreCase("Yes") && value2.equalsIgnoreCase("Yes") && value3.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_counseling), ba); + } + + private void evaluateSleepingUnderLLITN(BaseAncHomeVisitContract.View view, LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_sleeping_under_llitn_net), "", false, + BaseAncHomeVisitFragment.getInstance(view, ANC_HOME_VISIT.SLEEPING_UNDER_LLITN, null), + null); + + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "sleeping_llitn"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_sleeping_under_llitn_net), ba); + + } + + private void evaluateANCCard(BaseAncHomeVisitContract.View view, LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(context.getString(R.string.anc_home_visit_anc_card_received), "", false, + BaseAncHomeVisitFragment.getInstance(view, ANC_HOME_VISIT.ANC_CARD_RECEIVED, null), + null); + + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "anc_card"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(context.getString(R.string.anc_home_visit_anc_card_received), ba); + } + + private void evaluateHealthFacilityVisit(LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + + String visit = MessageFormat.format(context.getString(R.string.anc_home_visit_facility_visit), 1); + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(visit, "", false, null, ANC_HOME_VISIT.HEALTH_FACILITY_VISIT); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, "anc_hf_visit"); + + if (value.equalsIgnoreCase("Yes")) { + return BaseAncHomeVisitAction.Status.COMPLETED; + } else if (value.equalsIgnoreCase("No")) { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } else { + return BaseAncHomeVisitAction.Status.PENDING; + } + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(visit, ba); + } + + private void evaluateImmunization(BaseAncHomeVisitContract.View view, LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + + String immunization = MessageFormat.format(context.getString(R.string.anc_home_visit_tt_immunization), 1); + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(immunization, "", false, + BaseAncHomeVisitFragment.getInstance(view, ANC_HOME_VISIT.TT_IMMUNIZATION, null), + null); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, MessageFormat.format("tt{0}_date", 1)); + + try { + new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).parse(value); + return BaseAncHomeVisitAction.Status.COMPLETED; + } catch (Exception e) { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(immunization, ba); + } + + private void evaluateIPTP(BaseAncHomeVisitContract.View view, LinkedHashMap actionList, Context context) throws BaseAncHomeVisitAction.ValidationException { + + String iptp = MessageFormat.format(context.getString(R.string.anc_home_visit_iptp_sp), 1); + final BaseAncHomeVisitAction ba = new BaseAncHomeVisitAction(iptp, "", false, + BaseAncHomeVisitFragment.getInstance(view, ANC_HOME_VISIT.IPTP_SP, null), + null); + ba.setAncHomeVisitActionHelper(new BaseAncHomeVisitAction.AncHomeVisitActionHelper() { + @Override + public BaseAncHomeVisitAction.Status evaluateStatusOnPayload() { + if (ba.getJsonPayload() != null) { + try { + JSONObject jsonObject = new JSONObject(ba.getJsonPayload()); + + String value = getValue(jsonObject, MessageFormat.format("iptp{0}_date", 1)); + + try { + new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).parse(value); + return BaseAncHomeVisitAction.Status.COMPLETED; + } catch (Exception e) { + return BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED; + } + + } catch (Exception e) { + Timber.e(e); + } + } + return ba.computedStatus(); + } + }); + + actionList.put(iptp, ba); + } + } diff --git a/opensrp-chw/src/wcaro/res/drawable-hdpi/form_immunization.png b/opensrp-chw/src/wcaro/res/drawable-hdpi/form_immunization.png new file mode 100644 index 0000000000..9982481451 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-hdpi/form_immunization.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-hdpi/form_iptp_sp.png b/opensrp-chw/src/wcaro/res/drawable-hdpi/form_iptp_sp.png new file mode 100644 index 0000000000..98270bd6a3 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-hdpi/form_iptp_sp.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-ldpi/form_iptp_sp.png b/opensrp-chw/src/wcaro/res/drawable-ldpi/form_iptp_sp.png new file mode 100644 index 0000000000..c8a0809396 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-ldpi/form_iptp_sp.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-mdpi/form_immunization.png b/opensrp-chw/src/wcaro/res/drawable-mdpi/form_immunization.png new file mode 100644 index 0000000000..4a379012a9 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-mdpi/form_immunization.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-mdpi/form_iptp_sp.png b/opensrp-chw/src/wcaro/res/drawable-mdpi/form_iptp_sp.png new file mode 100644 index 0000000000..ddf5096cc8 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-mdpi/form_iptp_sp.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-xhdpi/form_immunization.png b/opensrp-chw/src/wcaro/res/drawable-xhdpi/form_immunization.png new file mode 100644 index 0000000000..1a724e9450 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-xhdpi/form_immunization.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-xhdpi/form_iptp_sp.png b/opensrp-chw/src/wcaro/res/drawable-xhdpi/form_iptp_sp.png new file mode 100644 index 0000000000..b6e2b79e9f Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-xhdpi/form_iptp_sp.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-xxhdpi/form_immunization.png b/opensrp-chw/src/wcaro/res/drawable-xxhdpi/form_immunization.png new file mode 100644 index 0000000000..23398797de Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-xxhdpi/form_immunization.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-xxhdpi/form_iptp_sp.png b/opensrp-chw/src/wcaro/res/drawable-xxhdpi/form_iptp_sp.png new file mode 100644 index 0000000000..46864bb11f Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-xxhdpi/form_iptp_sp.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-xxxhdpi/form_immunization.png b/opensrp-chw/src/wcaro/res/drawable-xxxhdpi/form_immunization.png new file mode 100644 index 0000000000..1ad5c7cec7 Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-xxxhdpi/form_immunization.png differ diff --git a/opensrp-chw/src/wcaro/res/drawable-xxxhdpi/form_iptp_sp.png b/opensrp-chw/src/wcaro/res/drawable-xxxhdpi/form_iptp_sp.png new file mode 100644 index 0000000000..c30890eb0e Binary files /dev/null and b/opensrp-chw/src/wcaro/res/drawable-xxxhdpi/form_iptp_sp.png differ