Skip to content

Commit

Permalink
LMH1-205: Unable to register vaccinations for child 2+ years
Browse files Browse the repository at this point in the history
  • Loading branch information
LZRS committed May 29, 2022
1 parent e5f2b25 commit 9c21f5a
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 30 deletions.
6 changes: 3 additions & 3 deletions opensrp-chw/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ android {
lmh {
dimension = 'baseDimension'
applicationIdSuffix ".lmh"
versionCode 2
versionName "2.0.1-rc5"
versionCode 4
versionName "2.0.1"
buildConfigField "int", "OPENMRS_UNIQUE_ID_INITIAL_BATCH_SIZE", '10000'
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '10000'
buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '1'
Expand All @@ -378,7 +378,7 @@ dependencies {

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

implementation('org.smartregister:opensrp-client-chw-core:2.1.4-LMH-Beta-04-SNAPSHOT@aar') {
implementation('org.smartregister:opensrp-client-chw-core:2.1.4-SNAPSHOT@aar') {
transitive = true
exclude group: 'com.android.support', module: 'appcompat-v7'
exclude group: 'androidx.legacy', module: 'legacy-support-v4'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.smartregister.chw.application;

import org.smartregister.chw.anc.domain.MemberObject;
import org.smartregister.chw.dao.ChwChildDao;

public class ChwApplicationFlv extends DefaultChwApplicationFlv {

@Override
Expand Down Expand Up @@ -229,22 +232,42 @@ public boolean greyOutFormActionsIfInvalid() {

@Override
public boolean checkExtraForDueInFamily() {
return true;
return true;
}

@Override
public boolean hideCaregiverAndFamilyHeadWhenOnlyOneAdult(){
public boolean hideCaregiverAndFamilyHeadWhenOnlyOneAdult() {
return true;
}

@Override
public boolean showsPhysicallyDisabledView() { return false; }
public boolean showsPhysicallyDisabledView() {
return false;
}

@Override
public boolean vaccinesDefaultChecked() { return false; }
public boolean vaccinesDefaultChecked() {
return false;
}

@Override
public boolean checkDueStatusFromUpcomingServices() {
return true;
}

@Override
public int immunizationCeilingMonths(MemberObject memberObject) {
String gender = ChwChildDao.getChildGender(memberObject.getBaseEntityId());

if (gender != null && gender.equalsIgnoreCase("Female")) {
if (memberObject.getAge() >= 9 && memberObject.getAge() <= 11) {
return 132;
} else {
return 60;
}
}

return 60;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ protected void initializePresenter() {
@Override
protected void setupViews() {
super.setupViews();
if (ChwApplication.getApplicationFlavor().checkDueStatusFromUpcomingServices()) {
// Initially hide visit bar, that would be made visible after due services are checked
findViewById(R.id.record_visit_bar)
.setVisibility(View.GONE);
}

familyFloatingMenu = new FamilyMemberFloatingMenu(this);
LinearLayout.LayoutParams linearLayoutParams =
new LinearLayout.LayoutParams(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.smartregister.chw.activity.ReportsActivity;
import org.smartregister.chw.activity.UpdatesRegisterActivity;
import org.smartregister.chw.anc.AncLibrary;
import org.smartregister.chw.anc.domain.MemberObject;
import org.smartregister.chw.anc.domain.Visit;
import org.smartregister.chw.configs.AllClientsRegisterRowOptions;
import org.smartregister.chw.core.application.CoreChwApplication;
Expand Down Expand Up @@ -678,6 +679,8 @@ public interface Flavor {

boolean hideCaregiverAndFamilyHeadWhenOnlyOneAdult();

int immunizationCeilingMonths(MemberObject memberObject);

boolean hasMap();

boolean showsPhysicallyDisabledView();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.smartregister.chw.application;

import org.smartregister.chw.anc.domain.MemberObject;
import org.smartregister.chw.core.utils.ChildDBConstants;
import org.smartregister.chw.core.utils.CoreConstants;
import org.smartregister.family.util.DBConstants;
Expand Down Expand Up @@ -324,6 +325,11 @@ public String[] getFTSTables() {
return new String[]{CoreConstants.TABLE_NAME.FAMILY, CoreConstants.TABLE_NAME.FAMILY_MEMBER, CoreConstants.TABLE_NAME.CHILD};
}

@Override
public int immunizationCeilingMonths(MemberObject memberObject) {
return 24;
}

@Override
public Map<String, String[]> getFTSSearchMap() {
Map<String, String[]> map = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.smartregister.chw.R;
import org.smartregister.chw.activity.ChildProfileActivity;
import org.smartregister.chw.activity.ReferralRegistrationActivity;
import org.smartregister.chw.anc.domain.MemberObject;
import org.smartregister.chw.application.ChwApplication;
import org.smartregister.chw.core.contract.CoreChildProfileContract;
import org.smartregister.chw.core.model.ChildVisit;
Expand All @@ -28,6 +29,7 @@
import org.smartregister.chw.model.ReferralTypeModel;
import org.smartregister.chw.util.Constants;
import org.smartregister.chw.util.JsonFormUtils;
import org.smartregister.chw.util.UpcomingServicesUtil;
import org.smartregister.chw.util.Utils;
import org.smartregister.clientandeventmodel.Client;
import org.smartregister.clientandeventmodel.Event;
Expand All @@ -52,6 +54,7 @@
public class ChildProfilePresenter extends CoreChildProfilePresenter {

private List<ReferralTypeModel> referralTypeModels;
private MemberObject childMemberObject = null;

public ChildProfilePresenter(CoreChildProfileContract.View childView, CoreChildProfileContract.Flavor flavor, CoreChildProfileContract.Model model, String childBaseEntityId) {
super(childView, model, childBaseEntityId);
Expand Down Expand Up @@ -134,6 +137,7 @@ public void startSickChildForm(CommonPersonObjectClient client) {
@Override
public void refreshProfileTopSection(CommonPersonObjectClient client, CommonPersonObject familyPersonObject) {
super.refreshProfileTopSection(client, familyPersonObject);
childMemberObject = new MemberObject(client);

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

private void setDueView() {
if (ChwChildDao.hasDueTodayVaccines(childBaseEntityId) || ChwChildDao.hasDueAlerts(childBaseEntityId)) {
// boolean vaccineCardReceived = VisitDao.memberHasVaccineCard(childBaseEntityId);

if ((childMemberObject != null && getView() != null
&& UpcomingServicesUtil.hasUpcomingDueServices(childMemberObject, getView().getContext()))
|| ChwChildDao.hasDueTodayVaccines(childBaseEntityId)
|| ChwChildDao.hasDueAlerts(childBaseEntityId)) {
getView().setVisitButtonDueStatus();
} else {
getView().setNoButtonView();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,24 @@ private String getChildDueQueryForChildrenUnderTwoAndGirlsAgeNineToEleven() {
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";
return (ChwApplication.getApplicationFlavor().checkExtraForDueInFamily() ? ageFilter :
" (ifnull(schedule_service.completion_date,'') = '' and schedule_service.expiry_date >= strftime('%Y-%m-%d') " +
"and schedule_service.due_date <= strftime('%Y-%m-%d') and ifnull(schedule_service.not_done_date,'') = '' ) " +
"and " + ageFilter);
"and schedule_service.due_date <= strftime('%Y-%m-%d') and ifnull(schedule_service.not_done_date,'') = '' ) " +
"and " + ageFilter);
}

private String getSelectCondition(){
private String getSelectCondition() {
String condition = " ( ec_family_member.relational_id = '" + this.familyBaseEntityId + "' or ec_family.base_entity_id = '" + this.familyBaseEntityId + "' ) AND ";
if(ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()){
if (ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()) {
condition += getDefaultChildDueQuery();
// + " EXISTS(select * from alerts where caseID = ec_family_member.base_entity_id and status in ('normal','urgent') and expiryDate > date()) AND "
}
else {
} else {
condition += getChildDueQueryForChildrenUnderTwoAndGirlsAgeNineToEleven();
// + "EXISTS(select * from alerts where caseID = ec_family_member.base_entity_id and status in ('normal','urgent') and expiryDate > date()) AND "
}

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

String validMembers(){
String validMembers() {
List<Pair<String, String>> familyMembers = FamilyMemberDao.getFamilyMembers(this.familyBaseEntityId);

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

boolean vaccineCardReceived = VisitDao.memberHasVaccineCard(member.getBaseEntityId());
// boolean vaccineCardReceived = VisitDao.memberHasVaccineCard(member.getBaseEntityId());
String childGender = ChwChildDao.getChildGender(member.getBaseEntityId());

if (!vaccineCardReceived || UpcomingServicesUtil.hasUpcomingDueServices(member, contextSupplier.get())) {
if (/*!vaccineCardReceived || */UpcomingServicesUtil.showStatusForChild(member, childGender)
&& UpcomingServicesUtil.hasUpcomingDueServices(member, contextSupplier.get())) {
joiner.append(String.format("'%s'", member.getBaseEntityId()));
joiner.append(",");
}
}
if(!joiner.toString().equalsIgnoreCase("")){
if (!joiner.toString().equalsIgnoreCase("")) {
joiner.deleteCharAt(joiner.length() - 1);
}

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

static class FamilyMemberDao extends AbstractDao{
static class FamilyMemberDao extends AbstractDao {
public static List<Pair<String, String>> getFamilyMembers(String baseEntityId) {
String sql = "SELECT base_entity_id, dob from ec_family_member" +
" where relational_id = '" + baseEntityId + "'" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ private void updateButtonState(Context context, RegisterViewHolder viewHolder, M
setTasksDoneStatus(context, viewHolder.dueButton);
} else if (visits_not_done != null && visits_not_done > 0) {
setTaskNotDone(context, viewHolder.dueButton);
}else if (due == 0 && over_due == 0){
viewHolder.dueButton.setVisibility(View.GONE);
}

} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.smartregister.chw.anc.contract.BaseAncUpcomingServicesContract;
import org.smartregister.chw.anc.domain.MemberObject;
import org.smartregister.chw.anc.model.BaseUpcomingService;
Expand All @@ -15,14 +16,20 @@
import org.smartregister.chw.dao.ChwChildDao;
import org.smartregister.chw.interactor.ChildUpcomingServiceInteractor;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

import timber.log.Timber;

public final class UpcomingServicesUtil {
static List<BaseUpcomingService> deepCopy(@Nullable List<BaseUpcomingService> serviceList) {
if (serviceList == null) return null;
Expand All @@ -32,7 +39,7 @@ static List<BaseUpcomingService> deepCopy(@Nullable List<BaseUpcomingService> se
for (BaseUpcomingService service : serviceList) {
BaseUpcomingService copy = new BaseUpcomingService();
copy.setServiceName(service.getServiceName());
copy.setServiceDate(service.getOverDueDate());
copy.setServiceDate(service.getServiceDate());
copy.setExpiryDate(service.getExpiryDate());
copy.setOverDueDate(service.getOverDueDate());

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

public static boolean hasUpcomingDueServices(MemberObject memberObject, Context ctx){
String childGender = ChwChildDao.getChildGender(memberObject.getBaseEntityId());
public static boolean showStatusForChild(MemberObject memberObject, final String childGender) {
int childAge = memberObject.getAge();
if (!ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()
&& childAge >= 2
&& !(childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11)){
return false;

return (ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus() && (childAge < 2 || (childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11))
|| !ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus());
}

static Integer getAgeInMonths(MemberObject memberObject) {
Date dob;
try {
dob = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(memberObject.getDob());
return Months.monthsBetween(new LocalDate(dob), new LocalDate()).getMonths();
} catch (ParseException e) {
Timber.e(e);
}
return null;
}

public static boolean hasUpcomingDueServices(MemberObject memberObject, Context ctx) {
Integer monthAge = getAgeInMonths(memberObject);
if (monthAge == null || monthAge >= ChwApplication.getApplicationFlavor().immunizationCeilingMonths(memberObject))
return false;

List<BaseUpcomingService> upcomingServices = new ChildUpcomingServiceInteractor().getUpcomingServices(memberObject, ctx);
return getDueServicesState(upcomingServices) != null;
}
Expand All @@ -88,7 +110,7 @@ public static void fetchUpcomingDueServicesState(MemberObject memberObject, Cont
int childAge = memberObject.getAge();
if (!ChwApplication.getApplicationFlavor().showChildrenAboveTwoDueStatus()
&& childAge >= 2
&& !(childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11)){
&& !(childGender.equalsIgnoreCase("Female") && childAge >= 9 && childAge <= 11)) {
String dueStatus = "";
onDueStatusFetched.accept(dueStatus);
return;
Expand All @@ -102,10 +124,10 @@ public void onDataFetched(List<BaseUpcomingService> serviceList) {
});
}

public static void fetchFamilyUpcomingDueServicesState(List<MemberObject> memberObjects, Context ctx, Consumer<Map<String, Integer> > onFamilyDueStatesConsumer){
public static void fetchFamilyUpcomingDueServicesState(List<MemberObject> memberObjects, Context ctx, Consumer<Map<String, Integer>> onFamilyDueStatesConsumer) {
Map<String, Integer> upcoming = new HashMap<>();
List<String> fetched = new ArrayList<>();
for (MemberObject member: memberObjects) {
for (MemberObject member : memberObjects) {
fetchUpcomingDueServicesState(member, ctx, new Consumer<String>() {
@Override
public void accept(String s) {
Expand All @@ -122,7 +144,7 @@ public Integer apply(String s) {
}
});
fetched.add(s);
if (fetched.size() >= memberObjects.size()){
if (fetched.size() >= memberObjects.size()) {
onFamilyDueStatesConsumer.accept(upcoming);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.mockito.Mockito;
import org.robolectric.util.ReflectionHelpers;
import org.smartregister.chw.BaseUnitTest;
import org.smartregister.chw.anc.domain.MemberObject;
import org.smartregister.immunization.ImmunizationLibrary;
import org.smartregister.reporting.ReportingLibrary;

Expand All @@ -29,4 +30,10 @@ public void testP2PClassifierIsInitialized() {
ReflectionHelpers.setField(application, "flavor", flv);
Assert.assertNotNull(application.getP2PClassifier());
}

@Test
public void testApplicationImmunizationCeiling(){
MemberObject memberObject = Mockito.mock(MemberObject.class);
Assert.assertEquals(24, ChwApplication.getApplicationFlavor().immunizationCeilingMonths(memberObject));
}
}
Loading

0 comments on commit 9c21f5a

Please sign in to comment.