Skip to content

Commit 9c21f5a

Browse files
committed
LMH1-205: Unable to register vaccinations for child 2+ years
1 parent e5f2b25 commit 9c21f5a

File tree

13 files changed

+227
-30
lines changed

13 files changed

+227
-30
lines changed

opensrp-chw/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ android {
351351
lmh {
352352
dimension = 'baseDimension'
353353
applicationIdSuffix ".lmh"
354-
versionCode 2
355-
versionName "2.0.1-rc5"
354+
versionCode 4
355+
versionName "2.0.1"
356356
buildConfigField "int", "OPENMRS_UNIQUE_ID_INITIAL_BATCH_SIZE", '10000'
357357
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '10000'
358358
buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '1'
@@ -378,7 +378,7 @@ dependencies {
378378

379379
implementation('com.google.android.gms:play-services-vision:17.0.2')
380380

381-
implementation('org.smartregister:opensrp-client-chw-core:2.1.4-LMH-Beta-04-SNAPSHOT@aar') {
381+
implementation('org.smartregister:opensrp-client-chw-core:2.1.4-SNAPSHOT@aar') {
382382
transitive = true
383383
exclude group: 'com.android.support', module: 'appcompat-v7'
384384
exclude group: 'androidx.legacy', module: 'legacy-support-v4'

opensrp-chw/src/lmh/java/org/smartregister/chw/application/ChwApplicationFlv.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.smartregister.chw.application;
22

3+
import org.smartregister.chw.anc.domain.MemberObject;
4+
import org.smartregister.chw.dao.ChwChildDao;
5+
36
public class ChwApplicationFlv extends DefaultChwApplicationFlv {
47

58
@Override
@@ -229,22 +232,42 @@ public boolean greyOutFormActionsIfInvalid() {
229232

230233
@Override
231234
public boolean checkExtraForDueInFamily() {
232-
return true;
235+
return true;
233236
}
237+
234238
@Override
235-
public boolean hideCaregiverAndFamilyHeadWhenOnlyOneAdult(){
239+
public boolean hideCaregiverAndFamilyHeadWhenOnlyOneAdult() {
236240
return true;
237241
}
238242

239243
@Override
240-
public boolean showsPhysicallyDisabledView() { return false; }
244+
public boolean showsPhysicallyDisabledView() {
245+
return false;
246+
}
241247

242248
@Override
243-
public boolean vaccinesDefaultChecked() { return false; }
249+
public boolean vaccinesDefaultChecked() {
250+
return false;
251+
}
244252

245253
@Override
246254
public boolean checkDueStatusFromUpcomingServices() {
247255
return true;
248256
}
257+
258+
@Override
259+
public int immunizationCeilingMonths(MemberObject memberObject) {
260+
String gender = ChwChildDao.getChildGender(memberObject.getBaseEntityId());
261+
262+
if (gender != null && gender.equalsIgnoreCase("Female")) {
263+
if (memberObject.getAge() >= 9 && memberObject.getAge() <= 11) {
264+
return 132;
265+
} else {
266+
return 60;
267+
}
268+
}
269+
270+
return 60;
271+
}
249272
}
250273

opensrp-chw/src/main/java/org/smartregister/chw/activity/ChildProfileActivity.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ protected void initializePresenter() {
141141
@Override
142142
protected void setupViews() {
143143
super.setupViews();
144+
if (ChwApplication.getApplicationFlavor().checkDueStatusFromUpcomingServices()) {
145+
// Initially hide visit bar, that would be made visible after due services are checked
146+
findViewById(R.id.record_visit_bar)
147+
.setVisibility(View.GONE);
148+
}
149+
144150
familyFloatingMenu = new FamilyMemberFloatingMenu(this);
145151
LinearLayout.LayoutParams linearLayoutParams =
146152
new LinearLayout.LayoutParams(

opensrp-chw/src/main/java/org/smartregister/chw/application/ChwApplication.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.smartregister.chw.activity.ReportsActivity;
4545
import org.smartregister.chw.activity.UpdatesRegisterActivity;
4646
import org.smartregister.chw.anc.AncLibrary;
47+
import org.smartregister.chw.anc.domain.MemberObject;
4748
import org.smartregister.chw.anc.domain.Visit;
4849
import org.smartregister.chw.configs.AllClientsRegisterRowOptions;
4950
import org.smartregister.chw.core.application.CoreChwApplication;
@@ -678,6 +679,8 @@ public interface Flavor {
678679

679680
boolean hideCaregiverAndFamilyHeadWhenOnlyOneAdult();
680681

682+
int immunizationCeilingMonths(MemberObject memberObject);
683+
681684
boolean hasMap();
682685

683686
boolean showsPhysicallyDisabledView();

opensrp-chw/src/main/java/org/smartregister/chw/application/DefaultChwApplicationFlv.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.smartregister.chw.application;
22

3+
import org.smartregister.chw.anc.domain.MemberObject;
34
import org.smartregister.chw.core.utils.ChildDBConstants;
45
import org.smartregister.chw.core.utils.CoreConstants;
56
import org.smartregister.family.util.DBConstants;
@@ -324,6 +325,11 @@ public String[] getFTSTables() {
324325
return new String[]{CoreConstants.TABLE_NAME.FAMILY, CoreConstants.TABLE_NAME.FAMILY_MEMBER, CoreConstants.TABLE_NAME.CHILD};
325326
}
326327

328+
@Override
329+
public int immunizationCeilingMonths(MemberObject memberObject) {
330+
return 24;
331+
}
332+
327333
@Override
328334
public Map<String, String[]> getFTSSearchMap() {
329335
Map<String, String[]> map = new HashMap<>();

opensrp-chw/src/main/java/org/smartregister/chw/presenter/ChildProfilePresenter.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.smartregister.chw.R;
1515
import org.smartregister.chw.activity.ChildProfileActivity;
1616
import org.smartregister.chw.activity.ReferralRegistrationActivity;
17+
import org.smartregister.chw.anc.domain.MemberObject;
1718
import org.smartregister.chw.application.ChwApplication;
1819
import org.smartregister.chw.core.contract.CoreChildProfileContract;
1920
import org.smartregister.chw.core.model.ChildVisit;
@@ -28,6 +29,7 @@
2829
import org.smartregister.chw.model.ReferralTypeModel;
2930
import org.smartregister.chw.util.Constants;
3031
import org.smartregister.chw.util.JsonFormUtils;
32+
import org.smartregister.chw.util.UpcomingServicesUtil;
3133
import org.smartregister.chw.util.Utils;
3234
import org.smartregister.clientandeventmodel.Client;
3335
import org.smartregister.clientandeventmodel.Event;
@@ -52,6 +54,7 @@
5254
public class ChildProfilePresenter extends CoreChildProfilePresenter {
5355

5456
private List<ReferralTypeModel> referralTypeModels;
57+
private MemberObject childMemberObject = null;
5558

5659
public ChildProfilePresenter(CoreChildProfileContract.View childView, CoreChildProfileContract.Flavor flavor, CoreChildProfileContract.Model model, String childBaseEntityId) {
5760
super(childView, model, childBaseEntityId);
@@ -134,6 +137,7 @@ public void startSickChildForm(CommonPersonObjectClient client) {
134137
@Override
135138
public void refreshProfileTopSection(CommonPersonObjectClient client, CommonPersonObject familyPersonObject) {
136139
super.refreshProfileTopSection(client, familyPersonObject);
140+
childMemberObject = new MemberObject(client);
137141

138142
if (ChwApplication.getApplicationFlavor().showLastNameOnChildProfile()) {
139143
String relationalId = getValue(client.getColumnmaps(), ChildDBConstants.KEY.RELATIONAL_ID, true).toLowerCase();
@@ -189,7 +193,12 @@ public void updateChildService(CoreChildService childService) {
189193
}
190194

191195
private void setDueView() {
192-
if (ChwChildDao.hasDueTodayVaccines(childBaseEntityId) || ChwChildDao.hasDueAlerts(childBaseEntityId)) {
196+
// boolean vaccineCardReceived = VisitDao.memberHasVaccineCard(childBaseEntityId);
197+
198+
if ((childMemberObject != null && getView() != null
199+
&& UpcomingServicesUtil.hasUpcomingDueServices(childMemberObject, getView().getContext()))
200+
|| ChwChildDao.hasDueTodayVaccines(childBaseEntityId)
201+
|| ChwChildDao.hasDueAlerts(childBaseEntityId)) {
193202
getView().setVisitButtonDueStatus();
194203
} else {
195204
getView().setNoButtonView();

opensrp-chw/src/main/java/org/smartregister/chw/presenter/FamilyProfileDuePresenter.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,24 @@ private String getChildDueQueryForChildrenUnderTwoAndGirlsAgeNineToEleven() {
5858
String ageFilter = "(((julianday('now') - julianday(ec_child.dob))/365.25) < 2 or (ec_child.gender = 'Female' and (((julianday('now') - julianday(ec_child.dob))/365.25) BETWEEN 9 AND 11)))\n";
5959
return (ChwApplication.getApplicationFlavor().checkExtraForDueInFamily() ? ageFilter :
6060
" (ifnull(schedule_service.completion_date,'') = '' and schedule_service.expiry_date >= strftime('%Y-%m-%d') " +
61-
"and schedule_service.due_date <= strftime('%Y-%m-%d') and ifnull(schedule_service.not_done_date,'') = '' ) " +
62-
"and " + ageFilter);
61+
"and schedule_service.due_date <= strftime('%Y-%m-%d') and ifnull(schedule_service.not_done_date,'') = '' ) " +
62+
"and " + ageFilter);
6363
}
6464

65-
private String getSelectCondition(){
65+
private String getSelectCondition() {
6666
String condition = " ( ec_family_member.relational_id = '" + this.familyBaseEntityId + "' or ec_family.base_entity_id = '" + this.familyBaseEntityId + "' ) AND ";
67-
if(ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()){
67+
if (ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()) {
6868
condition += getDefaultChildDueQuery();
6969
// + " EXISTS(select * from alerts where caseID = ec_family_member.base_entity_id and status in ('normal','urgent') and expiryDate > date()) AND "
70-
}
71-
else {
70+
} else {
7271
condition += getChildDueQueryForChildrenUnderTwoAndGirlsAgeNineToEleven();
7372
// + "EXISTS(select * from alerts where caseID = ec_family_member.base_entity_id and status in ('normal','urgent') and expiryDate > date()) AND "
7473
}
7574

7675
return condition + (ChwApplication.getApplicationFlavor().checkExtraForDueInFamily() ? String.format(" and ec_family_member.base_entity_id in (%s)", validMembers()) : "");
7776
}
7877

79-
String validMembers(){
78+
String validMembers() {
8079
List<Pair<String, String>> familyMembers = FamilyMemberDao.getFamilyMembers(this.familyBaseEntityId);
8180

8281
StringBuilder joiner = new StringBuilder();
@@ -86,14 +85,16 @@ String validMembers(){
8685
member.setFamilyBaseEntityId(this.familyBaseEntityId);
8786
member.setDob(familyMemberRepr.second);
8887

89-
boolean vaccineCardReceived = VisitDao.memberHasVaccineCard(member.getBaseEntityId());
88+
// boolean vaccineCardReceived = VisitDao.memberHasVaccineCard(member.getBaseEntityId());
89+
String childGender = ChwChildDao.getChildGender(member.getBaseEntityId());
9090

91-
if (!vaccineCardReceived || UpcomingServicesUtil.hasUpcomingDueServices(member, contextSupplier.get())) {
91+
if (/*!vaccineCardReceived || */UpcomingServicesUtil.showStatusForChild(member, childGender)
92+
&& UpcomingServicesUtil.hasUpcomingDueServices(member, contextSupplier.get())) {
9293
joiner.append(String.format("'%s'", member.getBaseEntityId()));
9394
joiner.append(",");
9495
}
9596
}
96-
if(!joiner.toString().equalsIgnoreCase("")){
97+
if (!joiner.toString().equalsIgnoreCase("")) {
9798
joiner.deleteCharAt(joiner.length() - 1);
9899
}
99100

@@ -108,7 +109,7 @@ public boolean saveDataFamilyKit(String jsonObject) {
108109
return familyKitModel.saveFamilyKitEvent(jsonObject);
109110
}
110111

111-
static class FamilyMemberDao extends AbstractDao{
112+
static class FamilyMemberDao extends AbstractDao {
112113
public static List<Pair<String, String>> getFamilyMembers(String baseEntityId) {
113114
String sql = "SELECT base_entity_id, dob from ec_family_member" +
114115
" where relational_id = '" + baseEntityId + "'" +

opensrp-chw/src/main/java/org/smartregister/chw/provider/FamilyRegisterProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ private void updateButtonState(Context context, RegisterViewHolder viewHolder, M
132132
setTasksDoneStatus(context, viewHolder.dueButton);
133133
} else if (visits_not_done != null && visits_not_done > 0) {
134134
setTaskNotDone(context, viewHolder.dueButton);
135+
}else if (due == 0 && over_due == 0){
136+
viewHolder.dueButton.setVisibility(View.GONE);
135137
}
136138

137139
} else {

opensrp-chw/src/main/java/org/smartregister/chw/util/UpcomingServicesUtil.java

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.joda.time.DateTime;
88
import org.joda.time.Days;
99
import org.joda.time.LocalDate;
10+
import org.joda.time.Months;
1011
import org.smartregister.chw.anc.contract.BaseAncUpcomingServicesContract;
1112
import org.smartregister.chw.anc.domain.MemberObject;
1213
import org.smartregister.chw.anc.model.BaseUpcomingService;
@@ -15,14 +16,20 @@
1516
import org.smartregister.chw.dao.ChwChildDao;
1617
import org.smartregister.chw.interactor.ChildUpcomingServiceInteractor;
1718

19+
import java.text.ParseException;
20+
import java.text.SimpleDateFormat;
1821
import java.util.ArrayList;
22+
import java.util.Date;
1923
import java.util.HashMap;
2024
import java.util.List;
25+
import java.util.Locale;
2126
import java.util.Map;
2227
import java.util.function.BiFunction;
2328
import java.util.function.Consumer;
2429
import java.util.function.Function;
2530

31+
import timber.log.Timber;
32+
2633
public final class UpcomingServicesUtil {
2734
static List<BaseUpcomingService> deepCopy(@Nullable List<BaseUpcomingService> serviceList) {
2835
if (serviceList == null) return null;
@@ -32,7 +39,7 @@ static List<BaseUpcomingService> deepCopy(@Nullable List<BaseUpcomingService> se
3239
for (BaseUpcomingService service : serviceList) {
3340
BaseUpcomingService copy = new BaseUpcomingService();
3441
copy.setServiceName(service.getServiceName());
35-
copy.setServiceDate(service.getOverDueDate());
42+
copy.setServiceDate(service.getServiceDate());
3643
copy.setExpiryDate(service.getExpiryDate());
3744
copy.setOverDueDate(service.getOverDueDate());
3845

@@ -71,14 +78,29 @@ static String getDueServicesState(List<BaseUpcomingService> serviceList) {
7178
return hasDue ? CoreConstants.VISIT_STATE.DUE : null;
7279
}
7380

74-
public static boolean hasUpcomingDueServices(MemberObject memberObject, Context ctx){
75-
String childGender = ChwChildDao.getChildGender(memberObject.getBaseEntityId());
81+
public static boolean showStatusForChild(MemberObject memberObject, final String childGender) {
7682
int childAge = memberObject.getAge();
77-
if (!ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()
78-
&& childAge >= 2
79-
&& !(childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11)){
80-
return false;
83+
84+
return (ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus() && (childAge < 2 || (childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11))
85+
|| !ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus());
86+
}
87+
88+
static Integer getAgeInMonths(MemberObject memberObject) {
89+
Date dob;
90+
try {
91+
dob = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(memberObject.getDob());
92+
return Months.monthsBetween(new LocalDate(dob), new LocalDate()).getMonths();
93+
} catch (ParseException e) {
94+
Timber.e(e);
8195
}
96+
return null;
97+
}
98+
99+
public static boolean hasUpcomingDueServices(MemberObject memberObject, Context ctx) {
100+
Integer monthAge = getAgeInMonths(memberObject);
101+
if (monthAge == null || monthAge >= ChwApplication.getApplicationFlavor().immunizationCeilingMonths(memberObject))
102+
return false;
103+
82104
List<BaseUpcomingService> upcomingServices = new ChildUpcomingServiceInteractor().getUpcomingServices(memberObject, ctx);
83105
return getDueServicesState(upcomingServices) != null;
84106
}
@@ -88,7 +110,7 @@ public static void fetchUpcomingDueServicesState(MemberObject memberObject, Cont
88110
int childAge = memberObject.getAge();
89111
if (!ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()
90112
&& childAge >= 2
91-
&& !(childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11)){
113+
&& !(childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11)) {
92114
String dueStatus = "";
93115
onDueStatusFetched.accept(dueStatus);
94116
return;
@@ -102,10 +124,10 @@ public void onDataFetched(List<BaseUpcomingService> serviceList) {
102124
});
103125
}
104126

105-
public static void fetchFamilyUpcomingDueServicesState(List<MemberObject> memberObjects, Context ctx, Consumer<Map<String, Integer> > onFamilyDueStatesConsumer){
127+
public static void fetchFamilyUpcomingDueServicesState(List<MemberObject> memberObjects, Context ctx, Consumer<Map<String, Integer>> onFamilyDueStatesConsumer) {
106128
Map<String, Integer> upcoming = new HashMap<>();
107129
List<String> fetched = new ArrayList<>();
108-
for (MemberObject member: memberObjects) {
130+
for (MemberObject member : memberObjects) {
109131
fetchUpcomingDueServicesState(member, ctx, new Consumer<String>() {
110132
@Override
111133
public void accept(String s) {
@@ -122,7 +144,7 @@ public Integer apply(String s) {
122144
}
123145
});
124146
fetched.add(s);
125-
if (fetched.size() >= memberObjects.size()){
147+
if (fetched.size() >= memberObjects.size()) {
126148
onFamilyDueStatesConsumer.accept(upcoming);
127149
}
128150
}

opensrp-chw/src/test/java/org/smartregister/chw/application/CoreChwApplicationTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.mockito.Mockito;
66
import org.robolectric.util.ReflectionHelpers;
77
import org.smartregister.chw.BaseUnitTest;
8+
import org.smartregister.chw.anc.domain.MemberObject;
89
import org.smartregister.immunization.ImmunizationLibrary;
910
import org.smartregister.reporting.ReportingLibrary;
1011

@@ -29,4 +30,10 @@ public void testP2PClassifierIsInitialized() {
2930
ReflectionHelpers.setField(application, "flavor", flv);
3031
Assert.assertNotNull(application.getP2PClassifier());
3132
}
33+
34+
@Test
35+
public void testApplicationImmunizationCeiling(){
36+
MemberObject memberObject = Mockito.mock(MemberObject.class);
37+
Assert.assertEquals(24, ChwApplication.getApplicationFlavor().immunizationCeilingMonths(memberObject));
38+
}
3239
}

0 commit comments

Comments
 (0)