From ef774bf0fa27dcf2607f7d49e1705e1660a4f023 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Thu, 22 Aug 2019 16:35:32 +0300 Subject: [PATCH 01/11] Added child visit events --- opensrp-chw-anc/gradle.properties | 2 +- .../BaseAncMemberProfileActivity.java | 8 +--- .../anc/adapter/BaseAncHomeVisitAdapter.java | 19 +++++---- .../chw/anc/domain/VaccineDisplay.java | 9 +++++ .../smartregister/chw/anc/domain/Visit.java | 9 +++++ .../BaseHomeVisitImmunizationFragment.java | 18 +++++++-- .../chw/anc/model/BaseAncHomeVisitAction.java | 2 +- .../chw/anc/repository/VisitRepository.java | 40 ++++++++++++++++--- .../BasePncMemberProfileActivity.java | 8 ---- 9 files changed, 78 insertions(+), 37 deletions(-) diff --git a/opensrp-chw-anc/gradle.properties b/opensrp-chw-anc/gradle.properties index 47918d5d..7011f4a8 100644 --- a/opensrp-chw-anc/gradle.properties +++ b/opensrp-chw-anc/gradle.properties @@ -1,5 +1,5 @@ POM_SETTING_NAME=OpenSRP Client Chw Anc POM_SETTING_ARTIFACT_ID=opensrp-client-chw-anc POM_SETTING_PACKAGING=aar -VERSION_NAME=0.1.9-SNAPSHOT +VERSION_NAME=0.1.10-SNAPSHOT VERSION_CODE=1 \ No newline at end of file diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncMemberProfileActivity.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncMemberProfileActivity.java index c7990b6c..50bb5f05 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncMemberProfileActivity.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncMemberProfileActivity.java @@ -105,12 +105,7 @@ protected void onCreation() { upArrow.setColorFilter(getResources().getColor(R.color.text_blue), PorterDuff.Mode.SRC_ATOP); actionBar.setHomeAsUpIndicator(upArrow); } - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); + toolbar.setNavigationOnClickListener(v -> finish()); appBarLayout = findViewById(R.id.collapsing_toolbar_appbarlayout); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { appBarLayout.setOutlineProvider(null); @@ -374,7 +369,6 @@ public void setFamilyStatus(AlertStatus status) { } } - @Override public void setMemberName(String memberName) { text_view_anc_member_name.setText(memberName); diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java index dcc872e5..b7a22987 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java @@ -86,21 +86,20 @@ public void onBindViewHolder(@NotNull MyViewHolder holder, int position) { holder.descriptionText.setVisibility(View.VISIBLE); holder.invalidText.setVisibility(View.GONE); holder.descriptionText.setText(ancHomeVisitAction.getSubTitle()); + + boolean isOverdue = ancHomeVisitAction.getScheduleStatus() == BaseAncHomeVisitAction.ScheduleStatus.OVERDUE && + ancHomeVisitAction.isEnabled(); + + holder.descriptionText.setTextColor( + isOverdue ? context.getResources().getColor(R.color.alert_urgent_red) : + context.getResources().getColor(android.R.color.darker_gray) + ); + } else { holder.descriptionText.setVisibility(View.GONE); holder.invalidText.setVisibility(View.VISIBLE); holder.invalidText.setText(Html.fromHtml("" + ancHomeVisitAction.getDisabledMessage() + "")); } - - holder.descriptionText.setVisibility(View.VISIBLE); - - boolean isOverdue = ancHomeVisitAction.getScheduleStatus() == BaseAncHomeVisitAction.ScheduleStatus.OVERDUE && - ancHomeVisitAction.isEnabled(); - - holder.descriptionText.setTextColor( - isOverdue ? context.getResources().getColor(R.color.alert_urgent_red) : - context.getResources().getColor(android.R.color.darker_gray) - ); } else { holder.descriptionText.setVisibility(View.GONE); } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VaccineDisplay.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VaccineDisplay.java index 15782306..3dd83750 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VaccineDisplay.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VaccineDisplay.java @@ -8,6 +8,7 @@ public class VaccineDisplay { private VaccineWrapper vaccineWrapper; private Date startDate; private Date endDate; + private Date dateGiven; private Boolean isValid; public VaccineWrapper getVaccineWrapper() { @@ -34,6 +35,14 @@ public void setEndDate(Date endDate) { this.endDate = endDate; } + public Date getDateGiven() { + return dateGiven; + } + + public void setDateGiven(Date dateGiven) { + this.dateGiven = dateGiven; + } + public Boolean getValid() { return isValid; } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/Visit.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/Visit.java index b67b8ac7..71efaf8e 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/Visit.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/Visit.java @@ -8,6 +8,7 @@ public class Visit { private String visitId; private String visitType; + private String parentVisitID; private String baseEntityId; private Date date; private Date updatedAt; @@ -35,6 +36,14 @@ public void setVisitType(String visitType) { this.visitType = visitType; } + public String getParentVisitID() { + return parentVisitID; + } + + public void setParentVisitID(String parentVisitID) { + this.parentVisitID = parentVisitID; + } + public String getBaseEntityId() { return baseEntityId; } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java index 5f41fe9b..c8346942 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java @@ -120,9 +120,10 @@ public void setVaccineDisplays(Map vaccineDisplays) { this.vaccineDisplays = vaccineDisplays; // redraw all vaccine views - if (vaccineDisplays.size() > 0) + if (vaccineDisplays.size() > 0 && singleDatePicker != null) { initializeDatePicker(singleDatePicker, vaccineDisplays.entrySet().iterator().next().getValue()); - addVaccineViews(); + addVaccineViews(); + } } @Override @@ -174,6 +175,10 @@ private void initializeDatePicker(@NotNull DatePicker datePicker, @NotNull Vacci } } + private void initializeDatePicker(@NotNull DatePicker datePicker, @NotNull Date startDate, @NotNull Date endDate) { + + } + private Date getDateFromDatePicker(DatePicker datePicker) { int day = datePicker.getDayOfMonth(); int month = datePicker.getMonth(); @@ -236,16 +241,21 @@ private void onSave() { boolean multiModeActive = multipleVaccineDatePickerView.getVisibility() == View.GONE; for (VaccineView vaccineView : vaccineViews) { - VaccineWrapper wrapper = vaccineDisplays.get(vaccineView.getVaccineName()).getVaccineWrapper(); + VaccineDisplay display = vaccineDisplays.get(vaccineView.getVaccineName()); + VaccineWrapper wrapper = display.getVaccineWrapper(); if (wrapper != null) { if (!checkBoxNoVaccinesDone.isChecked() && vaccineView.getCheckBox().isChecked()) { if (vaccineView.getDatePickerView() != null && multiModeActive) { - vaccineDateMap.put(wrapper, dateFormat.format(getDateFromDatePicker(vaccineView.getDatePickerView()))); + Date dateGiven = getDateFromDatePicker(vaccineView.getDatePickerView()); + vaccineDateMap.put(wrapper, dateFormat.format(dateGiven)); + display.setDateGiven(dateGiven); } else if (vaccineDate != null) { vaccineDateMap.put(wrapper, dateFormat.format(vaccineDate)); + display.setDateGiven(vaccineDate); } } else { vaccineDateMap.put(wrapper, Constants.HOME_VISIT.VACCINE_NOT_GIVEN); + display.setDateGiven(null); } } } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java index e5cd6e00..ed205e3e 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java @@ -309,7 +309,7 @@ public enum ScheduleStatus {DUE, OVERDUE} /** * Detached processing generates separate event when form is submitted */ - public enum ProcessingMode {COMBINED, DETACHED} + public enum ProcessingMode {COMBINED, DETACHED, SEPARATE} public interface AncHomeVisitActionHelper { diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java index e36c0272..46a222f9 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java @@ -22,6 +22,7 @@ public class VisitRepository extends BaseRepository { public static final String VISIT_TABLE = "visits"; private static final String VISIT_ID = "visit_id"; private static final String VISIT_TYPE = "visit_type"; + private static final String PARENT_VISIT_ID = "parent_visit_id"; private static final String BASE_ENTITY_ID = "base_entity_id"; private static final String VISIT_DATE = "visit_date"; private static final String VISIT_JSON = "visit_json"; @@ -34,6 +35,7 @@ public class VisitRepository extends BaseRepository { "CREATE TABLE " + VISIT_TABLE + "(" + VISIT_ID + " VARCHAR NULL, " + VISIT_TYPE + " VARCHAR NULL, " + + PARENT_VISIT_ID + " VARCHAR NULL, " + BASE_ENTITY_ID + " VARCHAR NULL, " + VISIT_DATE + " VARCHAR NULL, " + VISIT_JSON + " VARCHAR NULL, " @@ -48,6 +50,10 @@ public class VisitRepository extends BaseRepository { + VISIT_TYPE + " COLLATE NOCASE , " + VISIT_DATE + " COLLATE NOCASE" + ");"; + + public static final String PARENT_VISIT_ID_INDEX = "CREATE INDEX " + VISIT_TABLE + "_" + PARENT_VISIT_ID + "_index ON " + VISIT_TABLE + + "(" + PARENT_VISIT_ID + " COLLATE NOCASE );"; + private String[] VISIT_COLUMNS = {VISIT_ID, VISIT_TYPE, BASE_ENTITY_ID, VISIT_DATE, VISIT_JSON, PRE_PROCESSED, FORM_SUBMISSION_ID, PROCESSED, UPDATED_AT, CREATED_AT}; @@ -58,12 +64,14 @@ public VisitRepository(Repository repository) { public static void createTable(SQLiteDatabase database) { database.execSQL(CREATE_VISIT_TABLE); database.execSQL(BASE_ENTITY_ID_INDEX); + database.execSQL(PARENT_VISIT_ID_INDEX); } private ContentValues createValues(Visit visit) { ContentValues values = new ContentValues(); values.put(VISIT_ID, visit.getVisitId()); values.put(VISIT_TYPE, visit.getVisitType()); + values.put(PARENT_VISIT_ID, visit.getParentVisitID()); values.put(BASE_ENTITY_ID, visit.getBaseEntityId()); values.put(VISIT_DATE, visit.getDate() != null ? visit.getDate().getTime() : null); values.put(VISIT_JSON, visit.getJson()); @@ -118,6 +126,7 @@ private List readVisits(Cursor cursor) { Visit visit = new Visit(); visit.setVisitId(cursor.getString(cursor.getColumnIndex(VISIT_ID))); visit.setVisitType(cursor.getString(cursor.getColumnIndex(VISIT_TYPE))); + visit.setParentVisitID(cursor.getString(cursor.getColumnIndex(PARENT_VISIT_ID))); visit.setPreProcessedJson(cursor.getString(cursor.getColumnIndex(PRE_PROCESSED))); visit.setBaseEntityId(cursor.getString(cursor.getColumnIndex(BASE_ENTITY_ID))); visit.setDate(new Date(Long.parseLong(cursor.getString(cursor.getColumnIndex(VISIT_DATE))))); @@ -134,7 +143,8 @@ private List readVisits(Cursor cursor) { } catch (Exception e) { Timber.e(e); } finally { - cursor.close(); + if (cursor != null) + cursor.close(); } return visits; } @@ -189,13 +199,14 @@ public List getVisits(String baseEntityID, String visitType) { } return visits; } + public List getUniqueDayLatestThreeVisits(String baseEntityID, String visitType) { List visits = new ArrayList<>(); Cursor cursor = null; try { - String query = "select STRFTIME('%Y%m%d', datetime(("+VISIT_DATE+")/1000,'unixepoch')) as d,* from "+VISIT_TABLE+" where "+VISIT_TYPE+" = '"+visitType+"' AND " + - ""+BASE_ENTITY_ID+" = '"+baseEntityID+"' group by d order by "+VISIT_DATE+" desc limit 3"; - cursor = getReadableDatabase().rawQuery(query,null); + String query = "select STRFTIME('%Y%m%d', datetime((" + VISIT_DATE + ")/1000,'unixepoch')) as d,* from " + VISIT_TABLE + " where " + VISIT_TYPE + " = '" + visitType + "' AND " + + "" + BASE_ENTITY_ID + " = '" + baseEntityID + "' group by d order by " + VISIT_DATE + " desc limit 3"; + cursor = getReadableDatabase().rawQuery(query, null); visits = readVisits(cursor); } catch (Exception e) { Timber.e(e); @@ -206,11 +217,28 @@ public List getUniqueDayLatestThreeVisits(String baseEntityID, String vis } return visits; } - public List getVisitsByVisitId(String homeVisitId) { + + public List getVisitsByVisitId(String visitID) { + List visits = new ArrayList<>(); + Cursor cursor = null; + try { + cursor = getReadableDatabase().query(VISIT_TABLE, VISIT_COLUMNS, VISIT_ID + " = ? ", new String[]{visitID}, null, null, VISIT_DATE + " DESC ", null); + visits = readVisits(cursor); + } catch (Exception e) { + Timber.e(e); + } finally { + if (cursor != null) { + cursor.close(); + } + } + return visits; + } + + public List getChildEvents(String visitID) { List visits = new ArrayList<>(); Cursor cursor = null; try { - cursor = getReadableDatabase().query(VISIT_TABLE, VISIT_COLUMNS, VISIT_ID + " = ? ", new String[]{homeVisitId}, null, null, VISIT_DATE + " DESC ", null); + cursor = getReadableDatabase().query(VISIT_TABLE, VISIT_COLUMNS, PARENT_VISIT_ID + " = ? ", new String[]{visitID}, null, null, VISIT_DATE + " DESC ", null); visits = readVisits(cursor); } catch (Exception e) { Timber.e(e); diff --git a/opensrp-chw-pnc/src/main/java/org/smartregister/chw/pnc/activity/BasePncMemberProfileActivity.java b/opensrp-chw-pnc/src/main/java/org/smartregister/chw/pnc/activity/BasePncMemberProfileActivity.java index d2974d18..f5a8bbfd 100644 --- a/opensrp-chw-pnc/src/main/java/org/smartregister/chw/pnc/activity/BasePncMemberProfileActivity.java +++ b/opensrp-chw-pnc/src/main/java/org/smartregister/chw/pnc/activity/BasePncMemberProfileActivity.java @@ -28,11 +28,8 @@ public static void startMe(Activity activity, MemberObject memberObject, String intent.putExtra(FAMILY_HEAD_NAME, familyHeadName); intent.putExtra(FAMILY_HEAD_PHONE, familyHeadPhoneNumber); activity.startActivity(intent); - - } - @Override protected void setupViews() { super.setupViews(); @@ -40,11 +37,8 @@ protected void setupViews() { titleView.setText(getString(R.string.return_to_all_pnc_women)); record_reccuringvisit_done_bar.setVisibility(View.GONE); textViewAncVisitNot.setVisibility(View.GONE); - - } - @Override public void setMemberName(String memberName) { basePncMemberProfileInteractor.getPncMotherNameDetails(MEMBER_OBJECT, text_view_anc_member_name, imageView); @@ -58,7 +52,6 @@ public void setMemberGA(String memberGA) { } } - @Override protected String getProfileType() { return Constants.MEMBER_PROFILE_TYPES.PNC; @@ -69,7 +62,6 @@ public void setRecordVisitTitle(String title) { textview_record_anc_visit.setText(getString(R.string.record_pnc_visit)); } - @Override public void openMedicalHistory() { BasePncMedicalHistoryActivity.startMe(this, MEMBER_OBJECT); From cce5ea04b8a6126ae691e46bb7ce100f7115c215 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Fri, 23 Aug 2019 07:43:01 +0300 Subject: [PATCH 02/11] Persist separate events --- .../anc/adapter/BaseAncHomeVisitAdapter.java | 4 +- .../BaseHomeVisitImmunizationFragment.java | 11 ++ .../BaseAncHomeVisitInteractor.java | 126 +++++++++++------- .../chw/anc/repository/VisitRepository.java | 29 +++- .../chw/anc/util/JsonFormUtils.java | 3 +- .../smartregister/chw/anc/util/NCUtils.java | 18 +++ 6 files changed, 142 insertions(+), 49 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java index b7a22987..83a28a7c 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java @@ -139,8 +139,10 @@ private int getCircleColor(BaseAncHomeVisitAction ancHomeVisitAction) { } private void bindClickListener(View view, final BaseAncHomeVisitAction ancHomeVisitAction) { - if (!ancHomeVisitAction.isEnabled()) + if (!ancHomeVisitAction.isEnabled() || !ancHomeVisitAction.isValid()) { view.setOnClickListener(null); + return; + } view.setOnClickListener(v -> { if (StringUtils.isNotBlank(ancHomeVisitAction.getFormName())) { diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java index c8346942..21108066 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java @@ -249,13 +249,16 @@ private void onSave() { Date dateGiven = getDateFromDatePicker(vaccineView.getDatePickerView()); vaccineDateMap.put(wrapper, dateFormat.format(dateGiven)); display.setDateGiven(dateGiven); + display.setValid(true); } else if (vaccineDate != null) { vaccineDateMap.put(wrapper, dateFormat.format(vaccineDate)); display.setDateGiven(vaccineDate); + display.setValid(true); } } else { vaccineDateMap.put(wrapper, Constants.HOME_VISIT.VACCINE_NOT_GIVEN); display.setDateGiven(null); + display.setValid(false); } } } @@ -272,6 +275,14 @@ private void onSave() { } } + /** + * reset the view payload + */ + public void resetViewPayload() { + jsonObject = null; + visitView.onDialogOptionUpdated(""); + } + /** * executed to close the vaccine screen */ diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java index 1c7c6e84..955be425 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java @@ -86,49 +86,7 @@ public void submitVisit(final boolean editMode, final String memberID, final Map final Runnable runnable = () -> { boolean result = true; try { - - Map externalVisits = new HashMap<>(); - Map jsons = new HashMap<>(); - Map vaccineWrapperMap = new HashMap<>(); - Map serviceWrapperMap = new HashMap<>(); - - // aggregate forms to be processed - for (Map.Entry entry : map.entrySet()) { - String json = entry.getValue().getJsonPayload(); - if (StringUtils.isNotBlank(json)) { - - // do not process events that are meant to be in detached mode - // in a similar manner to the the aggregated events - if (entry.getValue().getProcessingMode() == BaseAncHomeVisitAction.ProcessingMode.DETACHED - || StringUtils.isNotBlank(entry.getValue().getBaseEntityID())) { - externalVisits.put(entry.getKey(), entry.getValue()); - continue; - } - - jsons.put(entry.getKey(), json); - JSONObject jsonObject = new JSONObject(json); - if (entry.getValue().getVaccineWrapper() != null) { - int position = 0; - for (VaccineWrapper v : entry.getValue().getVaccineWrapper()) { - vaccineWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), v); - position++; - } - } - - if (entry.getValue().getServiceWrapper() != null) { - int position = 0; - for (ServiceWrapper sw : entry.getValue().getServiceWrapper()) { - serviceWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), sw); - position++; - } - } - } - } - - Visit visit = saveVisit(editMode, memberID, getEncounterType(), jsons, vaccineWrapperMap, serviceWrapperMap); - if (visit != null) - saveDetachedEvents(visit, externalVisits); - + submitVisit(editMode, memberID, map, ""); } catch (Exception e) { Timber.e(e); result = false; @@ -141,14 +99,82 @@ public void submitVisit(final boolean editMode, final String memberID, final Map appExecutors.diskIO().execute(runnable); } + private void submitVisit(final boolean editMode, final String memberID, final Map map, String parentEventType) throws Exception { + + Map externalVisits = new HashMap<>(); + Map detachedVisits = new HashMap<>(); + Map jsons = new HashMap<>(); + Map vaccineWrapperMap = new HashMap<>(); + Map serviceWrapperMap = new HashMap<>(); + + // aggregate forms to be processed + for (Map.Entry entry : map.entrySet()) { + String json = entry.getValue().getJsonPayload(); + if (StringUtils.isNotBlank(json)) { + + // do not process events that are meant to be in detached mode + // in a similar manner to the the aggregated events + BaseAncHomeVisitAction.ProcessingMode mode = entry.getValue().getProcessingMode(); + if (mode == BaseAncHomeVisitAction.ProcessingMode.DETACHED + && StringUtils.isNotBlank(entry.getValue().getBaseEntityID())) { + detachedVisits.put(entry.getKey(), entry.getValue()); + continue; + } + + if (mode == BaseAncHomeVisitAction.ProcessingMode.SEPARATE + && StringUtils.isNotBlank(entry.getValue().getBaseEntityID()) + && StringUtils.isBlank(parentEventType) + ) { + externalVisits.put(entry.getKey(), entry.getValue()); + continue; + } + + jsons.put(entry.getKey(), json); + JSONObject jsonObject = new JSONObject(json); + if (entry.getValue().getVaccineWrapper() != null) { + int position = 0; + for (VaccineWrapper v : entry.getValue().getVaccineWrapper()) { + vaccineWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), v); + position++; + } + } + + if (entry.getValue().getServiceWrapper() != null) { + int position = 0; + for (ServiceWrapper sw : entry.getValue().getServiceWrapper()) { + serviceWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), sw); + position++; + } + } + } + } + + String type = StringUtils.isBlank(parentEventType) ? getEncounterType() : getEncounterType(); + Visit visit = saveVisit(editMode, memberID, type, jsons, vaccineWrapperMap, serviceWrapperMap, parentEventType); + if (visit != null && !externalVisits.isEmpty()) { + for (Map.Entry entry : externalVisits.entrySet()) { + Map subEvent = new HashMap<>(); + subEvent.put(entry.getKey(), entry.getValue()); + submitVisit(editMode, memberID, subEvent, visit.getVisitType()); + } + } + + if (visit != null && detachedVisits.size() > 0) + saveDetachedEvents(visit, detachedVisits); + } + private Visit saveVisit(boolean editMode, String memberID, String encounterType, final Map jsonString, Map vaccineWrapperMap, - Map serviceWrapperMap + Map serviceWrapperMap, + String parentEventType ) throws Exception { AllSharedPreferences allSharedPreferences = AncLibrary.getInstance().context().allSharedPreferences(); - Event baseEvent = JsonFormUtils.processVisitJsonForm(allSharedPreferences, memberID, encounterType, jsonString, getTableName()); + + String derivedEncounterType = StringUtils.isBlank(parentEventType) ? encounterType : ""; + Event baseEvent = JsonFormUtils.processVisitJsonForm(allSharedPreferences, memberID, derivedEncounterType, jsonString, getTableName()); + prepareEvent(baseEvent); if (baseEvent != null) { baseEvent.setFormSubmissionId(JsonFormUtils.generateRandomUUIDString()); @@ -162,10 +188,20 @@ private Visit saveVisit(boolean editMode, String memberID, String encounterType, if (editMode) { AncLibrary.getInstance().visitRepository().deleteVisit(visitID); AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(visitID); + + List childVisits = AncLibrary.getInstance().visitRepository().getChildEvents(visitID); + for (Visit v : childVisits) { + AncLibrary.getInstance().visitRepository().deleteVisit(v.getVisitId()); + AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(v.getVisitId()); + } } Visit visit = NCUtils.eventToVisit(baseEvent, visitID); visit.setPreProcessedJson(new Gson().toJson(baseEvent)); + if (StringUtils.isNotBlank(parentEventType)) { + String parentVisitID = AncLibrary.getInstance().visitRepository().getParentVisitEventID(visit.getBaseEntityId(), parentEventType, visit.getDate()); + visit.setParentVisitID(parentVisitID); + } AncLibrary.getInstance().visitRepository().addVisit(visit); // create the visit details diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java index 46a222f9..5224d083 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java @@ -11,9 +11,11 @@ import org.smartregister.repository.BaseRepository; import org.smartregister.repository.Repository; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Locale; import timber.log.Timber; @@ -54,8 +56,7 @@ public class VisitRepository extends BaseRepository { public static final String PARENT_VISIT_ID_INDEX = "CREATE INDEX " + VISIT_TABLE + "_" + PARENT_VISIT_ID + "_index ON " + VISIT_TABLE + "(" + PARENT_VISIT_ID + " COLLATE NOCASE );"; - private String[] VISIT_COLUMNS = {VISIT_ID, VISIT_TYPE, BASE_ENTITY_ID, VISIT_DATE, VISIT_JSON, PRE_PROCESSED, FORM_SUBMISSION_ID, PROCESSED, UPDATED_AT, CREATED_AT}; - + private String[] VISIT_COLUMNS = {VISIT_ID, VISIT_TYPE, PARENT_VISIT_ID, BASE_ENTITY_ID, VISIT_DATE, VISIT_JSON, PRE_PROCESSED, FORM_SUBMISSION_ID, PROCESSED, UPDATED_AT, CREATED_AT}; public VisitRepository(Repository repository) { super(repository); @@ -95,6 +96,30 @@ public void addVisit(Visit visit, SQLiteDatabase database) { database.insert(VISIT_TABLE, null, createValues(visit)); } + public String getParentVisitEventID(String baseEntityID, String parentEventType, Date eventDate) { + String visitID = null; + Cursor cursor = null; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); + String sql = "select " + VISIT_ID + " from visits where strftime('%Y-%m-%d',visit_date / 1000, 'unixepoch') = ? and visit_type = ? and base_entity_id = ? "; + try { + cursor = getReadableDatabase().rawQuery(sql, new String[]{sdf.format(eventDate), parentEventType, baseEntityID}); + if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) { + while (!cursor.isAfterLast()) { + visitID = cursor.getString(cursor.getColumnIndex(VISIT_ID)); + cursor.moveToNext(); + } + } + } catch (Exception e) { + Timber.e(e); + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return visitID; + } + public void deleteVisit(String visitID) { try { getWritableDatabase().delete(VISIT_TABLE, VISIT_ID + "= ?", new String[]{visitID}); diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java index a60e1656..5290a3ba 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java @@ -81,8 +81,9 @@ public static Event processVisitJsonForm(AllSharedPreferences allSharedPreferenc } JSONArray fields = new JSONArray(fields_obj); + String derivedEncounterType = StringUtils.isBlank(encounterType) ? getString(jsonForm, ENCOUNTER_TYPE) : encounterType; - return org.smartregister.util.JsonFormUtils.createEvent(fields, metadata, formTag(allSharedPreferences), entityId, encounterType, tableName); + return org.smartregister.util.JsonFormUtils.createEvent(fields, metadata, formTag(allSharedPreferences), entityId, derivedEncounterType, tableName); } public static Event prepareEvent(AllSharedPreferences allSharedPreferences, String entityId, String jsonString, String tableName) throws JSONException { diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index 7fa3766e..f7312a94 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -338,11 +338,29 @@ public static void processAncHomeVisit(EventClient baseEvent) { processAncHomeVisit(baseEvent, null); } + public static void processSubHomeVisit(EventClient baseEvent, String parentEventType) { + processAncHomeVisit(baseEvent, null, parentEventType); + } + + public static void processSubHomeVisit(EventClient baseEvent, SQLiteDatabase database, String parentEventType) { + processAncHomeVisit(baseEvent, database, parentEventType); + } + public static void processAncHomeVisit(EventClient baseEvent, SQLiteDatabase database) { + processAncHomeVisit(baseEvent, database, null); + } + + public static void processAncHomeVisit(EventClient baseEvent, SQLiteDatabase database, String parentEventType) { try { Visit visit = AncLibrary.getInstance().visitRepository().getVisitByFormSubmissionID(baseEvent.getEvent().getFormSubmissionId()); if (visit == null) { visit = eventToVisit(baseEvent.getEvent()); + + if (StringUtils.isNotBlank(parentEventType) && !parentEventType.equalsIgnoreCase(visit.getVisitType())) { + String parentVisitID = AncLibrary.getInstance().visitRepository().getParentVisitEventID(visit.getBaseEntityId(), parentEventType, visit.getDate()); + visit.setParentVisitID(parentVisitID); + } + if (database != null) { AncLibrary.getInstance().visitRepository().addVisit(visit, database); } else { From 5639d7d7fc47584545dc330b8d4e71fa0e7f6d64 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Fri, 23 Aug 2019 08:45:44 +0300 Subject: [PATCH 03/11] Edit mode for separate events fixed --- .../chw/anc/interactor/BaseAncHomeVisitInteractor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java index 955be425..af20c4f3 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java @@ -155,7 +155,7 @@ private void submitVisit(final boolean editMode, final String memberID, final Ma for (Map.Entry entry : externalVisits.entrySet()) { Map subEvent = new HashMap<>(); subEvent.put(entry.getKey(), entry.getValue()); - submitVisit(editMode, memberID, subEvent, visit.getVisitType()); + submitVisit(false, memberID, subEvent, visit.getVisitType()); } } From 7c8d7e982203abdb8c16c5db42fadb5edf107dd0 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Fri, 23 Aug 2019 12:39:48 +0300 Subject: [PATCH 04/11] fix on selected option in visit fragment --- .../fragment/BaseAncHomeVisitFragment.java | 19 +++++++++++++++++-- .../chw/anc/util/JsonFormUtils.java | 10 +++++++--- .../smartregister/chw/anc/util/NCUtils.java | 4 ++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseAncHomeVisitFragment.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseAncHomeVisitFragment.java index bb1cbbc5..1d20f04e 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseAncHomeVisitFragment.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseAncHomeVisitFragment.java @@ -205,8 +205,8 @@ private void prepareRadioView() { String key = object.getString(JsonFormConstants.KEY); rb.setTag(R.id.home_visit_radio_key, key); - rb.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (isChecked) + rb.setOnClickListener(v -> { + if (rb.isChecked()) onSelectOption(key); }); } catch (JSONException e) { @@ -342,6 +342,7 @@ public void setCount(String count) { public void setValue(String value) { if (getQuestionType() == QuestionType.BOOLEAN) { if (radioButtonNo != null && radioButtonYes != null) { + setYesNoListenersActive(false); if (value.equalsIgnoreCase("Yes")) { radioButtonYes.setChecked(true); radioButtonNo.setChecked(false); @@ -349,6 +350,7 @@ public void setValue(String value) { radioButtonYes.setChecked(false); radioButtonNo.setChecked(true); } + setYesNoListenersActive(true); } } else if (getQuestionType() == QuestionType.DATE_SELECTOR) { // datePicker.updateDate(); @@ -363,6 +365,9 @@ public void setValue(String value) { } } else if (getQuestionType() == QuestionType.RADIO) { // + if (radioGroupDynamic.getChildCount() == 0) + prepareRadioView(); + int count = radioGroupDynamic.getChildCount(); int x = 0; while (count > x) { @@ -376,6 +381,16 @@ public void setValue(String value) { } } + private void setYesNoListenersActive(boolean active) { + if (active) { + radioButtonYes.setOnClickListener(this); + radioButtonNo.setOnClickListener(this); + } else { + radioButtonYes.setOnClickListener(null); + radioButtonNo.setOnClickListener(null); + } + } + @Override public void setOptions(List options) { if (this.optionList == null) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java index 5290a3ba..8fb37592 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java @@ -280,7 +280,6 @@ public static String getCheckBoxValue(JSONObject jsonObject, String key) { } public static void populateForm(JSONObject jsonObject, Map> details) { - Timber.v("populateForm"); try { // x steps String count_str = jsonObject.getString(JsonFormConstants.COUNT); @@ -293,13 +292,18 @@ public static void populateForm(JSONObject jsonObject, Map= 0) { JSONObject jo = jsonArray.getJSONObject(field_count); - List detailList = details.get(jo.getString(JsonFormConstants.KEY)); + String key = jo.getString(JsonFormConstants.KEY); + List detailList = details.get(key); if (detailList != null) { if (jo.getString(JsonFormConstants.TYPE).equalsIgnoreCase(JsonFormConstants.CHECK_BOX)) { jo.put(JsonFormConstants.VALUE, getValue(jo, detailList)); } else { - jo.put(JsonFormConstants.VALUE, getValue(detailList.get(0))); + String value = getValue(detailList.get(0)); + if (key.contains("date")) { + value = NCUtils.getFormattedDate(NCUtils.getSaveDateFormat(), NCUtils.getSourceDateFormat(), value); + } + jo.put(JsonFormConstants.VALUE, value); } } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index f7312a94..b35ea8fe 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -215,11 +215,11 @@ public static String getTodayDate() { return formatter.format(date); } - private static SimpleDateFormat getSourceDateFormat() { + public static SimpleDateFormat getSourceDateFormat() { return new SimpleDateFormat(AncLibrary.getInstance().getSourceDateFormat(), Locale.getDefault()); } - private static SimpleDateFormat getSaveDateFormat() { + public static SimpleDateFormat getSaveDateFormat() { return new SimpleDateFormat(AncLibrary.getInstance().getSaveDateFormat(), Locale.getDefault()); } From dbdbe5fe0043291f863865f2e5d7f15f20e44635 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Sat, 24 Aug 2019 14:54:54 +0300 Subject: [PATCH 05/11] improve query performance and added date picker boundaries --- .../BaseHomeVisitImmunizationFragment.java | 41 +++++++++++++++---- .../chw/anc/repository/VisitRepository.java | 2 +- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java index 21108066..8ba13107 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java @@ -85,7 +85,7 @@ public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, singleDatePicker = view.findViewById(R.id.earlier_date_picker); if (vaccineDisplays.size() > 0) - initializeDatePicker(singleDatePicker, vaccineDisplays.entrySet().iterator().next().getValue()); + initializeDatePicker(singleDatePicker, vaccineDisplays); checkBoxNoVaccinesDone = view.findViewById(R.id.select); checkBoxNoVaccinesDone.setOnClickListener(this); @@ -121,7 +121,7 @@ public void setVaccineDisplays(Map vaccineDisplays) { // redraw all vaccine views if (vaccineDisplays.size() > 0 && singleDatePicker != null) { - initializeDatePicker(singleDatePicker, vaccineDisplays.entrySet().iterator().next().getValue()); + initializeDatePicker(singleDatePicker, vaccineDisplays); addVaccineViews(); } } @@ -166,17 +166,42 @@ private void addVaccineViews() { } private void initializeDatePicker(@NotNull DatePicker datePicker, @NotNull VaccineDisplay vaccineDisplay) { - if (vaccineDisplay.getStartDate().getTime() > vaccineDisplay.getEndDate().getTime()) { - datePicker.setMinDate(vaccineDisplay.getStartDate().getTime()); - datePicker.setMaxDate(vaccineDisplay.getStartDate().getTime()); + Date startDate = vaccineDisplay.getStartDate(); + Date endDate = (vaccineDisplay.getEndDate() != null && vaccineDisplay.getEndDate().getTime() < new Date().getTime()) ? + vaccineDisplay.getEndDate() : new Date(); + + if (startDate.getTime() > endDate.getTime()) { + datePicker.setMinDate(endDate.getTime()); + datePicker.setMaxDate(endDate.getTime()); } else { - datePicker.setMinDate(vaccineDisplay.getStartDate().getTime()); - datePicker.setMaxDate(vaccineDisplay.getEndDate().getTime()); + datePicker.setMinDate(startDate.getTime()); + datePicker.setMaxDate(endDate.getTime()); } } - private void initializeDatePicker(@NotNull DatePicker datePicker, @NotNull Date startDate, @NotNull Date endDate) { + private void initializeDatePicker(@NotNull DatePicker datePicker, @NotNull Map vaccineDisplays) { + //compute the start date and the end date + Date startDate = null; + Date endDate = new Date(); + for (Map.Entry entry : vaccineDisplays.entrySet()) { + VaccineDisplay display = entry.getValue(); + + // get the largest start date + if (startDate == null || display.getStartDate().getTime() < startDate.getTime()) + startDate = display.getStartDate(); + // get the lowest end date + if (display.getEndDate() != null && display.getEndDate().getTime() < endDate.getTime()) + endDate = display.getEndDate(); + } + + if (startDate != null && startDate.getTime() > endDate.getTime()) { + datePicker.setMinDate(endDate.getTime()); + datePicker.setMaxDate(endDate.getTime()); + } else { + datePicker.setMinDate(startDate != null ? startDate.getTime() : endDate.getTime()); + datePicker.setMaxDate(endDate.getTime()); + } } private Date getDateFromDatePicker(DatePicker datePicker) { diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java index 5224d083..ee811637 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitRepository.java @@ -100,7 +100,7 @@ public String getParentVisitEventID(String baseEntityID, String parentEventType, String visitID = null; Cursor cursor = null; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); - String sql = "select " + VISIT_ID + " from visits where strftime('%Y-%m-%d',visit_date / 1000, 'unixepoch') = ? and visit_type = ? and base_entity_id = ? "; + String sql = "select " + VISIT_ID + " from visits where base_entity_id = ? COLLATE NOCASE and visit_type = ? COLLATE NOCASE strftime('%Y-%m-%d',visit_date / 1000, 'unixepoch') = ? "; try { cursor = getReadableDatabase().rawQuery(sql, new String[]{sdf.format(eventDate), parentEventType, baseEntityID}); if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) { From 69220a2875a9b494afa33420e4a8fda380ff0952 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Mon, 26 Aug 2019 07:19:57 +0300 Subject: [PATCH 06/11] Save visit optmization --- .../activity/BaseAncHomeVisitActivity.java | 6 +- .../BaseAncUpcomingServicesActivity.java | 7 +- .../anc/adapter/BaseAncHomeVisitAdapter.java | 4 + .../BaseHomeVisitImmunizationFragment.java | 12 +- .../BaseAncHomeVisitInteractor.java | 161 +++++++++++------- .../chw/anc/model/BaseAncHomeVisitAction.java | 21 ++- .../smartregister/chw/anc/util/NCUtils.java | 78 +++++++++ .../adapter/BaseAncHomeVisitAdapterTest.java | 4 +- 8 files changed, 218 insertions(+), 75 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncHomeVisitActivity.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncHomeVisitActivity.java index fa24d9d2..e0377f2b 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncHomeVisitActivity.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncHomeVisitActivity.java @@ -211,9 +211,9 @@ public void redrawVisitUI() { boolean valid = actionList.size() > 0; for (Map.Entry entry : actionList.entrySet()) { BaseAncHomeVisitAction action = entry.getValue(); - if (!action.isOptional() - && action.getActionStatus() == BaseAncHomeVisitAction.Status.PENDING - && action.isValid() + if ( + (!action.isOptional() && (action.getActionStatus() == BaseAncHomeVisitAction.Status.PENDING && action.isValid())) + || !action.isEnabled() ) { valid = false; break; diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncUpcomingServicesActivity.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncUpcomingServicesActivity.java index de07222a..b2123e44 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncUpcomingServicesActivity.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/activity/BaseAncUpcomingServicesActivity.java @@ -82,12 +82,7 @@ private void setUpActionBar() { upArrow.setColorFilter(getResources().getColor(R.color.text_blue), PorterDuff.Mode.SRC_ATOP); actionBar.setHomeAsUpIndicator(upArrow); } - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); + toolbar.setNavigationOnClickListener(v -> finish()); } public void setUpView() { diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java index 83a28a7c..d99b9a4f 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapter.java @@ -121,6 +121,10 @@ public void onBindViewHolder(@NotNull MyViewHolder holder, int position) { private int getCircleColor(BaseAncHomeVisitAction ancHomeVisitAction) { int color_res; + boolean valid = ancHomeVisitAction.isValid() && ancHomeVisitAction.isEnabled(); + if (!valid) + return R.color.transparent_gray; + switch (ancHomeVisitAction.getActionStatus()) { case PENDING: color_res = R.color.transparent_gray; diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java index 8ba13107..8765f0c0 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/fragment/BaseHomeVisitImmunizationFragment.java @@ -19,6 +19,7 @@ import org.smartregister.chw.anc.model.BaseHomeVisitImmunizationFragmentModel; import org.smartregister.chw.anc.presenter.BaseHomeVisitImmunizationFragmentPresenter; import org.smartregister.chw.anc.util.Constants; +import org.smartregister.chw.anc.util.JsonFormUtils; import org.smartregister.chw.anc.util.NCUtils; import org.smartregister.chw.opensrp_chw_anc.R; import org.smartregister.immunization.db.VaccineRepo; @@ -51,6 +52,7 @@ public class BaseHomeVisitImmunizationFragment extends BaseHomeVisitFragment imp private CheckBox checkBoxNoVaccinesDone; private DatePicker singleDatePicker; private Button saveButton; + private SimpleDateFormat dateFormat = new SimpleDateFormat(Constants.DATE_FORMATS.NATIVE_FORMS, Locale.getDefault()); public static BaseHomeVisitImmunizationFragment getInstance(final BaseAncHomeVisitContract.VisitView view, String baseEntityID, Map> details, List vaccineDisplays) { BaseHomeVisitImmunizationFragment fragment = new BaseHomeVisitImmunizationFragment(); @@ -60,6 +62,12 @@ public static BaseHomeVisitImmunizationFragment getInstance(final BaseAncHomeVis for (VaccineDisplay vaccineDisplay : vaccineDisplays) { fragment.vaccineDisplays.put(vaccineDisplay.getVaccineWrapper().getName(), vaccineDisplay); } + + if (details != null && details.size() > 0) { + fragment.jsonObject = NCUtils.getVisitJSONFromVisitDetails(baseEntityID, details, vaccineDisplays); + JsonFormUtils.populateForm(fragment.jsonObject, details); + } + return fragment; } @@ -124,6 +132,9 @@ public void setVaccineDisplays(Map vaccineDisplays) { initializeDatePicker(singleDatePicker, vaccineDisplays); addVaccineViews(); } + + // reset the json payload if the vaccine view was updated manually + this.jsonObject = null; } @Override @@ -260,7 +271,6 @@ private void onSave() { // notify the view (write to json file then dismiss) Date vaccineDate = getDateFromDatePicker(singleDatePicker); - SimpleDateFormat dateFormat = new SimpleDateFormat(Constants.DATE_FORMATS.NATIVE_FORMS, Locale.getDefault()); HashMap vaccineDateMap = new HashMap<>(); boolean multiModeActive = multipleVaccineDatePickerView.getVisibility() == View.GONE; diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java index af20c4f3..25b33af3 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java @@ -16,6 +16,7 @@ import org.smartregister.chw.anc.domain.Visit; import org.smartregister.chw.anc.domain.VisitDetail; import org.smartregister.chw.anc.model.BaseAncHomeVisitAction; +import org.smartregister.chw.anc.repository.VisitRepository; import org.smartregister.chw.anc.util.AppExecutors; import org.smartregister.chw.anc.util.Constants; import org.smartregister.chw.anc.util.JsonFormUtils; @@ -131,26 +132,60 @@ private void submitVisit(final boolean editMode, final String memberID, final Ma jsons.put(entry.getKey(), json); JSONObject jsonObject = new JSONObject(json); - if (entry.getValue().getVaccineWrapper() != null) { - int position = 0; - for (VaccineWrapper v : entry.getValue().getVaccineWrapper()) { - vaccineWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), v); - position++; - } - } - if (entry.getValue().getServiceWrapper() != null) { - int position = 0; - for (ServiceWrapper sw : entry.getValue().getServiceWrapper()) { - serviceWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), sw); - position++; - } - } + extractVaccineWrappers(entry, vaccineWrapperMap, jsonObject); + extractServiceWrappers(entry, serviceWrapperMap, jsonObject); } } String type = StringUtils.isBlank(parentEventType) ? getEncounterType() : getEncounterType(); - Visit visit = saveVisit(editMode, memberID, type, jsons, vaccineWrapperMap, serviceWrapperMap, parentEventType); + + // persist to database + Visit visit = saveVisit(editMode, memberID, type, jsons, parentEventType); + if (visit != null) { + saveVisitDetails(visit, vaccineWrapperMap, serviceWrapperMap); + processExternalVisits(visit, externalVisits, memberID); + if (detachedVisits.size() > 0) + saveDetachedEvents(visit, detachedVisits); + } + } + + private void extractVaccineWrappers( + Map.Entry entry, + Map vaccineWrapperMap, + JSONObject jsonObject + ) { + if (entry.getValue().getVaccineWrapper() != null) { + int position = 0; + for (VaccineWrapper v : entry.getValue().getVaccineWrapper()) { + vaccineWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), v); + position++; + } + } + } + + private void extractServiceWrappers( + Map.Entry entry, + Map serviceWrapperMap, + JSONObject jsonObject + ) { + if (entry.getValue().getServiceWrapper() != null) { + int position = 0; + for (ServiceWrapper sw : entry.getValue().getServiceWrapper()) { + serviceWrapperMap.put(JsonFormUtils.getObjectKey(jsonObject, position), sw); + position++; + } + } + } + + /** + * recursively persist visits to the db + * @param visit + * @param externalVisits + * @param memberID + * @throws Exception + */ + private void processExternalVisits(Visit visit, Map externalVisits, String memberID) throws Exception { if (visit != null && !externalVisits.isEmpty()) { for (Map.Entry entry : externalVisits.entrySet()) { Map subEvent = new HashMap<>(); @@ -158,15 +193,10 @@ private void submitVisit(final boolean editMode, final String memberID, final Ma submitVisit(false, memberID, subEvent, visit.getVisitType()); } } - - if (visit != null && detachedVisits.size() > 0) - saveDetachedEvents(visit, detachedVisits); } private Visit saveVisit(boolean editMode, String memberID, String encounterType, final Map jsonString, - Map vaccineWrapperMap, - Map serviceWrapperMap, String parentEventType ) throws Exception { @@ -174,66 +204,73 @@ private Visit saveVisit(boolean editMode, String memberID, String encounterType, String derivedEncounterType = StringUtils.isBlank(parentEventType) ? encounterType : ""; Event baseEvent = JsonFormUtils.processVisitJsonForm(allSharedPreferences, memberID, derivedEncounterType, jsonString, getTableName()); - prepareEvent(baseEvent); + if (baseEvent != null) { baseEvent.setFormSubmissionId(JsonFormUtils.generateRandomUUIDString()); JsonFormUtils.tagEvent(allSharedPreferences, baseEvent); String visitID = (editMode) ? - AncLibrary.getInstance().visitRepository().getLatestVisit(memberID, getEncounterType()).getVisitId() : + visitRepository().getLatestVisit(memberID, getEncounterType()).getVisitId() : JsonFormUtils.generateRandomUUIDString(); // reset database - if (editMode) { - AncLibrary.getInstance().visitRepository().deleteVisit(visitID); - AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(visitID); - - List childVisits = AncLibrary.getInstance().visitRepository().getChildEvents(visitID); - for (Visit v : childVisits) { - AncLibrary.getInstance().visitRepository().deleteVisit(v.getVisitId()); - AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(v.getVisitId()); - } - } + if (editMode) + deleteOldVisit(visitID); Visit visit = NCUtils.eventToVisit(baseEvent, visitID); visit.setPreProcessedJson(new Gson().toJson(baseEvent)); - if (StringUtils.isNotBlank(parentEventType)) { - String parentVisitID = AncLibrary.getInstance().visitRepository().getParentVisitEventID(visit.getBaseEntityId(), parentEventType, visit.getDate()); - visit.setParentVisitID(parentVisitID); - } - AncLibrary.getInstance().visitRepository().addVisit(visit); - - // create the visit details - if (visit.getVisitDetails() != null) { - Gson gson = Converters.registerDateTime(new GsonBuilder()).create(); - - for (Map.Entry> entry : visit.getVisitDetails().entrySet()) { - if (entry.getValue() != null) { - for (VisitDetail d : entry.getValue()) { - - VaccineWrapper vaccineWrapper = vaccineWrapperMap.get(d.getVisitKey()); - if (vaccineWrapper != null) { - String json = gson.toJson(vaccineWrapper); - d.setPreProcessedJson(json); - d.setPreProcessedType("vaccine"); - } - - ServiceWrapper serviceWrapper = serviceWrapperMap.get(d.getVisitKey()); - if (serviceWrapper != null) { - String json = gson.toJson(serviceWrapper); - d.setPreProcessedJson(json); - d.setPreProcessedType("service"); - } + if (StringUtils.isNotBlank(parentEventType)) + visit.setParentVisitID(visitRepository().getParentVisitEventID(visit.getBaseEntityId(), parentEventType, visit.getDate())); - AncLibrary.getInstance().visitDetailsRepository().addVisitDetails(d); + visitRepository().addVisit(visit); + return visit; + } + return null; + } + + private VisitRepository visitRepository(){ + return AncLibrary.getInstance().visitRepository(); + } + + private void deleteOldVisit(String visitID) { + AncLibrary.getInstance().visitRepository().deleteVisit(visitID); + AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(visitID); + + List childVisits = AncLibrary.getInstance().visitRepository().getChildEvents(visitID); + for (Visit v : childVisits) { + AncLibrary.getInstance().visitRepository().deleteVisit(v.getVisitId()); + AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(v.getVisitId()); + } + } + + private void saveVisitDetails(Visit visit, Map vaccineWrapperMap, Map serviceWrapperMap) { + if (visit.getVisitDetails() != null) { + Gson gson = Converters.registerDateTime(new GsonBuilder()).create(); + + for (Map.Entry> entry : visit.getVisitDetails().entrySet()) { + if (entry.getValue() != null) { + for (VisitDetail d : entry.getValue()) { + + VaccineWrapper vaccineWrapper = vaccineWrapperMap.get(d.getVisitKey()); + if (vaccineWrapper != null) { + String json = gson.toJson(vaccineWrapper); + d.setPreProcessedJson(json); + d.setPreProcessedType("vaccine"); } + + ServiceWrapper serviceWrapper = serviceWrapperMap.get(d.getVisitKey()); + if (serviceWrapper != null) { + String json = gson.toJson(serviceWrapper); + d.setPreProcessedJson(json); + d.setPreProcessedType("service"); + } + + AncLibrary.getInstance().visitDetailsRepository().addVisitDetails(d); } } } - return visit; } - return null; } /** diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java index ed205e3e..5e50ef65 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java @@ -24,6 +24,7 @@ public class BaseAncHomeVisitAction { private String title; private String subTitle; private String disabledMessage; + private PayloadType payloadType; private Status actionStatus; private ScheduleStatus scheduleStatus; private ProcessingMode processingMode; @@ -43,6 +44,8 @@ private BaseAncHomeVisitAction(Builder builder) throws ValidationException { this.baseEntityID = builder.baseEntityID; this.title = builder.title; this.subTitle = builder.subTitle; + this.disabledMessage = builder.disabledMessage; + this.payloadType = builder.payloadType; this.actionStatus = builder.actionStatus; this.scheduleStatus = builder.scheduleStatus; this.optional = builder.optional; @@ -56,7 +59,6 @@ private BaseAncHomeVisitAction(Builder builder) throws ValidationException { this.processingMode = builder.processingMode; this.jsonPayload = builder.jsonPayload; this.validator = builder.validator; - this.disabledMessage = builder.disabledMessage; validateMe(); initialize(); @@ -161,6 +163,14 @@ public void setDisabledMessage(String disabledMessage) { this.disabledMessage = disabledMessage; } + public PayloadType getPayloadType() { + return payloadType; + } + + public void setPayloadType(PayloadType payloadType) { + this.payloadType = payloadType; + } + public Status getActionStatus() { return actionStatus; } @@ -311,6 +321,8 @@ public enum ScheduleStatus {DUE, OVERDUE} */ public enum ProcessingMode {COMBINED, DETACHED, SEPARATE} + public enum PayloadType {JSON, VACCINE, SERVICE} + public interface AncHomeVisitActionHelper { /** @@ -332,7 +344,6 @@ public interface AncHomeVisitActionHelper { */ void onPayloadReceived(String jsonPayload); - /** * executed after form is loaded on start * add functionality to evaluate the state of the view immediately the form is processed @@ -375,6 +386,7 @@ public static class Builder { private String title; private String subTitle; private String disabledMessage; + private PayloadType payloadType = PayloadType.JSON; private Status actionStatus = Status.PENDING; private ScheduleStatus scheduleStatus = ScheduleStatus.DUE; private ProcessingMode processingMode = ProcessingMode.COMBINED; @@ -409,6 +421,11 @@ public Builder withDisabledMessage(String disabledMessage) { return this; } + public Builder withPayloadType(PayloadType payloadType) { + this.payloadType = payloadType; + return this; + } + public Builder withOptional(boolean optional) { this.optional = optional; return this; diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index b35ea8fe..78dc0eae 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -30,6 +30,7 @@ import net.sqlcipher.database.SQLiteDatabase; import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joda.time.DateTime; import org.joda.time.Days; @@ -40,6 +41,7 @@ import org.json.JSONObject; import org.smartregister.chw.anc.AncLibrary; import org.smartregister.chw.anc.contract.BaseAncWomanCallDialogContract; +import org.smartregister.chw.anc.domain.VaccineDisplay; import org.smartregister.chw.anc.domain.Visit; import org.smartregister.chw.anc.domain.VisitDetail; import org.smartregister.chw.opensrp_chw_anc.R; @@ -551,6 +553,7 @@ public static JSONObject getVisitJSONFromWrapper(String entityID, Map> detailsMap, List vaccineDisplays) { + try { + JSONObject jsonObject = JsonFormUtils.getFormAsJson(Constants.FORMS.IMMUNIZATIOIN_VISIT); + jsonObject.put("entity_id", entityID); + JSONArray jsonArray = jsonObject.getJSONObject(JsonFormConstants.STEP1).getJSONArray(JsonFormConstants.FIELDS); + + for (VaccineDisplay vaccineDisplay: vaccineDisplays){ + JSONObject field = new JSONObject(); + + String name = removeSpaces(vaccineDisplay.getVaccineWrapper().getName()); + String value = getText(detailsMap.get(name)); + + field.put(JsonFormConstants.KEY, name); + field.put(JsonFormConstants.OPENMRS_ENTITY_PARENT, ""); + field.put(JsonFormConstants.OPENMRS_ENTITY, "concept"); + field.put(JsonFormConstants.TYPE, "edit_text"); + field.put(JsonFormConstants.OPENMRS_ENTITY_ID, name); + field.put(JsonFormConstants.VALUE, value); + + jsonArray.put(field); + } + + return jsonObject; + } catch (Exception e) { + Timber.e(e); + } + return null; + } + + public static String removeSpaces(String s) { return s.replace(" ", "_").toLowerCase(); } + + /** + * Extract value from VisitDetail + * + * @return + */ + @NotNull + public static String getText(@Nullable VisitDetail visitDetail) { + if (visitDetail == null) + return ""; + + String val = visitDetail.getHumanReadable(); + if (StringUtils.isNotBlank(val)) + return val.trim(); + + return (StringUtils.isNotBlank(visitDetail.getDetails())) ? visitDetail.getDetails().trim() : ""; + } + + @NotNull + public static String getText(@Nullable List visitDetails) { + if (visitDetails == null) + return ""; + + List vals = new ArrayList<>(); + for (VisitDetail vd : visitDetails) { + String val = getText(vd); + if (StringUtils.isNotBlank(val)) + vals.add(val); + } + + return toCSV(vals); + } + + public static String toCSV(List list) { + String result = ""; + if (list.size() > 0) { + StringBuilder sb = new StringBuilder(); + for (String s : list) { + sb.append(s).append(","); + } + result = sb.deleteCharAt(sb.length() - 1).toString(); + } + return result; + } } diff --git a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java index 42351e76..1ac3b9f2 100644 --- a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java +++ b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java @@ -66,10 +66,12 @@ public void testGetCircleColorPartial() throws Exception { } @Test - public void testBindClickListener() throws Exception { + public void testBindClickListenerOnValidObject() throws Exception { BaseAncHomeVisitAdapter ancHomeVisitAdapter = new BaseAncHomeVisitAdapter(context, view, myDataset); View view = Mockito.mock(View.class); BaseAncHomeVisitAction ancHomeVisitAction = Mockito.mock(BaseAncHomeVisitAction.class); + Mockito.doReturn(true).when(ancHomeVisitAction).isValid(); + Mockito.doReturn(true).when(ancHomeVisitAction).isEnabled(); Whitebox.invokeMethod(ancHomeVisitAdapter, "bindClickListener", view, ancHomeVisitAction); From 3f1fc9d47998938ce34760976a0151ebdc33536f Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Mon, 26 Aug 2019 07:59:03 +0300 Subject: [PATCH 07/11] Added parent code to visit details repository --- .../chw/anc/domain/VisitDetail.java | 9 ++++++++ .../BaseAncHomeVisitInteractor.java | 6 +++--- .../chw/anc/model/BaseAncHomeVisitAction.java | 18 ---------------- .../repository/VisitDetailsRepository.java | 9 ++++++-- .../chw/anc/util/JsonFormUtils.java | 1 - .../smartregister/chw/anc/util/NCUtils.java | 21 ++++++++++++++----- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VisitDetail.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VisitDetail.java index af022c9e..d756c23a 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VisitDetail.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/domain/VisitDetail.java @@ -7,6 +7,7 @@ public class VisitDetail { private String visitId; private String baseEntityId; private String visitKey; + private String parentCode; private String details; // private String humanReadable; // private String jsonDetails; @@ -48,6 +49,14 @@ public void setVisitKey(String visitKey) { this.visitKey = visitKey; } + public String getParentCode() { + return parentCode; + } + + public void setParentCode(String parentCode) { + this.parentCode = parentCode; + } + public String getDetails() { return details; } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java index 25b33af3..6541a5c4 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java @@ -234,12 +234,12 @@ private VisitRepository visitRepository(){ } private void deleteOldVisit(String visitID) { - AncLibrary.getInstance().visitRepository().deleteVisit(visitID); + visitRepository().deleteVisit(visitID); AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(visitID); - List childVisits = AncLibrary.getInstance().visitRepository().getChildEvents(visitID); + List childVisits = visitRepository().getChildEvents(visitID); for (Visit v : childVisits) { - AncLibrary.getInstance().visitRepository().deleteVisit(v.getVisitId()); + visitRepository().deleteVisit(v.getVisitId()); AncLibrary.getInstance().visitDetailsRepository().deleteVisitDetails(v.getVisitId()); } } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java index 5e50ef65..c2c90737 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/model/BaseAncHomeVisitAction.java @@ -24,7 +24,6 @@ public class BaseAncHomeVisitAction { private String title; private String subTitle; private String disabledMessage; - private PayloadType payloadType; private Status actionStatus; private ScheduleStatus scheduleStatus; private ProcessingMode processingMode; @@ -45,7 +44,6 @@ private BaseAncHomeVisitAction(Builder builder) throws ValidationException { this.title = builder.title; this.subTitle = builder.subTitle; this.disabledMessage = builder.disabledMessage; - this.payloadType = builder.payloadType; this.actionStatus = builder.actionStatus; this.scheduleStatus = builder.scheduleStatus; this.optional = builder.optional; @@ -163,14 +161,6 @@ public void setDisabledMessage(String disabledMessage) { this.disabledMessage = disabledMessage; } - public PayloadType getPayloadType() { - return payloadType; - } - - public void setPayloadType(PayloadType payloadType) { - this.payloadType = payloadType; - } - public Status getActionStatus() { return actionStatus; } @@ -321,8 +311,6 @@ public enum ScheduleStatus {DUE, OVERDUE} */ public enum ProcessingMode {COMBINED, DETACHED, SEPARATE} - public enum PayloadType {JSON, VACCINE, SERVICE} - public interface AncHomeVisitActionHelper { /** @@ -386,7 +374,6 @@ public static class Builder { private String title; private String subTitle; private String disabledMessage; - private PayloadType payloadType = PayloadType.JSON; private Status actionStatus = Status.PENDING; private ScheduleStatus scheduleStatus = ScheduleStatus.DUE; private ProcessingMode processingMode = ProcessingMode.COMBINED; @@ -421,11 +408,6 @@ public Builder withDisabledMessage(String disabledMessage) { return this; } - public Builder withPayloadType(PayloadType payloadType) { - this.payloadType = payloadType; - return this; - } - public Builder withOptional(boolean optional) { this.optional = optional; return this; diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitDetailsRepository.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitDetailsRepository.java index 7ed2ed39..f0a8bd03 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitDetailsRepository.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/repository/VisitDetailsRepository.java @@ -21,6 +21,7 @@ public class VisitDetailsRepository extends BaseRepository { private static final String VISIT_DETAILS_ID = "visit_details_id"; private static final String VISIT_ID = "visit_id"; private static final String VISIT_KEY = "visit_key"; + private static final String PARENT_CODE = "parent_code"; private static final String DETAILS = "details"; private static final String HUMAN_READABLE = "human_readable_details"; private static final String JSON_DETAILS = "json_details"; @@ -35,6 +36,7 @@ public class VisitDetailsRepository extends BaseRepository { + VISIT_DETAILS_ID + " VARCHAR NULL, " + VISIT_ID + " VARCHAR NULL, " + VISIT_KEY + " VARCHAR NULL, " + + PARENT_CODE + " VARCHAR NULL, " + JSON_DETAILS + " VARCHAR NULL, " + PRE_PROCESSED_JSON + " VARCHAR NULL, " + PRE_PROCESSED_TYPE + " VARCHAR NULL, " @@ -50,7 +52,7 @@ public class VisitDetailsRepository extends BaseRepository { + ");"; - private String[] VISIT_DETAILS_COLUMNS = {VISIT_ID, VISIT_KEY, VISIT_DETAILS_ID, HUMAN_READABLE, JSON_DETAILS, PRE_PROCESSED_JSON, PRE_PROCESSED_TYPE, DETAILS, PROCESSED, UPDATED_AT, CREATED_AT}; + private String[] VISIT_DETAILS_COLUMNS = {VISIT_ID, VISIT_KEY, PARENT_CODE, VISIT_DETAILS_ID, HUMAN_READABLE, JSON_DETAILS, PRE_PROCESSED_JSON, PRE_PROCESSED_TYPE, DETAILS, PROCESSED, UPDATED_AT, CREATED_AT}; public VisitDetailsRepository(Repository repository) { super(repository); @@ -66,6 +68,7 @@ private ContentValues createValues(VisitDetail visitDetail) { values.put(VISIT_DETAILS_ID, visitDetail.getVisitDetailsId()); values.put(VISIT_ID, visitDetail.getVisitId()); values.put(VISIT_KEY, visitDetail.getVisitKey()); + values.put(PARENT_CODE, visitDetail.getParentCode()); values.put(JSON_DETAILS, visitDetail.getJsonDetails()); values.put(PRE_PROCESSED_JSON, visitDetail.getPreProcessedJson()); values.put(PRE_PROCESSED_TYPE, visitDetail.getPreProcessedType()); @@ -129,6 +132,7 @@ private List readVisitDetails(Cursor cursor) { visitDetail.setVisitId(cursor.getString(cursor.getColumnIndex(VISIT_ID))); visitDetail.setVisitDetailsId(cursor.getString(cursor.getColumnIndex(VISIT_DETAILS_ID))); visitDetail.setVisitKey(cursor.getString(cursor.getColumnIndex(VISIT_KEY))); + visitDetail.setParentCode(cursor.getString(cursor.getColumnIndex(PARENT_CODE))); visitDetail.setJsonDetails(cursor.getString(cursor.getColumnIndex(JSON_DETAILS))); visitDetail.setPreProcessedJson(cursor.getString(cursor.getColumnIndex(PRE_PROCESSED_JSON))); visitDetail.setPreProcessedType(cursor.getString(cursor.getColumnIndex(PRE_PROCESSED_TYPE))); @@ -145,7 +149,8 @@ private List readVisitDetails(Cursor cursor) { } catch (Exception e) { Timber.e(e); } finally { - cursor.close(); + if (cursor != null) + cursor.close(); } return visitDetailList; } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java index 8fb37592..6352db2a 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/JsonFormUtils.java @@ -102,7 +102,6 @@ public static Event prepareEvent(AllSharedPreferences allSharedPreferences, Stri return org.smartregister.util.JsonFormUtils.createEvent(fields, metadata, formTag(allSharedPreferences), entityId, encounterType, tableName); } - public static Event createUntaggedEvent(String baseEntityId, String eventType, String table) { try { diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index 78dc0eae..86999b71 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -294,6 +294,7 @@ public static Map> eventsObsToDetails(List obsLis detail.setVisitId(visitID); detail.setBaseEntityId(baseEntityID); detail.setVisitKey(obs.getFormSubmissionField()); + detail.setParentCode(obs.getParentCode()); if (detail.getVisitKey().contains("date")) { // parse the @@ -322,10 +323,20 @@ public static Map> eventsObsToDetails(List obsLis } public static String getFormattedDate(SimpleDateFormat source_sdf, SimpleDateFormat dest_sdf, String value) { + if (StringUtils.isBlank(value)) + return ""; + try { Date date = source_sdf.parse(value); return dest_sdf.format(date); } catch (Exception e) { + try { + // fallback for long datetypes + Date date = new Date(Long.parseLong(value)); + return dest_sdf.format(date); + } catch (NumberFormatException | NullPointerException nfe) { + Timber.e(e); + } Timber.e(e); } return value; @@ -551,9 +562,9 @@ public static JSONObject getVisitJSONFromWrapper(String entityID, Map entry : vaccineWrapperDateMap.entrySet()) { JSONObject field = new JSONObject(); field.put(JsonFormConstants.KEY, removeSpaces(entry.getKey().getName())); - field.put(JsonFormConstants.OPENMRS_ENTITY_PARENT, ""); + field.put(JsonFormConstants.OPENMRS_ENTITY_PARENT, "vaccine"); field.put(JsonFormConstants.OPENMRS_ENTITY, "concept"); - field.put(JsonFormConstants.TYPE, "edit_text"); + field.put(JsonFormConstants.TYPE, JsonFormConstants.EDIT_TEXT); field.put(JsonFormConstants.OPENMRS_ENTITY_ID, removeSpaces(entry.getKey().getName())); field.put(JsonFormConstants.VALUE, entry.getValue()); @@ -574,16 +585,16 @@ public static JSONObject getVisitJSONFromVisitDetails(String entityID, Map Date: Mon, 26 Aug 2019 08:37:18 +0300 Subject: [PATCH 08/11] fixed failing test --- .../smartregister/chw/anc/util/NCUtils.java | 1 + .../chw/anc/util/VisitUtils.java | 39 +++++++++++++++++++ .../adapter/BaseAncHomeVisitAdapterTest.java | 6 +++ 3 files changed, 46 insertions(+) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index 86999b71..bed344d8 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -422,6 +422,7 @@ public static Visit eventToVisit(org.smartregister.domain.db.Event event) throws detail.setVisitDetailsId(org.smartregister.chw.anc.util.JsonFormUtils.generateRandomUUIDString()); detail.setVisitId(visit.getVisitId()); detail.setVisitKey(obs.getFormSubmissionField()); + detail.setParentCode(obs.getParentCode()); if (detail.getVisitKey().contains("date")) { // parse the diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java index 8d8dc6c5..251bb12b 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java @@ -8,6 +8,7 @@ import com.google.gson.GsonBuilder; import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; import org.smartregister.chw.anc.AncLibrary; import org.smartregister.chw.anc.domain.Visit; import org.smartregister.chw.anc.domain.VisitDetail; @@ -25,10 +26,14 @@ import org.smartregister.immunization.service.intent.VaccineIntentService; import org.smartregister.repository.AllSharedPreferences; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; public class VisitUtils { @@ -141,6 +146,11 @@ private static void processVisitDetails(VisitDetailsRepository visitDetailsRepos break; } } + VaccineWrapper wrapper = getVaccineWrapperFromDetails(visitDetail); + if (wrapper != null) + vaccineWrappers.add(wrapper); + + visitDetailsRepository.completeProcessing(visitDetail.getVisitDetailsId()); } } @@ -159,6 +169,35 @@ private static void processVisitDetails(VisitDetailsRepository visitDetailsRepos } } + private static VaccineWrapper getVaccineWrapperFromDetails(VisitDetail detail) { + if (!"vaccine".equalsIgnoreCase(detail.getParentCode())) + return null; + Date vacDate = getDateFromString(detail.getDetails()); + if (vacDate == null) return null; + + VaccineWrapper vaccineWrapper = new VaccineWrapper(); + vaccineWrapper.setName(detail.getVisitKey()); + vaccineWrapper.setUpdatedVaccineDate(new DateTime(vacDate), false); + + return vaccineWrapper; + } + + public static Date getDateFromString(String dateStr) { + Date date = getDateFromString(dateStr, "yyyy-MM-dd"); + if (date == null) + date = getDateFromString(dateStr, "dd-MM-yyyy"); + + return date; + } + + public static Date getDateFromString(String strDate, String format) { + try { + return new SimpleDateFormat(format, Locale.getDefault()).parse(strDate); + } catch (ParseException e) { + return null; + } + } + public static void saveVaccines(List tags, String baseEntityID) { for (VaccineWrapper tag : tags) { if (tag.getUpdatedVaccineDate() == null) { diff --git a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java index 1ac3b9f2..004ebd11 100644 --- a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java +++ b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/adapter/BaseAncHomeVisitAdapterTest.java @@ -39,6 +39,8 @@ public void setUp() { public void testGetCircleColorComplete() throws Exception { BaseAncHomeVisitAdapter ancHomeVisitAdapter = new BaseAncHomeVisitAdapter(context, view, myDataset); BaseAncHomeVisitAction ancHomeVisitAction = Mockito.mock(BaseAncHomeVisitAction.class); + Mockito.doReturn(true).when(ancHomeVisitAction).isEnabled(); + Mockito.doReturn(true).when(ancHomeVisitAction).isValid(); Mockito.doReturn(BaseAncHomeVisitAction.Status.COMPLETED).when(ancHomeVisitAction).getActionStatus(); int res = Whitebox.invokeMethod(ancHomeVisitAdapter, "getCircleColor", ancHomeVisitAction); @@ -49,6 +51,8 @@ public void testGetCircleColorComplete() throws Exception { public void testGetCircleColorPending() throws Exception { BaseAncHomeVisitAdapter ancHomeVisitAdapter = new BaseAncHomeVisitAdapter(context, view, myDataset); BaseAncHomeVisitAction ancHomeVisitAction = Mockito.mock(BaseAncHomeVisitAction.class); + Mockito.doReturn(true).when(ancHomeVisitAction).isEnabled(); + Mockito.doReturn(true).when(ancHomeVisitAction).isValid(); Mockito.doReturn(BaseAncHomeVisitAction.Status.PENDING).when(ancHomeVisitAction).getActionStatus(); int res = Whitebox.invokeMethod(ancHomeVisitAdapter, "getCircleColor", ancHomeVisitAction); @@ -59,6 +63,8 @@ public void testGetCircleColorPending() throws Exception { public void testGetCircleColorPartial() throws Exception { BaseAncHomeVisitAdapter ancHomeVisitAdapter = new BaseAncHomeVisitAdapter(context, view, myDataset); BaseAncHomeVisitAction ancHomeVisitAction = Mockito.mock(BaseAncHomeVisitAction.class); + Mockito.doReturn(true).when(ancHomeVisitAction).isEnabled(); + Mockito.doReturn(true).when(ancHomeVisitAction).isValid(); Mockito.doReturn(BaseAncHomeVisitAction.Status.PARTIALLY_COMPLETED).when(ancHomeVisitAction).getActionStatus(); int res = Whitebox.invokeMethod(ancHomeVisitAdapter, "getCircleColor", ancHomeVisitAction); From 65ae24ef193486cc326e974e8bec6b6c50450230 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Mon, 26 Aug 2019 11:32:14 +0300 Subject: [PATCH 09/11] Codacy fix --- .../BaseAncHomeVisitInteractor.java | 28 ++++++-------- .../smartregister/chw/anc/util/NCUtils.java | 37 ++++++++----------- .../chw/anc/util/VisitUtils.java | 18 +++------ 3 files changed, 32 insertions(+), 51 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java index 6541a5c4..8b87d112 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/interactor/BaseAncHomeVisitInteractor.java @@ -112,29 +112,22 @@ private void submitVisit(final boolean editMode, final String memberID, final Ma for (Map.Entry entry : map.entrySet()) { String json = entry.getValue().getJsonPayload(); if (StringUtils.isNotBlank(json)) { - // do not process events that are meant to be in detached mode // in a similar manner to the the aggregated events BaseAncHomeVisitAction.ProcessingMode mode = entry.getValue().getProcessingMode(); - if (mode == BaseAncHomeVisitAction.ProcessingMode.DETACHED - && StringUtils.isNotBlank(entry.getValue().getBaseEntityID())) { + if (mode == BaseAncHomeVisitAction.ProcessingMode.DETACHED) { + detachedVisits.put(entry.getKey(), entry.getValue()); - continue; - } + } else if (mode == BaseAncHomeVisitAction.ProcessingMode.SEPARATE && StringUtils.isBlank(parentEventType)) { - if (mode == BaseAncHomeVisitAction.ProcessingMode.SEPARATE - && StringUtils.isNotBlank(entry.getValue().getBaseEntityID()) - && StringUtils.isBlank(parentEventType) - ) { externalVisits.put(entry.getKey(), entry.getValue()); - continue; - } + } else { + jsons.put(entry.getKey(), json); + JSONObject jsonObject = new JSONObject(json); - jsons.put(entry.getKey(), json); - JSONObject jsonObject = new JSONObject(json); - - extractVaccineWrappers(entry, vaccineWrapperMap, jsonObject); - extractServiceWrappers(entry, serviceWrapperMap, jsonObject); + extractVaccineWrappers(entry, vaccineWrapperMap, jsonObject); + extractServiceWrappers(entry, serviceWrapperMap, jsonObject); + } } } @@ -180,6 +173,7 @@ private void extractServiceWrappers( /** * recursively persist visits to the db + * * @param visit * @param externalVisits * @param memberID @@ -229,7 +223,7 @@ private Visit saveVisit(boolean editMode, String memberID, String encounterType, return null; } - private VisitRepository visitRepository(){ + private VisitRepository visitRepository() { return AncLibrary.getInstance().visitRepository(); } diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index bed344d8..ec5f1ec9 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -295,16 +295,8 @@ public static Map> eventsObsToDetails(List obsLis detail.setBaseEntityId(baseEntityID); detail.setVisitKey(obs.getFormSubmissionField()); detail.setParentCode(obs.getParentCode()); - - if (detail.getVisitKey().contains("date")) { - // parse the - detail.setDetails(getFormattedDate(getSourceDateFormat(), getSaveDateFormat(), cleanString(obs.getValues().toString()))); - detail.setHumanReadable(getFormattedDate(getSourceDateFormat(), getSaveDateFormat(), cleanString(obs.getHumanReadableValues().toString()))); - } else { - detail.setDetails(cleanString(obs.getValues().toString())); - detail.setHumanReadable(cleanString(obs.getHumanReadableValues().toString())); - } - + detail.setDetails(getDetailsValue(detail, obs.getValues().toString())); + detail.setHumanReadable(getDetailsValue(detail, obs.getHumanReadableValues().toString())); detail.setJsonDetails(new JSONObject(JsonFormUtils.gson.toJson(obs)).toString()); detail.setProcessed(false); detail.setCreatedAt(new Date()); @@ -423,16 +415,8 @@ public static Visit eventToVisit(org.smartregister.domain.db.Event event) throws detail.setVisitId(visit.getVisitId()); detail.setVisitKey(obs.getFormSubmissionField()); detail.setParentCode(obs.getParentCode()); - - if (detail.getVisitKey().contains("date")) { - // parse the - detail.setDetails(getFormattedDate(getSourceDateFormat(), getSaveDateFormat(), cleanString(obs.getValues().toString()))); - detail.setHumanReadable(getFormattedDate(getSourceDateFormat(), getSaveDateFormat(), cleanString(obs.getHumanReadableValues().toString()))); - } else { - detail.setDetails(cleanString(obs.getValues().toString())); - detail.setHumanReadable(cleanString(obs.getHumanReadableValues().toString())); - } - + detail.setDetails(getDetailsValue(detail, obs.getValues().toString())); + detail.setHumanReadable(getDetailsValue(detail, obs.getHumanReadableValues().toString())); detail.setProcessed(true); detail.setCreatedAt(new Date()); detail.setUpdatedAt(new Date()); @@ -451,6 +435,17 @@ public static Visit eventToVisit(org.smartregister.domain.db.Event event) throws return visit; } + public static String getDetailsValue(VisitDetail detail, String val) { + String clean_val = cleanString(val); + if (detail.getVisitKey().contains("date")) { + return getFormattedDate(getSourceDateFormat(), getSaveDateFormat(), clean_val); + } else if ("vaccine".equalsIgnoreCase(detail.getParentCode()) && !Constants.HOME_VISIT.VACCINE_NOT_GIVEN.equalsIgnoreCase(clean_val)) { + return getFormattedDate(getSourceDateFormat(), getSaveDateFormat(), clean_val); + } + + return clean_val; + } + public static int getMemberProfileImageResourceIDentifier(String entityType) { return R.mipmap.ic_member; } @@ -464,7 +459,6 @@ public static String gestationAgeString(String lmp, Context context, boolean ful } public static void saveVaccineEvents(JSONArray fields, String baseID) { - for (int i = 0; i < vaccines.length; i++) { saveVaccineEvent(vaccines[i], getFieldJSONObject(fields, vaccines[i]), baseID); } @@ -609,7 +603,6 @@ public static JSONObject getVisitJSONFromVisitDetails(String entityID, Map tags, String baseEntityID) if (StringUtils.isNumeric(lastChar)) { vaccine.setCalculation(Integer.valueOf(lastChar)); } else { - vaccine.setCalculation(-1); + vaccine.setCalculation(0); } JsonFormUtils.tagSyncMetadata(NCUtils.context().allSharedPreferences(), vaccine); From 806a9a7fbfec68867252bde3cbcaac97de754ff0 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Mon, 26 Aug 2019 12:17:33 +0300 Subject: [PATCH 10/11] Fixed processing visits --- .../chw/anc/util/VisitUtils.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java index b22ad9e4..7d854086 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/VisitUtils.java @@ -97,7 +97,7 @@ public static void processVisits(VisitRepository visitRepository, VisitDetailsRe if (!v.getProcessed()) { // process details - processVisitDetails(visitDetailsRepository, v.getVisitId(), v.getBaseEntityId()); + processVisitDetails(v, visitDetailsRepository, v.getVisitId(), v.getBaseEntityId()); // persist to db Event baseEvent = new Gson().fromJson(v.getPreProcessedJson(), Event.class); @@ -117,7 +117,7 @@ public static void processVisits(VisitRepository visitRepository, VisitDetailsRe context.startService(new Intent(context, RecurringIntentService.class)); } - private static void processVisitDetails(VisitDetailsRepository visitDetailsRepository, String visitID, String baseEntityID) throws Exception { + private static void processVisitDetails(Visit visit, VisitDetailsRepository visitDetailsRepository, String visitID, String baseEntityID) throws Exception { List visitDetailList = visitDetailsRepository.getVisits(visitID); List vaccineWrappers = new ArrayList<>(); List serviceWrappers = new ArrayList<>(); @@ -145,10 +145,7 @@ private static void processVisitDetails(VisitDetailsRepository visitDetailsRepos break; } } - VaccineWrapper wrapper = getVaccineWrapperFromDetails(visitDetail); - if (wrapper != null) - vaccineWrappers.add(wrapper); - + saveVisitDetailsAsVaccine(visitDetail, baseEntityID, visit.getDate()); visitDetailsRepository.completeProcessing(visitDetail.getVisitDetailsId()); } @@ -168,7 +165,7 @@ private static void processVisitDetails(VisitDetailsRepository visitDetailsRepos } } - private static VaccineWrapper getVaccineWrapperFromDetails(VisitDetail detail) { + private static Vaccine saveVisitDetailsAsVaccine(VisitDetail detail, String baseEntityID, Date eventDate) { if (!"vaccine".equalsIgnoreCase(detail.getParentCode())) return null; @@ -178,11 +175,23 @@ private static VaccineWrapper getVaccineWrapperFromDetails(VisitDetail detail) { Date vacDate = getDateFromString(detail.getDetails()); if (vacDate == null) return null; - VaccineWrapper vaccineWrapper = new VaccineWrapper(); - vaccineWrapper.setName(detail.getVisitKey()); - vaccineWrapper.setUpdatedVaccineDate(new DateTime(vacDate), false); + Vaccine vaccine = new Vaccine(); + vaccine.setBaseEntityId(baseEntityID); + vaccine.setName(detail.getVisitKey()); + vaccine.setDate(vacDate); + vaccine.setCreatedAt(eventDate); + + String lastChar = vaccine.getName().substring(vaccine.getName().length() - 1); + if (StringUtils.isNumeric(lastChar)) { + vaccine.setCalculation(Integer.valueOf(lastChar)); + } else { + vaccine.setCalculation(0); + } + + JsonFormUtils.tagSyncMetadata(NCUtils.context().allSharedPreferences(), vaccine); + getVaccineRepository().add(vaccine); // persist to local db - return vaccineWrapper; + return vaccine; } public static Date getDateFromString(String dateStr) { From d7e10a73548d3a92af88796a7fbe18619d05d358 Mon Sep 17 00:00:00 2001 From: rkodev <43806892+rkodev@users.noreply.github.com> Date: Mon, 26 Aug 2019 12:40:19 +0300 Subject: [PATCH 11/11] Added test --- .../smartregister/chw/anc/util/NCUtils.java | 4 +- .../chw/anc/util/NCUtilsTest.java | 47 +++++++++++++++++++ ...itNCUtilsTest.java => VisitUtilsTest.java} | 2 +- 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/NCUtilsTest.java rename opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/{VisitNCUtilsTest.java => VisitUtilsTest.java} (99%) diff --git a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java index ec5f1ec9..33a4aa4c 100644 --- a/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java +++ b/opensrp-chw-anc/src/main/java/org/smartregister/chw/anc/util/NCUtils.java @@ -644,9 +644,9 @@ public static String toCSV(List list) { if (list.size() > 0) { StringBuilder sb = new StringBuilder(); for (String s : list) { - sb.append(s).append(","); + sb.append(s).append(", "); } - result = sb.deleteCharAt(sb.length() - 1).toString(); + result = sb.deleteCharAt(sb.length() - 2).toString(); } return result; } diff --git a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/NCUtilsTest.java b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/NCUtilsTest.java new file mode 100644 index 00000000..0f59b203 --- /dev/null +++ b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/NCUtilsTest.java @@ -0,0 +1,47 @@ +package org.smartregister.chw.anc.util; + +import org.junit.Assert; +import org.junit.Test; +import org.smartregister.chw.anc.domain.VisitDetail; + +import java.util.ArrayList; +import java.util.List; + +public class NCUtilsTest { + + @Test + public void testGetText() { + List details = new ArrayList<>(); + + VisitDetail visitDetail1 = new VisitDetail(); + visitDetail1.setHumanReadable("test1"); + details.add(visitDetail1); + + VisitDetail visitDetail2 = new VisitDetail(); + visitDetail2.setHumanReadable("test2"); + details.add(visitDetail2); + + VisitDetail visitDetail3 = new VisitDetail(); + details.add(visitDetail3); + + details.add(null); + + String val = NCUtils.getText(details).trim(); + String expected = "test1, test2"; + + Assert.assertEquals(expected, val); + } + + @Test + public void testGetTextOneParam() { + + VisitDetail visitDetail1 = new VisitDetail(); + visitDetail1.setHumanReadable("test1"); + + String val = NCUtils.getText(visitDetail1).trim(); + String expected = "test1"; + + Assert.assertEquals(expected, val); + } + +} diff --git a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/VisitNCUtilsTest.java b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/VisitUtilsTest.java similarity index 99% rename from opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/VisitNCUtilsTest.java rename to opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/VisitUtilsTest.java index b89d11ac..5ee3c2d1 100644 --- a/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/VisitNCUtilsTest.java +++ b/opensrp-chw-anc/src/test/java/org/smartregister/chw/anc/util/VisitUtilsTest.java @@ -39,7 +39,7 @@ import static org.junit.Assert.assertTrue; @PrepareForTest({AncLibrary.class, JsonFormUtils.class, ImmunizationLibrary.class}) -public class VisitNCUtilsTest { +public class VisitUtilsTest { @Rule public PowerMockRule rule = new PowerMockRule();