• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpenSRP / opensrp-client-child / #797

pending completion
#797

Pull #330

github-actions

web-flow
Merge 30c622bb3 into c099d4f8b
Pull Request #330: Fix offline search results count

5228 of 9051 relevant lines covered (57.76%)

0.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.28
opensrp-child/src/main/java/org/smartregister/child/activity/BaseChildImmunizationActivity.java
1
package org.smartregister.child.activity;
2

3
import static org.smartregister.immunization.util.VaccinatorUtils.receivedVaccines;
4

5
import android.app.Activity;
6
import android.content.Context;
7
import android.content.DialogInterface;
8
import android.content.Intent;
9
import android.graphics.Color;
10
import android.graphics.drawable.ColorDrawable;
11
import android.os.AsyncTask;
12
import android.os.Bundle;
13
import android.os.Handler;
14
import android.os.Looper;
15
import android.text.TextUtils;
16
import android.view.View;
17
import android.view.ViewGroup;
18
import android.widget.ImageButton;
19
import android.widget.ImageView;
20
import android.widget.LinearLayout;
21
import android.widget.TextView;
22

23
import androidx.annotation.NonNull;
24
import androidx.annotation.VisibleForTesting;
25
import androidx.core.app.ActivityCompat;
26
import androidx.fragment.app.Fragment;
27
import androidx.fragment.app.FragmentTransaction;
28

29
import com.google.android.material.snackbar.Snackbar;
30
import com.google.gson.Gson;
31

32
import org.apache.commons.lang3.StringUtils;
33
import org.apache.commons.lang3.text.WordUtils;
34
import org.apache.commons.lang3.tuple.Triple;
35
import org.jetbrains.annotations.NotNull;
36
import org.joda.time.DateTime;
37
import org.json.JSONException;
38
import org.opensrp.api.constants.Gender;
39
import org.pcollections.TreePVector;
40
import org.smartregister.AllConstants;
41
import org.smartregister.child.ChildLibrary;
42
import org.smartregister.child.R;
43
import org.smartregister.child.contract.ChildImmunizationContract;
44
import org.smartregister.child.contract.IChildDetails;
45
import org.smartregister.child.contract.IGetSiblings;
46
import org.smartregister.child.domain.NamedObject;
47
import org.smartregister.child.domain.Observation;
48
import org.smartregister.child.domain.RegisterClickables;
49
import org.smartregister.child.event.ClientDirtyFlagEvent;
50
import org.smartregister.child.presenter.BaseChildImmunizationPresenter;
51
import org.smartregister.child.task.GetSiblingsTask;
52
import org.smartregister.child.task.SaveChildStatusTask;
53
import org.smartregister.child.task.ShowGrowthChartTask;
54
import org.smartregister.child.task.UndoVaccineTask;
55
import org.smartregister.child.toolbar.LocationSwitcherToolbar;
56
import org.smartregister.child.util.AsyncTaskUtils;
57
import org.smartregister.child.util.ChildAppProperties;
58
import org.smartregister.child.util.ChildDbUtils;
59
import org.smartregister.child.util.ChildJsonFormUtils;
60
import org.smartregister.child.util.Constants;
61
import org.smartregister.child.util.DBConstants;
62
import org.smartregister.child.util.Utils;
63
import org.smartregister.child.view.BCGNotificationDialog;
64
import org.smartregister.child.view.SiblingPicturesGroup;
65
import org.smartregister.clientandeventmodel.Event;
66
import org.smartregister.commonregistry.CommonPersonObjectClient;
67
import org.smartregister.domain.Alert;
68
import org.smartregister.domain.Photo;
69
import org.smartregister.domain.db.EventClient;
70
import org.smartregister.growthmonitoring.GrowthMonitoringLibrary;
71
import org.smartregister.growthmonitoring.domain.Height;
72
import org.smartregister.growthmonitoring.domain.HeightWrapper;
73
import org.smartregister.growthmonitoring.domain.Weight;
74
import org.smartregister.growthmonitoring.domain.WeightWrapper;
75
import org.smartregister.growthmonitoring.fragment.EditGrowthDialogFragment;
76
import org.smartregister.growthmonitoring.fragment.GrowthDialogFragment;
77
import org.smartregister.growthmonitoring.fragment.RecordGrowthDialogFragment;
78
import org.smartregister.growthmonitoring.listener.GrowthMonitoringActionListener;
79
import org.smartregister.growthmonitoring.repository.HeightRepository;
80
import org.smartregister.growthmonitoring.repository.WeightRepository;
81
import org.smartregister.immunization.ImmunizationLibrary;
82
import org.smartregister.immunization.db.VaccineRepo;
83
import org.smartregister.immunization.domain.ServiceRecord;
84
import org.smartregister.immunization.domain.ServiceSchedule;
85
import org.smartregister.immunization.domain.ServiceType;
86
import org.smartregister.immunization.domain.ServiceWrapper;
87
import org.smartregister.immunization.domain.Vaccine;
88
import org.smartregister.immunization.domain.VaccineSchedule;
89
import org.smartregister.immunization.domain.VaccineWrapper;
90
import org.smartregister.immunization.fragment.ActivateChildStatusDialogFragment;
91
import org.smartregister.immunization.fragment.ServiceDialogFragment;
92
import org.smartregister.immunization.fragment.UndoServiceDialogFragment;
93
import org.smartregister.immunization.fragment.UndoVaccinationDialogFragment;
94
import org.smartregister.immunization.fragment.VaccinationDialogFragment;
95
import org.smartregister.immunization.listener.ServiceActionListener;
96
import org.smartregister.immunization.listener.VaccinationActionListener;
97
import org.smartregister.immunization.repository.RecurringServiceRecordRepository;
98
import org.smartregister.immunization.repository.RecurringServiceTypeRepository;
99
import org.smartregister.immunization.repository.VaccineRepository;
100
import org.smartregister.immunization.service.intent.RecurringIntentService;
101
import org.smartregister.immunization.util.IMConstants;
102
import org.smartregister.immunization.util.ImageUtils;
103
import org.smartregister.immunization.util.RecurringServiceUtils;
104
import org.smartregister.immunization.util.VaccinateActionUtils;
105
import org.smartregister.immunization.util.VaccinatorUtils;
106
import org.smartregister.immunization.view.ServiceGroup;
107
import org.smartregister.immunization.view.VaccineGroup;
108
import org.smartregister.repository.AllSharedPreferences;
109
import org.smartregister.repository.BaseRepository;
110
import org.smartregister.service.AlertService;
111
import org.smartregister.util.DateUtil;
112
import org.smartregister.util.OpenSRPImageLoader;
113
import org.smartregister.view.activity.DrishtiApplication;
114
import org.smartregister.view.customcontrols.CustomFontTextView;
115

116
import java.io.Serializable;
117
import java.security.SecureRandom;
118
import java.text.SimpleDateFormat;
119
import java.util.ArrayList;
120
import java.util.Calendar;
121
import java.util.Collections;
122
import java.util.Date;
123
import java.util.HashMap;
124
import java.util.LinkedHashMap;
125
import java.util.List;
126
import java.util.Locale;
127
import java.util.Map;
128
import java.util.concurrent.TimeUnit;
129

130
import timber.log.Timber;
131

132
/**
133
 * Created by ndegwamartin on 06/03/2019.
134
 */
135
public abstract class BaseChildImmunizationActivity extends BaseChildActivity
1✔
136
        implements LocationSwitcherToolbar.OnLocationChangeListener, GrowthMonitoringActionListener,
137
        VaccinationActionListener, ServiceActionListener, View.OnClickListener, IChildDetails, ChildImmunizationContract.View, IGetSiblings {
138

139
    private final boolean recurringServiceEnabled = Boolean.parseBoolean(ChildLibrary.getInstance().getProperties()
1✔
140
            .getProperty(ChildAppProperties.KEY.FEATURE_RECURRING_SERVICE_ENABLED, "true"));
1✔
141
    public static final String DIALOG_TAG = "ChildImmunoActivity_DIALOG_TAG";
142
    private static final int RANDOM_MAX_RANGE = 4232;
143
    private static final int RANDOM_MIN_RANGE = 213;
144
    private static final int RECORD_WEIGHT_BUTTON_ACTIVE_MIN = 12;
145
    private static Boolean monitorGrowth = false;
1✔
146
    protected LinearLayout floatingActionButton;
147
    private ArrayList<VaccineGroup> vaccineGroups;
148
    private ArrayList<ServiceGroup> serviceGroups;
149
    private boolean bcgScarNotificationShown;
150
    private boolean weightNotificationShown;
151
    // Views
152
    private LocationSwitcherToolbar toolbar;
153
    // Data
154
    protected RegisterClickables registerClickables;
155
    private boolean dialogOpen = false;
1✔
156
    private boolean isGrowthEdit = false;
1✔
157
    private boolean isChildActive = false;
1✔
158
    private View recordGrowth;
159
    private TextView recordWeightText;
160
    private ImageView profileImageIV;
161
    private TextView childSiblingsTV;
162
    private ImageView recordWeightCheck;
163
    private TextView dobTV;
164
    private TextView ageTV;
165
    private TextView nameTV;
166
    private TextView childIdTV;
167
    private TextView systemOfRegistrationTV;
168
    private LinearLayout vaccineGroupCanvasLL;
169
    private LinearLayout profileNamelayout;
170
    private LinearLayout serviceGroupCanvasLL;
171
    private LinearLayout someLayout;
172
    private CustomFontTextView nextAppointmentDateView;
173
    private ImageButton growthChartButton;
174
    private SiblingPicturesGroup siblingPicturesGroup;
175
    private ChildImmunizationContract.Presenter presenter;
176

177
    @Override
178
    protected void onCreate(Bundle savedInstanceState) {
179
        super.onCreate(savedInstanceState);
1✔
180

181
        monitorGrowth = ChildLibrary.getInstance().getProperties().isTrue(org.smartregister.growthmonitoring.util.AppProperties.KEY.MONITOR_GROWTH);
1✔
182
        presenter = new BaseChildImmunizationPresenter(this);
1✔
183

184
        setUpToolbar();
1✔
185
        setUpViews();
1✔
186

187
        // Get child details from bundled data
188
        Bundle extras = this.getIntent().getExtras();
1✔
189
        String caseId = "";
1✔
190
        if (extras != null) {
1✔
191
            caseId = extras.getString(Constants.INTENT_KEY.BASE_ENTITY_ID);
1✔
192
            childDetails = getChildDetails(caseId);
1✔
193

194
            CommonPersonObjectClient cardChildDetails = null;
1✔
195
            if (extras.containsKey(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS) && childDetails == null) {
1✔
196
                cardChildDetails = (CommonPersonObjectClient) extras.get(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS);
×
197
            }
198

199
            if (childDetails == null) {
1✔
200
                childDetails = cardChildDetails;
×
201
            } else {
202
                if (cardChildDetails != null) {
1✔
203
                    // card last update
204
                    String cardTxDateTime = cardChildDetails.getColumnmaps().getOrDefault(Constants.KEY.NFC_LAST_PROCESSED_TIMESTAMP, "0");
×
205
                    long lastCardTxDateTime = Long.parseLong(cardTxDateTime != null ? cardTxDateTime : "0");
×
206
                    // device last update
207
                    String lastDeviceInteraction = childDetails.getColumnmaps().getOrDefault(Constants.KEY.LAST_INTERACTED_WITH, "0");
×
208
                    long lastInteractedWith = Long.parseLong(lastDeviceInteraction != null ? lastDeviceInteraction : "0");
×
209

210
                    if (lastCardTxDateTime > lastInteractedWith) {
×
211
                        childDetails = cardChildDetails;
×
212
                    }
213
                }
214
            }
215
        }
216

217
        Serializable serializable = extras.getSerializable(Constants.INTENT_KEY.EXTRA_REGISTER_CLICKABLES);
1✔
218
        if (serializable != null && serializable instanceof RegisterClickables) {
1✔
219
            registerClickables = (RegisterClickables) serializable;
1✔
220
        }
221

222
        bcgScarNotificationShown =
1✔
223
                ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.NOTIFICATIONS_BCG_ENABLED) &&
1✔
224
                        !ChildLibrary.getInstance().getProperties()
1✔
225
                                .getPropertyBoolean(ChildAppProperties.KEY.NOTIFICATIONS_BCG_ENABLED);
×
226
        weightNotificationShown = false;
1✔
227
//        ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED)
228
//                ? ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED)
229
//                : false;
230

231
        setLastModified(false);
1✔
232

233
        if (getChildDetails() == null) {
1✔
234
            Timber.e("Unable to fetch child details with case id: %s", caseId);
×
235
            Utils.showToast(this, getString(R.string.error_child_details));
×
236
            getActivity().finish();
×
237
            return;
×
238
        }
239
        setUpFloatingActionButton();
1✔
240
        Utils.refreshDataCaptureStrategyBanner(this, getOpenSRPContext().allSharedPreferences().fetchCurrentLocality());
1✔
241
    }
1✔
242

243
    @VisibleForTesting
244
    protected CommonPersonObjectClient getChildDetails(String caseId) {
245
        return ChildDbUtils.fetchCommonPersonObjectClientByBaseEntityId(caseId);
×
246
    }
247

248
    public static void launchActivity(Context fromContext, CommonPersonObjectClient childDetails,
249
                                      RegisterClickables registerClickables) {
250
        Intent intent = new Intent(fromContext, Utils.metadata().childImmunizationActivity);
1✔
251
        Bundle bundle = new Bundle();
1✔
252
        bundle.putSerializable(Constants.INTENT_KEY.BASE_ENTITY_ID, childDetails.getCaseId());
1✔
253
        bundle.putSerializable(Constants.INTENT_KEY.EXTRA_REGISTER_CLICKABLES, registerClickables);
1✔
254

255
        // load the child details
256
        if (ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.FEATURE_NFC_CARD_ENABLED) && (childDetails.getColumnmaps().containsKey(Constants.KEY.IS_CHILD_DATA_ON_DEVICE) && childDetails.getColumnmaps().get(Constants.KEY.IS_CHILD_DATA_ON_DEVICE).equalsIgnoreCase(Constants.FALSE))) {
1✔
257
            bundle.putSerializable(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS, childDetails);
×
258
        }
259

260
        bundle.putSerializable(Constants.INTENT_KEY.NEXT_APPOINTMENT_DATE,
1✔
261
                registerClickables != null && !TextUtils.isEmpty(registerClickables.getNextAppointmentDate()) ?
×
262
                        registerClickables.getNextAppointmentDate() : "");
1✔
263
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
1✔
264
        intent.putExtras(bundle);
1✔
265

266
        fromContext.startActivity(intent);
1✔
267
    }
1✔
268

269
    public static Object clone(@NonNull Object object) {
270

271
        Gson gson = new Gson();
×
272
        String serializedObject = gson.toJson(object);
×
273

274
        return gson.fromJson(serializedObject, object.getClass());
×
275
    }
276

277
    private void setUpViews() {
278
        recordGrowth = findViewById(R.id.record_growth);
1✔
279
        recordWeightText = findViewById(R.id.record_growth_text);
1✔
280
        profileNamelayout = findViewById(R.id.profile_name_layout);
1✔
281
        childSiblingsTV = findViewById(R.id.child_siblings_tv);
1✔
282
        recordWeightCheck = findViewById(R.id.record_growth_check);
1✔
283
        dobTV = findViewById(R.id.dob_tv);
1✔
284
        ageTV = findViewById(R.id.age_tv);
1✔
285
        vaccineGroupCanvasLL = findViewById(R.id.vaccine_group_canvas_ll);
1✔
286
        serviceGroupCanvasLL = findViewById(R.id.service_group_canvas_ll);
1✔
287
        profileImageIV = findViewById(R.id.profile_image_iv);
1✔
288
        nameTV = findViewById(R.id.name_tv);
1✔
289
        childIdTV = findViewById(R.id.child_id_tv);
1✔
290
        systemOfRegistrationTV = findViewById(R.id.system_of_registration);
1✔
291
        floatingActionButton = findViewById(R.id.fab);
1✔
292
        someLayout = findViewById(R.id.content_base_inner);
1✔
293
        nextAppointmentDateView = findViewById(R.id.next_appointment_date);
1✔
294
        growthChartButton = findViewById(R.id.growth_chart_button);
1✔
295
        siblingPicturesGroup = findViewById(R.id.sibling_pictures);
1✔
296
    }
1✔
297

298
    private void setUpToolbar() {
299
        if (getSupportActionBar() != null) {
1✔
300
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
1✔
301
        }
302

303
        toolbar = (LocationSwitcherToolbar) getToolbar();
1✔
304
        toolbar.setNavigationOnClickListener(v -> goToRegisterPage());
1✔
305
        toolbar.setOnLocationChangeListener(this);
1✔
306
        toolbar.init(this);
1✔
307
    }
1✔
308

309
    private void setUpFloatingActionButton() {
310

311
        if (ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.FEATURE_NFC_CARD_ENABLED)) {
1✔
312

313
            floatingActionButton.setOnClickListener(this);
1✔
314

315
            configureFloatingActionBackground(getGenderButtonColor(childDetails.getColumnmaps().get(Constants.KEY.GENDER)),
1✔
316
                    null);
317

318
            someLayout.setPadding(someLayout.getPaddingLeft(), someLayout.getPaddingTop(), someLayout.getPaddingRight(),
1✔
319
                    someLayout.getPaddingBottom() + 80);
1✔
320
        }
321
    }
1✔
322

323
    public LinearLayout getServiceGroupCanvasLL() {
324
        return serviceGroupCanvasLL;
×
325
    }
326

327

328
    protected abstract void goToRegisterPage();
329

330
    protected void configureFloatingActionBackground(Integer drawableResourceId, String title) {
331
        TextView fabText = ((TextView) floatingActionButton.findViewById(R.id.fab_text));
1✔
332
        ImageView fabImage = ((ImageView) floatingActionButton.findViewById(R.id.fab_image));
1✔
333
        if (drawableResourceId != null) {
1✔
334
            int paddingLeft = floatingActionButton.getPaddingLeft();
1✔
335
            int paddingRight = floatingActionButton.getPaddingRight();
1✔
336
            int paddingTop = floatingActionButton.getPaddingTop();
1✔
337
            int paddingBottom = floatingActionButton.getPaddingBottom();
1✔
338

339
            if (isActiveStatus(childDetails)) {
1✔
340
                floatingActionButton.setClickable(true);
1✔
341
                floatingActionButton.setBackgroundResource(drawableResourceId);
1✔
342
                fabText.setTextColor(Color.WHITE);
1✔
343
                fabImage.setColorFilter(Color.WHITE);
1✔
344
            } else {
345
                floatingActionButton.setClickable(false);
1✔
346
                floatingActionButton.setBackgroundResource(R.drawable.light_grey_background);
1✔
347
                fabText.setTextColor(R.color.silver);
1✔
348
                fabImage.setColorFilter(ActivityCompat.getColor(this, R.color.silver));
1✔
349
            }
350
            floatingActionButton.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
1✔
351
        }
352

353
        if (title != null) {
1✔
354
            fabText.setText(title);
1✔
355
        }
356

357
        floatingActionButton.setVisibility(View.VISIBLE);
1✔
358
    }
1✔
359

360
    protected int getGenderButtonColor(String gender) {
361
        int imageResource = R.drawable.pill_background_gender_neutral_green;
1✔
362
        if (StringUtils.isNotBlank(gender)) {
1✔
363
            switch (gender.toLowerCase()) {
1✔
364
                case Constants.GENDER.MALE:
365
                    imageResource = R.drawable.pill_background_male_blue;
1✔
366
                    break;
1✔
367
                case Constants.GENDER.FEMALE:
368
                    imageResource = R.drawable.pill_background_female_pink;
1✔
369
                    break;
1✔
370
                default:
371
                    imageResource = R.drawable.pill_background_gender_neutral_green;
1✔
372
                    break;
373
            }
374
        }
375

376
        return imageResource;
1✔
377
    }
378

379
    @Override
380
    protected int getContentView() {
381
        return R.layout.activity_child_immunization;
1✔
382
    }
383

384
    @Override
385
    protected int getToolbarId() {
386
        return LocationSwitcherToolbar.TOOLBAR_ID;
1✔
387
    }
388

389
    @Override
390
    protected abstract int getDrawerLayoutId();//Navigation drawer ID ?
391

392
    @Override
393
    protected int[] updateGenderViews(Gender gender) {
394
        int[] selectedColor = super.updateGenderViews(gender);
1✔
395

396
        String identifier = getString(R.string.neutral_sex_id);
1✔
397
        int toolbarResource = R.drawable.vertical_separator_neutral;
1✔
398
        if (gender.equals(Gender.FEMALE)) {
1✔
399
            toolbarResource = R.drawable.vertical_separator_female;
×
400
            identifier = getString(R.string.female_sex_id);
×
401
        } else if (gender.equals(Gender.MALE)) {
1✔
402
            toolbarResource = R.drawable.vertical_separator_male;
1✔
403
            identifier = getString(R.string.male_sex_id);
1✔
404
        }
405

406
        if (Locale.getDefault().toString().equalsIgnoreCase("ar") || Locale.getDefault().toString().equalsIgnoreCase("fr")) {
1✔
407
            identifier = "";
×
408
        }
409
        toolbar.updateSeparatorView(toolbarResource);
1✔
410
        childSiblingsTV.setText(String.format(getString(R.string.child_siblings), identifier).toUpperCase());
1✔
411

412
        updateProfilePicture(gender);
1✔
413
        return selectedColor;
1✔
414
    }
415

416
    @Override
417
    protected void onResume() {
418
        super.onResume();
×
419
        if (vaccineGroups != null) {
×
420
            vaccineGroupCanvasLL.removeAllViews();
×
421
            vaccineGroups = null;
×
422
        }
423

424
        if (serviceGroups != null) {
×
425
            serviceGroupCanvasLL.removeAllViews();
×
426
            serviceGroups = null;
×
427
        }
428

429
        updateViews();
×
430

431
        if (!recurringServiceEnabled) {
×
432
            getServiceGroupCanvasLL().setVisibility(View.GONE);
×
433
        }
434
    }
×
435

436
    @Override
437
    public void setChildDetails(Map<String, String> detailsMap) {
438
        childDetails.setColumnmaps(detailsMap);
×
439
        childDetails.setDetails(detailsMap);
×
440
    }
×
441

442
    @VisibleForTesting
443
    @Override
444
    protected boolean isActiveStatus(CommonPersonObjectClient child) {
445
        return super.isActiveStatus(child);
1✔
446
    }
447

448
    @VisibleForTesting
449
    @Override
450
    protected String getHumanFriendlyChildsStatus(CommonPersonObjectClient child) {
451
        return super.getHumanFriendlyChildsStatus(child);
1✔
452
    }
453

454
    @Override
455
    public void updateViews() {
456
        profileNamelayout.setOnClickListener(v -> launchDetailActivity(getActivity(), childDetails, null));
1✔
457

458
        if (ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.FEATURE_NFC_CARD_ENABLED) && (!childDetails.getColumnmaps().containsKey(Constants.KEY.IS_CHILD_DATA_ON_DEVICE) || childDetails.getColumnmaps().get(Constants.KEY.IS_CHILD_DATA_ON_DEVICE).equalsIgnoreCase(AllConstants.TRUE))) {
1✔
459
            CommonPersonObjectClient objectClient = ChildDbUtils.fetchCommonPersonObjectClientByBaseEntityId(childDetails.getColumnmaps().get(DBConstants.KEY.BASE_ENTITY_ID));
×
460
            if (objectClient != null) {
×
461
                childDetails = objectClient;
×
462
            } else {
463
                Timber.e("fetchCommonPersonObjectClientByBaseEntityId is null, child record is not n the database.");
×
464
            }
465
        }
466

467
        isChildActive = isActiveStatus(childDetails);
1✔
468

469
        showChildsStatus(childDetails);
1✔
470

471
        updateGenderViews();
1✔
472

473
        toolbar.setTitle(getActivityTitle());
1✔
474
        ((TextView) toolbar.findViewById(R.id.title)).setText(getActivityTitle());//Called differently Fixes weird bug
1✔
475

476
        updateAgeViews();
1✔
477
        updateSystemOfRegistration();
1✔
478
        updateChildIdViews();
1✔
479
        updateNextAppointmentDateView();
1✔
480

481
        startUpdateViewTask();
1✔
482
        updateFloatingActionButtonBasedOnChildStatus();
1✔
483
    }
1✔
484

485
    @VisibleForTesting
486
    protected void startUpdateViewTask() {
487
        AlertService alertService = getOpenSRPContext().alertService();
1✔
488

489
        UpdateViewTask updateViewTask = new UpdateViewTask();
1✔
490
        updateViewTask.setWeightRepository(GrowthMonitoringLibrary.getInstance().weightRepository());
1✔
491
        if (monitorGrowth) {
1✔
492
            updateViewTask.setHeightRepository(GrowthMonitoringLibrary.getInstance().heightRepository());
×
493
        }
494
        updateViewTask.setVaccineRepository(ImmunizationLibrary.getInstance().vaccineRepository());
1✔
495

496
        if (recurringServiceEnabled) {
1✔
497
            updateViewTask.setRecurringServiceTypeRepository(ImmunizationLibrary.getInstance().recurringServiceTypeRepository());
×
498
            updateViewTask.setRecurringServiceRecordRepository(ImmunizationLibrary.getInstance().recurringServiceRecordRepository());
×
499
        }
500

501
        updateViewTask.setAlertService(alertService);
1✔
502
        Utils.startAsyncTask(updateViewTask, null);
1✔
503
    }
1✔
504

505
    public abstract void launchDetailActivity(Context fromContext, CommonPersonObjectClient childDetails,
506
                                              RegisterClickables registerClickables);
507

508
    protected abstract Activity getActivity();
509

510
    private void showChildsStatus(CommonPersonObjectClient child) {
511
        String status = getHumanFriendlyChildsStatus(child);
1✔
512
        showChildsStatus(status);
1✔
513
    }
1✔
514

515
    private void updateGenderViews() {
516
        Gender gender = isDataOk() ? Utils.getGenderEnum(childDetails.getColumnmaps()) : Gender.UNKNOWN;
1✔
517

518
        int[] colors = updateGenderViews(gender);
1✔
519
        int normalShade = colors[1];
1✔
520
        findViewById(R.id.advanced_data_capture_strategy_wrapper).setBackground(new ColorDrawable(getResources().getColor(normalShade)));
1✔
521
    }
1✔
522

523
    private void updateAgeViews() {
524
        String dobString;
525
        String formattedAge = "";
1✔
526
        String formattedDob = "";
1✔
527
        if (isDataOk()) {
1✔
528
            dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
1✔
529
            Date dob = Utils.dobStringToDate(dobString);
1✔
530
            if (dob != null) {
1✔
531
                formattedDob = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH).format(dob);
1✔
532
                long timeDiff = Calendar.getInstance().getTimeInMillis() - dob.getTime();
1✔
533

534
                if (timeDiff >= 0) {
1✔
535
                    formattedAge = DateUtil.getDuration(timeDiff, Locale.ENGLISH);
1✔
536
                } else {
537
                    formattedAge = DateUtil.getDuration(0, Locale.ENGLISH);
×
538
                }
539
            }
540
        }
541

542
        dobTV.setText(String.format("%s: %s", getString(R.string.birthdate), formattedDob));
1✔
543
        ageTV.setText(String.format("%s: %s", getString(R.string.age), formattedAge));
1✔
544
    }
1✔
545

546
    protected void updateChildIdViews() {
547
        String name = "";
1✔
548
        String childId = "";
1✔
549
        if (isDataOk()) {
1✔
550
            name = constructChildName();
1✔
551
            childId = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.ZEIR_ID, false);
1✔
552

553
            boolean showOutOfCatchmentText = ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.NOVEL.OUT_OF_CATCHMENT)
1✔
554
                    && Boolean.parseBoolean(org.smartregister.util.Utils.getValue(childDetails.getColumnmaps(), Constants.Client.IS_OUT_OF_CATCHMENT, false));
1✔
555
            findViewById(R.id.outOfCatchment).setVisibility(showOutOfCatchmentText ? View.VISIBLE : View.GONE);
1✔
556

557
            nameTV.setText(name);
1✔
558
            childIdTV.setText(getString(R.string.format_label_colon_text, getString(R.string.label_zeir), Utils.formatIdentifiers(childId)));
1✔
559
        }
560

561
        Utils.startAsyncTask(new GetSiblingsTask(childDetails, this), null);
1✔
562
    }
1✔
563

564
    private void updateSystemOfRegistration() {
565
        String systemOfRegistration = org.smartregister.util.Utils.getValue(childDetails.getColumnmaps(), Constants.Client.SYSTEM_OF_REGISTRATION, false);
1✔
566
        systemOfRegistrationTV.setText(systemOfRegistration != null ? systemOfRegistration : "");
1✔
567
    }
1✔
568

569
    private void updateNextAppointmentDateView() {
570
        if (registerClickables != null && !TextUtils.isEmpty(registerClickables.getNextAppointmentDate())) {
1✔
571
            ((View) nextAppointmentDateView.getParent()).setVisibility(View.VISIBLE);
×
572
            nextAppointmentDateView.setText(registerClickables.getNextAppointmentDate());
×
573
        } else {
574
            ((View) nextAppointmentDateView.getParent()).setVisibility(View.GONE);
1✔
575
        }
576
    }
1✔
577

578
    private void updateProfilePicture(Gender gender) {
579
        if (isDataOk() && childDetails.entityId() != null) { //image already in local storage most likey ):
1✔
580
            //set profile image by passing the client id.If the image doesn't exist in the image repository then
581
            // download and save locally
582
            profileImageIV.setTag(R.id.entity_id, childDetails.entityId());
1✔
583
            DrishtiApplication.getCachedImageLoaderInstance().getImageByClientId(childDetails.entityId(),
1✔
584
                    OpenSRPImageLoader
585
                            .getStaticImageListener(profileImageIV, ImageUtils.profileImageResourceByGender(gender),
1✔
586
                                    ImageUtils.profileImageResourceByGender(gender)));
1✔
587

588
        }
589
    }
1✔
590

591
    @Override
592
    protected Class onBackActivity() {
593
        return BaseChildRegisterActivity.class;
1✔
594
    }
595

596
    @Override
597
    protected void onSaveInstanceState(Bundle outState) {
598
        super.onSaveInstanceState(outState);
×
599
        outState.putSerializable(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS, childDetails);
×
600
    }
×
601

602
    @Override
603
    protected void onRestoreInstanceState(@NotNull Bundle savedInstanceState) {
604
        super.onRestoreInstanceState(savedInstanceState);
×
605

606
        Serializable serializable = savedInstanceState.getSerializable(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS);
×
607
        if (serializable instanceof CommonPersonObjectClient) {
×
608
            childDetails = (CommonPersonObjectClient) serializable;
×
609
        }
610
    }
×
611

612
    @Override
613
    public void finish() {
614
        if (isLastModified()) {
1✔
615
            Utils.updateLastInteractionWith(childDetails.entityId(), Utils.metadata().getRegisterQueryProvider().getDemographicTable());
×
616
        }
617
        super.finish();
1✔
618
    }
1✔
619

620
    @Override
621
    public void onSiblingsFetched(List<String> ids) {
622
        siblingPicturesGroup.setSiblingBaseEntityIds((BaseActivity) getActivity(), ids);
1✔
623
    }
1✔
624

625
    public abstract boolean isLastModified();
626

627
    public abstract void setLastModified(boolean lastModified);
628

629
    private void updateServiceViews(Map<String, List<ServiceType>> serviceTypeMap, List<ServiceRecord> serviceRecordList,
630
                                    List<Alert> alerts) {
631
        Map<String, List<ServiceType>> foundServiceTypeMap = new LinkedHashMap<>();
×
632
        if (serviceGroups == null) {
×
633
            for (String type : serviceTypeMap.keySet()) {
×
634
                if (foundServiceTypeMap.containsKey(type)) {
×
635
                    continue;
×
636
                }
637

638
                getServiceTypes(serviceTypeMap, serviceRecordList, foundServiceTypeMap, type);
×
639

640
                if (foundServiceTypeMap.containsKey(type)) {
×
641
                    continue;
×
642
                }
643

644
                getAlerts(serviceTypeMap, alerts, foundServiceTypeMap, type);
×
645
            }
×
646

647
            if (foundServiceTypeMap.isEmpty()) {
×
648
                return;
×
649
            }
650

651
            serviceGroups = new ArrayList<>();
×
652
            createServiceGroupCanvas(serviceRecordList, alerts, foundServiceTypeMap);
×
653
        } else {
654
            for (ServiceGroup serviceGroup : serviceGroups) {
×
655
                try {
656
                    serviceGroup.setChildActive(isChildActive);
×
657
                    serviceGroup.updateChildsActiveStatus();
×
658
                } catch (Exception e) {
×
659
                    Timber.e(e);
×
660
                }
×
661
            }
×
662
        }
663

664
    }
×
665

666
    private void getServiceTypes(Map<String, List<ServiceType>> serviceTypeMap, List<ServiceRecord> serviceRecordList, Map<String, List<ServiceType>> foundServiceTypeMap, String type) {
667
        for (ServiceRecord serviceRecord : serviceRecordList) {
×
668
            if (serviceRecord.getSyncStatus().equals(RecurringServiceTypeRepository.TYPE_Unsynced) &&
×
669
                    serviceRecord.getType().equals(type)) {
×
670
                foundServiceTypeMap.put(type, serviceTypeMap.get(type));
×
671
                break;
×
672
            }
673
        }
×
674
    }
×
675

676
    private void getAlerts(Map<String, List<ServiceType>> serviceTypeMap, List<Alert> alerts, Map<String, List<ServiceType>> foundServiceTypeMap, String type) {
677
        for (Alert alert : alerts) {
×
678
            if (StringUtils.containsIgnoreCase(alert.scheduleName(), type) ||
×
679
                    StringUtils.containsIgnoreCase(alert.visitCode(), type)) {
×
680
                foundServiceTypeMap.put(type, serviceTypeMap.get(type));
×
681
                break;
×
682
            }
683
        }
×
684
    }
×
685

686
    private void createServiceGroupCanvas(List<ServiceRecord> serviceRecordList, List<Alert> alerts, Map<String, List<ServiceType>> foundServiceTypeMap) {
687
        ServiceGroup curGroup = new ServiceGroup(this);
×
688
        curGroup.setChildActive(isChildActive);
×
689
        curGroup.setData(childDetails, foundServiceTypeMap, serviceRecordList, alerts);
×
690
        serviceOnClickListener(curGroup);
×
691
        undoServiceOnClickListener(curGroup);
×
692
        serviceGroupCanvasLL.addView(curGroup);
×
693
        serviceGroups.add(curGroup);
×
694
    }
×
695

696
    private void undoServiceOnClickListener(ServiceGroup curGroup) {
697
        curGroup.setOnServiceUndoClickListener((serviceGroup, serviceWrapper) -> {
×
698
            if (dialogOpen) {
×
699
                return;
×
700
            }
701

702
            dialogOpen = true;
×
703
            if (isChildActive) {
×
704
                addServiceUndoDialogFragment(serviceGroup, serviceWrapper);
×
705
            } else {
706
                showActivateChildStatusDialogBox();
×
707
            }
708
        });
×
709
    }
×
710

711
    private void serviceOnClickListener(ServiceGroup curGroup) {
712
        curGroup.setOnServiceClickedListener((serviceGroup, serviceWrapper) -> {
×
713
            if (dialogOpen) {
×
714
                return;
×
715
            }
716

717
            dialogOpen = true;
×
718
            if (isChildActive) {
×
719
                addServiceDialogFragment(serviceWrapper, serviceGroup);
×
720
            } else {
721
                showActivateChildStatusDialogBox();
×
722
            }
723
        });
×
724
    }
×
725

726
    private void addServiceDialogFragment(ServiceWrapper serviceWrapper, ServiceGroup serviceGroup) {
727
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
×
728
        Fragment prev = this.getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
729
        if (prev != null) {
×
730
            return;
×
731
        }
732
        ft.addToBackStack(null);
×
733

734
        serviceGroup.setModalOpen(true);
×
735

736
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
737
        DateTime dob = Utils.dobStringToDateTime(dobString);
×
738
        if (dob == null) {
×
739
            dob = DateTime.now();
×
740
        }
741

742
        List<ServiceRecord> serviceRecordList =
743
                ImmunizationLibrary.getInstance().recurringServiceRecordRepository().findByEntityId(childDetails.entityId());
×
744
        if (serviceRecordList == null) {
×
745
            serviceRecordList = new ArrayList<>();
×
746
        }
747

748
        ServiceDialogFragment serviceDialogFragment =
×
749
                ServiceDialogFragment.newInstance(dob, serviceRecordList, serviceWrapper, true);
×
750
        serviceDialogFragment.show(ft, DIALOG_TAG);
×
751
        serviceDialogFragment.setOnDismissListener(dialog -> dialogOpen = false);
×
752
    }
×
753

754
    private void showActivateChildStatusDialogBox() {
755
        String thirdPersonPronoun = getChildsThirdPersonPronoun(childDetails);
×
756
        String childCurrentStatus = WordUtils.uncapitalize(getHumanFriendlyChildsStatus(childDetails), '-', ' ');
×
757
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
×
758
        Fragment prev = this.getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
759
        if (prev != null) {
×
760
            return;
×
761
        }
762
        ft.addToBackStack(null);
×
763

764
        final ActivateChildStatusDialogFragment activateChildStatusFragmentDialog = ActivateChildStatusDialogFragment.newInstance(thirdPersonPronoun, childCurrentStatus, R.style.PathAlertDialog);
×
765
        activateChildStatusFragmentDialog.setOnClickListener((dialog, which) -> {
×
766
            if (which == DialogInterface.BUTTON_POSITIVE) {
×
767
                String columnName = Constants.CHILD_STATUS.INACTIVE;
×
768
                if (Constants.BOOLEAN_STRING.TRUE.equals(getChildDetails().getDetails().getOrDefault(Constants.CHILD_STATUS.INACTIVE, Constants.FALSE))) {
×
769
                    columnName = Constants.CHILD_STATUS.INACTIVE;
×
770
                } else if (Constants.BOOLEAN_STRING.TRUE.equals(getChildDetails().getDetails().getOrDefault(Constants.CHILD_STATUS.LOST_TO_FOLLOW_UP, Constants.FALSE))) {
×
771
                    columnName = Constants.CHILD_STATUS.LOST_TO_FOLLOW_UP;
×
772
                }
773

774
                ChildDbUtils.updateChildDetailsValue(columnName, Constants.FALSE, childDetails.entityId());
×
775
                getChildDetails().getDetails().put(columnName, Constants.FALSE);
×
776
                SaveChildStatusTask saveChildStatusTask = new SaveChildStatusTask(getActivity(), presenter);
×
777
                Utils.startAsyncTask(saveChildStatusTask, null);
×
778
            }
779
        });
×
780
        activateChildStatusFragmentDialog.setOnDismissListener(dialog -> dialogOpen = false);
×
781
        activateChildStatusFragmentDialog.show(ft, DIALOG_TAG);
×
782
    }
×
783

784
    private void addServiceUndoDialogFragment(ServiceGroup serviceGroup, ServiceWrapper serviceWrapper) {
785
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
×
786
        Fragment prev = getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
787
        if (prev != null) {
×
788
            return;
×
789
        }
790
        ft.addToBackStack(null);
×
791

792
        serviceGroup.setModalOpen(true);
×
793

794
        UndoServiceDialogFragment undoServiceDialogFragment = UndoServiceDialogFragment.newInstance(serviceWrapper);
×
795
        undoServiceDialogFragment.show(ft, DIALOG_TAG);
×
796
        undoServiceDialogFragment.setOnDismissListener(dialog -> dialogOpen = false);
×
797
    }
×
798

799
    private String getChildsThirdPersonPronoun(CommonPersonObjectClient childDetails) {
800
        String genderString = Utils.getValue(childDetails, AllConstants.ChildRegistrationFields.GENDER, false);
1✔
801
        if (Constants.GENDER.FEMALE.equalsIgnoreCase(genderString)) {
1✔
802
            return getString(R.string.her);
1✔
803
        } else if (Constants.GENDER.MALE.equalsIgnoreCase(genderString)) {
1✔
804
            return getString(R.string.him);
1✔
805
        }
806

807
        return getString(R.string.her) + "/" + getString(R.string.him);
×
808
    }
809

810
    private void updateVaccinationViews(List<Vaccine> vaccineList, List<Alert> alerts) {
811

812
        if (vaccineGroups == null) {
×
813

814
            final String BCG_NAME = "BCG";
×
815
            final String BCG2_NAME = "BCG 2";
×
816
            final String BCG_NO_SCAR_NAME = "BCG: no scar";
×
817
            final String BCG_SCAR_NAME = "BCG: scar";
×
818
            final String VACCINE_GROUP_BIRTH_NAME = "Birth";
×
819
            final int BIRTH_VACCINE_GROUP_INDEX = 0;
×
820
            List<org.smartregister.immunization.domain.jsonmapping.VaccineGroup> compiledVaccineGroups;
821

822
            vaccineGroups = new ArrayList<>();
×
823
            List<org.smartregister.immunization.domain.jsonmapping.VaccineGroup> supportedVaccines =
×
824
                    VaccinatorUtils.getSupportedVaccines(this);
×
825

826
            boolean showBcg2Reminder = ((childDetails.getColumnmaps().containsKey(Constants.SHOW_BCG2_REMINDER)) &&
×
827
                    (childDetails.getColumnmaps().get(Constants.SHOW_BCG2_REMINDER) != null) &&
×
828
                    Boolean.parseBoolean(childDetails.getColumnmaps().get(Constants.SHOW_BCG2_REMINDER)));
×
829
            boolean showBcgScar = (childDetails.getColumnmaps().containsKey(Constants.SHOW_BCG_SCAR)) && (childDetails.getColumnmaps().get(Constants.SHOW_BCG_SCAR) != null);
×
830

831
            org.smartregister.immunization.domain.jsonmapping.VaccineGroup birthVaccineGroup =
×
832
                    (org.smartregister.immunization.domain.jsonmapping.VaccineGroup) clone(
×
833
                            getVaccineGroupByName(supportedVaccines, VACCINE_GROUP_BIRTH_NAME));
×
834

835
            if (showBcg2Reminder) {
×
836

837
                compiledVaccineGroups = TreePVector.from(supportedVaccines).minus(BIRTH_VACCINE_GROUP_INDEX)
×
838
                        .plus(BIRTH_VACCINE_GROUP_INDEX, birthVaccineGroup);
×
839

840
                updateVaccineName(getVaccineByName(birthVaccineGroup.vaccines, BCG_NAME), BCG_NO_SCAR_NAME);
×
841

842
                List<org.smartregister.immunization.domain.jsonmapping.Vaccine> specialVaccines =
×
843
                        VaccinatorUtils.getJsonVaccineGroup(VaccinatorUtils.special_vaccines_file);
×
844
                if (specialVaccines != null && !specialVaccines.isEmpty()) {
×
845
                    for (org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine : specialVaccines) {
×
846
                        if (vaccine.name.contains(BCG_NAME) && BCG_NAME.equals(vaccine.type)) {
×
847
                            vaccine.name = BCG2_NAME;
×
848
                            birthVaccineGroup.vaccines.add(vaccine);
×
849
                            break;
×
850
                        }
851
                    }
×
852

853
                }
854
            } else if (showBcgScar) {
×
855

856
                compiledVaccineGroups = TreePVector.from(supportedVaccines).minus(BIRTH_VACCINE_GROUP_INDEX)
×
857
                        .plus(BIRTH_VACCINE_GROUP_INDEX, birthVaccineGroup);
×
858

859
                final long DATE = Long.parseLong(childDetails.getColumnmaps().get(Constants.SHOW_BCG_SCAR));
×
860

861
                List<org.smartregister.immunization.domain.jsonmapping.Vaccine> specialVaccines =
×
862
                        VaccinatorUtils.getJsonVaccineGroup(VaccinatorUtils.special_vaccines_file);
×
863
                if (specialVaccines != null && !specialVaccines.isEmpty()) {
×
864
                    for (org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine : specialVaccines) {
×
865
                        if (vaccine.name.contains(BCG_NAME) && BCG_NAME.equals(vaccine.type)) {
×
866
                            vaccine.name = BCG_SCAR_NAME;
×
867
                            birthVaccineGroup.vaccines.add(vaccine);
×
868
                            vaccineList.add(createBcg2Vaccine(new Date(DATE), VaccineRepository.TYPE_Synced));
×
869
                            break;
×
870
                        }
871
                    }
×
872

873
                }
874
            } else {
×
875
                compiledVaccineGroups = supportedVaccines;
×
876
            }
877

878
            for (org.smartregister.immunization.domain.jsonmapping.VaccineGroup vaccineGroup : compiledVaccineGroups) {
×
879
                try {
880
                    addVaccineGroup(-1, vaccineGroup, vaccineList, alerts);
×
881
                } catch (Exception e) {
×
882
                    Timber.e(e);
×
883
                }
×
884
            }
×
885
        } else {
×
886
            for (VaccineGroup vaccineGroup : vaccineGroups) {
×
887
                try {
888
                    vaccineGroup.setChildActive(isChildActive);
×
889
                    vaccineGroup.updateChildsActiveStatus();
×
890
                } catch (Exception e) {
×
891
                    Timber.e(e);
×
892
                }
×
893
            }
×
894
        }
895

896
        showVaccineNotifications(vaccineList, alerts);
×
897
    }
×
898

899
    public org.smartregister.immunization.domain.jsonmapping.VaccineGroup getVaccineGroupByName(
900
            @NonNull List<org.smartregister.immunization.domain.jsonmapping.VaccineGroup> vaccineGroupList,
901
            @NonNull String name) {
902

903
        for (org.smartregister.immunization.domain.jsonmapping.VaccineGroup vaccineGroup : vaccineGroupList) {
1✔
904
            if (vaccineGroup.id.equals(name)) return vaccineGroup;
1✔
905
        }
×
906
        return null;
×
907
    }
908

909
    public void updateVaccineName(org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine,
910
                                  @NonNull String newName) {
911

912
        if (vaccine != null) vaccine.name = newName;
×
913
    }
×
914

915
    public org.smartregister.immunization.domain.jsonmapping.Vaccine getVaccineByName(
916
            @NonNull List<org.smartregister.immunization.domain.jsonmapping.Vaccine> vaccineList, @NonNull String name) {
917

918
        for (org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine : vaccineList) {
1✔
919
            if (vaccine.name.equals(name)) return vaccine;
1✔
920
        }
×
921
        return null;
×
922
    }
923

924
    protected Vaccine createBcg2Vaccine(Date date, String syncStatus) {
925
        AllSharedPreferences allSharedPreferences = getOpenSRPContext().allSharedPreferences();
1✔
926
        String provider = allSharedPreferences.fetchRegisteredANM();
1✔
927
        Vaccine vaccine = new Vaccine();
1✔
928
        vaccine.setId(-1L);
1✔
929
        vaccine.setBaseEntityId(childDetails.entityId());
1✔
930
        vaccine.setName(Constants.KEY.BCG_SCAR);
1✔
931
        vaccine.setDate(date);
1✔
932
        vaccine.setTeam(allSharedPreferences.fetchDefaultTeam(provider));
1✔
933
        vaccine.setTeamId(allSharedPreferences.fetchDefaultTeamId(provider));
1✔
934
        vaccine.setAnmId(provider);
1✔
935
        vaccine.setLocationId(ChildJsonFormUtils.getProviderLocationId(this));
1✔
936
        vaccine.setSyncStatus(syncStatus);
1✔
937
        vaccine.setFormSubmissionId(ChildJsonFormUtils.generateRandomUUIDString());
1✔
938
        vaccine.setUpdatedAt(new Date().getTime());
1✔
939

940
        String lastChar = vaccine.getName().substring(vaccine.getName().length() - 1);
1✔
941
        if (StringUtils.isNumeric(lastChar)) {
1✔
942
            vaccine.setCalculation(Integer.valueOf(lastChar));
×
943
        } else {
944
            vaccine.setCalculation(-1);
1✔
945
        }
946
        String outOfCatchment = isDataOk() && childDetails.getColumnmaps() != null && childDetails.getColumnmaps().containsKey(Constants.Client.IS_OUT_OF_CATCHMENT) ? Utils.getValue(childDetails.getColumnmaps(), Constants.Client.IS_OUT_OF_CATCHMENT, false) : "false";
1✔
947
        vaccine.setOutOfCatchment(Constants.BOOLEAN_STRING.TRUE.equals(outOfCatchment) ? 1 : 0);
1✔
948
        return vaccine;
1✔
949
    }
950

951
    private void addVaccineGroup(int canvasId,
952
                                 org.smartregister.immunization.domain.jsonmapping.VaccineGroup vaccineGroupData,
953
                                 List<Vaccine> vaccineList, List<Alert> alerts) {
954
        VaccineGroup curGroup = new VaccineGroup(this);
×
955
        curGroup.setChildActive(isChildActive);
×
956
        curGroup.setData(vaccineGroupData, childDetails, vaccineList, alerts, Constants.KEY.CHILD);
×
957
        curGroup.setOnRecordAllClickListener((vaccineGroup, dueVaccines) -> {
×
958
            if (dialogOpen) {
×
959
                return;
×
960
            }
961

962
            dialogOpen = true;
×
963
            if (isChildActive) {
×
964
                addVaccinationDialogFragment(dueVaccines, vaccineGroup);
×
965
            } else {
966
                showActivateChildStatusDialogBox();
×
967
            }
968
        });
×
969
        curGroup.setOnVaccineClickedListener((vaccineGroup, vaccine) -> {
×
970
            if (dialogOpen) {
×
971
                return;
×
972
            }
973

974
            dialogOpen = true;
×
975
            if (isChildActive) {
×
976
                ArrayList<VaccineWrapper> vaccineWrappers = new ArrayList<>();
×
977
                vaccineWrappers.add(vaccine);
×
978
                addVaccinationDialogFragment(vaccineWrappers, vaccineGroup);
×
979
            } else {
×
980
                showActivateChildStatusDialogBox();
×
981
            }
982
        });
×
983
        curGroup.setOnVaccineUndoClickListener((vaccineGroup, vaccine) -> {
×
984
            if (dialogOpen) {
×
985
                return;
×
986
            }
987

988
            dialogOpen = true;
×
989
            if (isChildActive) {
×
990
                addVaccineUndoDialogFragment(vaccineGroup, vaccine);
×
991
            } else {
992
                showActivateChildStatusDialogBox();
×
993
            }
994
        });
×
995

996
        LinearLayout parent;
997
        int groupParentId = canvasId;
×
998
        if (groupParentId == -1) {
×
999
            SecureRandom r = new SecureRandom();
×
1000
            groupParentId = r.nextInt(RANDOM_MAX_RANGE - RANDOM_MIN_RANGE) + RANDOM_MIN_RANGE;
×
1001
            parent = new LinearLayout(this);
×
1002
            parent.setId(groupParentId);
×
1003
            vaccineGroupCanvasLL.addView(parent);
×
1004
        } else {
×
1005
            parent = findViewById(groupParentId);
×
1006
            parent.removeAllViews();
×
1007
        }
1008
        parent.addView(curGroup);
×
1009
        curGroup.setTag(R.id.vaccine_group_vaccine_data, vaccineGroupData.toString());
×
1010
        curGroup.setTag(R.id.vaccine_group_parent_id, String.valueOf(groupParentId));
×
1011
        vaccineGroups.add(curGroup);
×
1012
    }
×
1013

1014
    @Override
1015
    public void showVaccineNotifications(List<Vaccine> vaccineList, List<Alert> alerts) {
1016

1017
        Map<String, String> details = childDetails.getDetails();
1✔
1018

1019
        if (details.get(Constants.SHOW_BCG2_REMINDER) != null || details.get(Constants.SHOW_BCG_SCAR) != null) {
1✔
1020
            return;
1✔
1021
        }
1022

1023
        // This fixes the possibility of multiple popups
1024
        if (registerClickables != null && (registerClickables.isRecordAll()
1✔
1025
                || registerClickables.isRecordWeight())) {
1✔
1026
            return;
×
1027
        }
1028

1029
        if (VaccinateActionUtils.hasVaccine(vaccineList, VaccineRepo.Vaccine.bcg2)) {
1✔
1030
            return;
1✔
1031
        }
1032

1033
        Vaccine bcg = VaccinateActionUtils.getVaccine(vaccineList, VaccineRepo.Vaccine.bcg);
1✔
1034
        if (bcg == null) {
1✔
1035
            return;
1✔
1036
        }
1037

1038
        Alert alert = VaccinateActionUtils.getAlert(alerts, VaccineRepo.Vaccine.bcg2);
1✔
1039
        if (alert == null || alert.isComplete()) {
1✔
1040
            return;
1✔
1041
        }
1042

1043
        /*int bcgOffsetInWeeks = 12;
1044
        Calendar twelveWeeksLaterDate = Calendar.getInstance();
1045
        twelveWeeksLaterDate.setTime(bcg.getDate());
1046
        twelveWeeksLaterDate.add(Calendar.WEEK_OF_YEAR, bcgOffsetInWeeks);
1047

1048
        Calendar today = Calendar.getInstance();
1049

1050
        if (today.getTime().after(twelveWeeksLaterDate.getTime()) || DateUtils.isSameDay(twelveWeeksLaterDate, today)) {
1051
            showCheckBcgScarNotification(alert);
1052
        }*/
1053

1054
        ArrayList<org.smartregister.immunization.domain.jsonmapping.Vaccine> vaccinesMapping = ((ArrayList<org.smartregister.immunization.domain.jsonmapping.Vaccine>) ImmunizationLibrary.getInstance().getVaccinesConfigJsonMap().get("special_vaccines.json"));
1✔
1055

1056

1057
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
1✔
1058
        Date dob = Utils.dobStringToDate(dobString);
1✔
1059

1060
        for (org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine : vaccinesMapping) {
1✔
1061
            if (vaccine.getType().equalsIgnoreCase(Constants.VACCINE.BCG)) {
1✔
1062
                boolean allowedExpiredVaccineEntry = ChildLibrary.getInstance().getProperties().hasProperty(IMConstants.APP_PROPERTIES.VACCINE_EXPIRED_ENTRY_ALLOW) &&
1✔
1063
                        ChildLibrary.getInstance().getProperties().getPropertyBoolean(IMConstants.APP_PROPERTIES.VACCINE_EXPIRED_ENTRY_ALLOW);
1✔
1064
                if (isVaccineDue(vaccineList, dob, vaccine, allowedExpiredVaccineEntry)) {
1✔
1065
                    showCheckBcgScarNotification();
1✔
1066
                }
1067

1068
                break;
1069
            }
1070
        }
×
1071
    }
1✔
1072

1073
    @VisibleForTesting
1074
    protected boolean isVaccineDue(@NonNull List<Vaccine> vaccineList, @NonNull Date dob, @NonNull org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine, boolean allowedExpiredVaccineEntry) {
1075
        return Utils.isVaccineDue(vaccineList, dob, vaccine, allowedExpiredVaccineEntry);
×
1076
    }
1077

1078
    private void addVaccinationDialogFragment(ArrayList<VaccineWrapper> vaccineWrappers, VaccineGroup vaccineGroup) {
1079
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
×
1080
        Fragment prev = this.getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
1081
        if (prev != null) {
×
1082
            return;
×
1083
        }
1084
        ft.addToBackStack(null);
×
1085

1086
        vaccineGroup.setModalOpen(true);
×
1087
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1088
        Date dob = Utils.dobStringToDate(dobString);
×
1089
        if (dob == null) {
×
1090
            dob = Calendar.getInstance().getTime();
×
1091
        }
1092

1093
        List<Vaccine> vaccineList =
1094
                ImmunizationLibrary.getInstance().vaccineRepository().findByEntityId(childDetails.entityId());
×
1095
        if (vaccineList == null) {
×
1096
            vaccineList = new ArrayList<>();
×
1097
        }
1098

1099
        VaccinationDialogFragment vaccinationDialogFragment =
×
1100
                VaccinationDialogFragment.newInstance(dob, vaccineList, vaccineWrappers, true);
×
1101
        vaccinationDialogFragment.show(ft, DIALOG_TAG);
×
1102
        vaccinationDialogFragment.setOnDismissListener(dialog -> dialogOpen = false);
×
1103

1104
    }
×
1105

1106
    private void addVaccineUndoDialogFragment(VaccineGroup vaccineGroup, VaccineWrapper vaccineWrapper) {
1107
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
×
1108
        Fragment prev = getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
1109
        if (prev != null) {
×
1110
            return;
×
1111
        }
1112
        fragmentTransaction.addToBackStack(null);
×
1113

1114
        vaccineGroup.setModalOpen(true);
×
1115

1116
        UndoVaccinationDialogFragment undoVaccinationDialogFragment = UndoVaccinationDialogFragment.newInstance(vaccineWrapper);
×
1117
        undoVaccinationDialogFragment.show(fragmentTransaction, DIALOG_TAG);
×
1118
        undoVaccinationDialogFragment.setOnDismissListener(dialog -> dialogOpen = false);
×
1119
    }
×
1120

1121
    private void showCheckBcgScarNotification() {
1122
        if (!bcgScarNotificationShown) {
1✔
1123
            bcgScarNotificationShown = true;
1✔
1124
            final ViewGroup rootView = (ViewGroup) ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
1✔
1125

1126
            new BCGNotificationDialog(this, (dialog, which) -> {
1✔
1127
                onBcgReminderOptionSelected(Constants.SHOW_BCG_SCAR);
×
1128
                Snackbar.make(rootView, R.string.turn_off_reminder_notification_message, Snackbar.LENGTH_LONG).show();
×
1129
            }, (dialog, which) -> {
×
1130
                onBcgReminderOptionSelected(Constants.SHOW_BCG2_REMINDER);
×
1131
                Snackbar.make(rootView, R.string.create_reminder_notification_message, Snackbar.LENGTH_LONG).show();
×
1132
            }).show();
1✔
1133
        }
1134
    }
1✔
1135

1136
    public void onBcgReminderOptionSelected(String option) {
1137
        final long DATE = new Date().getTime();
×
1138
        switch (option) {
×
1139
            case Constants.SHOW_BCG2_REMINDER:
1140
                ChildDbUtils.updateChildDetailsValue(Constants.SHOW_BCG2_REMINDER, Boolean.TRUE.toString(), childDetails.entityId());
×
1141
                break;
×
1142

1143
            case Constants.SHOW_BCG_SCAR:
1144
                ChildDbUtils.updateChildDetailsValue(Constants.SHOW_BCG_SCAR, String.valueOf(DATE), childDetails.entityId());
×
1145
                String providerId = getOpenSRPContext().allSharedPreferences().fetchRegisteredANM();
×
1146
                String locationId = Utils.context().allSharedPreferences().getPreference(AllConstants.CURRENT_LOCATION_ID);
×
1147
                ChildJsonFormUtils.createBCGScarEvent(getActivity(), childDetails.entityId(), providerId, locationId);
×
1148
                break;
×
1149

1150
            default:
1151
                break;
1152
        }
1153

1154
        vaccineGroupCanvasLL.removeAllViews();
×
1155
        vaccineGroups = null;
×
1156
        updateViews();
×
1157
    }
×
1158

1159
    private void updateGrowthViews(Weight lastUnsyncedWeight, Height lastUnsyncedHeight, final boolean isActive) {
1160
        String childName = constructChildName();
1✔
1161
        String gender = Utils.getValue(childDetails.getColumnmaps(), AllConstants.ChildRegistrationFields.GENDER, true);
1✔
1162
        String motherFirstName = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.MOTHER_FIRST_NAME, true);
1✔
1163
        if (StringUtils.isBlank(childName) && StringUtils.isNotBlank(motherFirstName)) {
1✔
1164
            childName = "B/o " + motherFirstName.trim();
×
1165
        }
1166

1167
        String openSrpId = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.ZEIR_ID, false);
1✔
1168
        String duration = "";
1✔
1169
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
1✔
1170
        DateTime dateTime = Utils.dobStringToDateTime(dobString);
1✔
1171
        if (dateTime != null) {
1✔
1172
            duration = DateUtil.getDuration(dateTime);
1✔
1173
        }
1174

1175
        Photo photo = getProfilePhotoByClient(childDetails);
1✔
1176

1177
        WeightWrapper weightWrapper = getWeightWrapper(lastUnsyncedWeight, childName, gender, openSrpId, duration, photo);
1✔
1178
        if (weightWrapper != null) {
1✔
1179
            weightWrapper.setDob(dobString);
1✔
1180
        }
1181

1182
        HeightWrapper heightWrapper = null;
1✔
1183
        if (monitorGrowth) {
1✔
1184
            heightWrapper = getHeightWrapper(lastUnsyncedHeight, childName, gender, openSrpId, duration, photo);
1✔
1185
            heightWrapper.setDob(dobString);
1✔
1186
        }
1187
        updateRecordGrowthMonitoringViews(weightWrapper, heightWrapper, isActive);
1✔
1188

1189
        growthChartButton.setOnClickListener(v -> Utils.startAsyncTask(new ShowGrowthChartTask(presenter, childDetails), null));
1✔
1190
    }
1✔
1191

1192
    @VisibleForTesting
1193
    protected Photo getProfilePhotoByClient(CommonPersonObjectClient childDetails) {
1194
        return ImageUtils.profilePhotoByClient(childDetails);
×
1195
    }
1196

1197
    @NotNull
1198
    private WeightWrapper getWeightWrapper(Weight lastUnsyncedWeight, String childName, String gender, String openSrpId,
1199
                                           String duration, Photo photo) {
1200
        WeightWrapper weightWrapper = new WeightWrapper();
1✔
1201
        weightWrapper.setId(childDetails.entityId());
1✔
1202
        weightWrapper.setGender(gender);
1✔
1203
        weightWrapper.setPatientName(childName);
1✔
1204
        weightWrapper.setPatientNumber(openSrpId);
1✔
1205
        weightWrapper.setPatientAge(duration);
1✔
1206
        weightWrapper.setPhoto(photo);
1✔
1207
        weightWrapper.setPmtctStatus(Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.PMTCT_STATUS, false));
1✔
1208

1209
        if (lastUnsyncedWeight != null) {
1✔
1210
            weightWrapper.setWeight(lastUnsyncedWeight.getKg());
1✔
1211
            weightWrapper.setDbKey(lastUnsyncedWeight.getId());
1✔
1212
            weightWrapper.setUpdatedWeightDate(new DateTime(lastUnsyncedWeight.getDate()), false);
1✔
1213
        }
1214
        return weightWrapper;
1✔
1215
    }
1216

1217
    @NotNull
1218
    private HeightWrapper getHeightWrapper(Height lastUnsyncedHeight, String childName, String gender, String openSrpId,
1219
                                           String duration, Photo photo) {
1220
        HeightWrapper heightWrapper = new HeightWrapper();
1✔
1221
        heightWrapper.setId(childDetails.entityId());
1✔
1222
        heightWrapper.setGender(gender);
1✔
1223
        heightWrapper.setPatientName(childName);
1✔
1224
        heightWrapper.setPatientNumber(openSrpId);
1✔
1225
        heightWrapper.setPatientAge(duration);
1✔
1226
        heightWrapper.setPhoto(photo);
1✔
1227
        heightWrapper.setPmtctStatus(Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.PMTCT_STATUS, false));
1✔
1228

1229
        if (lastUnsyncedHeight != null) {
1✔
1230
            heightWrapper.setHeight(lastUnsyncedHeight.getCm());
1✔
1231
            heightWrapper.setDbKey(lastUnsyncedHeight.getId());
1✔
1232
            heightWrapper.setUpdatedHeightDate(new DateTime(lastUnsyncedHeight.getDate()), false);
1✔
1233
        }
1234
        return heightWrapper;
1✔
1235
    }
1236

1237
    @VisibleForTesting
1238
    protected void updateRecordGrowthMonitoringViews(WeightWrapper weightWrapper, HeightWrapper heightWrapper, final boolean isActive) {
1239

1240
        recordWeightText.setText(R.string.record_growth);
1✔
1241
        recordWeightText.setTextColor(!isActive ? getResources().getColor(R.color.inactive_text_color) : getResources().getColor(R.color.text_black));
1✔
1242
        recordWeightCheck.setVisibility(View.GONE);
1✔
1243

1244
        //Checking if the growth point is also a birth date point by comparing DOB. We wont allow edits for such
1245

1246
        if (weightWrapper != null) {
1✔
1247
            updateWeightWrapper(weightWrapper, recordGrowth, recordWeightText, recordWeightCheck);
1✔
1248
        }
1249

1250
        if (monitorGrowth) {
1✔
1251
            updateHeightWrapper(heightWrapper, recordGrowth, recordWeightCheck);
1✔
1252
        }
1253

1254
        updateRecordWeightText(weightWrapper, heightWrapper);
1✔
1255
        updateRecordGrowth(weightWrapper, heightWrapper, isActive);
1✔
1256

1257
    }
1✔
1258

1259
    private void updateRecordWeightText(WeightWrapper weightWrapper, HeightWrapper heightWrapper) {
1260
        String weight = "";
1✔
1261
        String height = "";
1✔
1262
        if ((weightWrapper != null && weightWrapper.getDbKey() != null && weightWrapper.getWeight() != null) || (heightWrapper != null && heightWrapper.getDbKey() != null && heightWrapper.getHeight() != null)) {
1✔
1263
            if (weightWrapper != null && weightWrapper.getWeight() != null) {
1✔
1264
                weight = Utils.kgStringSuffix(weightWrapper.getWeight());
1✔
1265
            }
1266
            if (monitorGrowth && heightWrapper != null && heightWrapper.getHeight() != null) {
1✔
1267
                height = Utils.cmStringSuffix(heightWrapper.getHeight());
1✔
1268
            }
1269

1270
            isGrowthEdit = true;
1✔
1271
            if (monitorGrowth) {
1✔
1272
                recordWeightText.setText(getGrowthMonitoringValues(height, weight));
1✔
1273
            } else {
1274
                recordWeightText.setText(weight);
1✔
1275
            }
1276
        } else {
1277
            isGrowthEdit = false;
×
1278
        }
1279
    }
1✔
1280

1281
    private String getGrowthMonitoringValues(String height, String weight) {
1282
        String seperator = !TextUtils.isEmpty(height) && !TextUtils.isEmpty(weight) ? ", " : "";
1✔
1283
        return weight + seperator + height;
1✔
1284
    }
1285

1286
    private void updateRecordGrowth(WeightWrapper weightWrapper, HeightWrapper heightWrapper, final boolean isActive) {
1287
        recordGrowth.setClickable(true);
1✔
1288
        recordGrowth.setBackground(getResources().getDrawable(R.drawable.record_growth_bg));
1✔
1289
        recordGrowth.setTag(R.id.weight_wrapper, weightWrapper);
1✔
1290
        if (monitorGrowth) {
1✔
1291
            recordGrowth.setTag(R.id.height_wrapper, heightWrapper);
1✔
1292
        }
1293

1294
        recordGrowth.setTag(R.id.growth_edit_flag, isGrowthEdit);
1✔
1295
        recordGrowth.setOnClickListener(new View.OnClickListener() {
1✔
1296
            @Override
1297
            public void onClick(View view) {
1298
                if (isActive) {
×
1299
                    showGrowthDialog(view);
×
1300
                } else {
1301
                    showActivateChildStatusDialogBox();
×
1302
                }
1303
            }
×
1304
        });
1305
    }
1✔
1306

1307
    private void updateWeightWrapper(WeightWrapper weightWrapper, View recordGrowth, TextView recordWeightText, ImageView recordWeightCheck) {
1308
        if (weightWrapper != null && weightWrapper.getDbKey() != null && weightWrapper.getWeight() != null) {
1✔
1309
            recordWeightCheck.setVisibility(View.VISIBLE);
1✔
1310

1311
            if (weightWrapper.getUpdatedWeightDate() != null) {
1✔
1312
                long timeDiff = Calendar.getInstance().getTimeInMillis() - weightWrapper.getUpdatedWeightDate().getMillis();
1✔
1313

1314
                if (timeDiff <= TimeUnit.MILLISECONDS.convert(RECORD_WEIGHT_BUTTON_ACTIVE_MIN, TimeUnit.HOURS)) {
1✔
1315
                    //disable the button
1316
                    recordGrowth.setClickable(false);
1✔
1317
                    recordGrowth.setBackground(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
1✔
1318
                } else {
1319
                    //reset state
1320
                    weightWrapper.setWeight(null);
1✔
1321
                    weightWrapper.setDbKey(null);
1✔
1322
                    recordGrowth.setClickable(true);
1✔
1323
                    recordGrowth.setBackground(getResources().getDrawable(R.drawable.record_growth_bg));
1✔
1324
                    recordWeightText.setText(R.string.record_growth);
1✔
1325
                    recordWeightCheck.setVisibility(View.GONE);
1✔
1326

1327
                    // Reset the edit flag since this
1328
                    isGrowthEdit = false;
1✔
1329
                }
1330
            }
1331
        }
1332
    }
1✔
1333

1334
    private void updateHeightWrapper(HeightWrapper heightWrapper, View recordGrowth, ImageView recordWeightCheck) {
1335
        if (heightWrapper != null && heightWrapper.getDbKey() != null && heightWrapper.getHeight() != null) {
1✔
1336
            recordWeightCheck.setVisibility(View.VISIBLE);
1✔
1337

1338
            if (heightWrapper.getUpdatedHeightDate() != null) {
1✔
1339
                long timeDiff = Calendar.getInstance().getTimeInMillis() - heightWrapper.getUpdatedHeightDate().getMillis();
1✔
1340

1341
                if (timeDiff <= TimeUnit.MILLISECONDS.convert(RECORD_WEIGHT_BUTTON_ACTIVE_MIN, TimeUnit.HOURS)) {
1✔
1342
                    //disable the button
1343
                    recordGrowth.setClickable(false);
1✔
1344
                    recordGrowth.setBackground(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
1✔
1345
                } else {
1346
                    //reset state
1347
                    heightWrapper.setHeight(null);
1✔
1348
                    heightWrapper.setDbKey(null);
1✔
1349
                    recordGrowth.setClickable(true);
1✔
1350
                    recordGrowth.setBackground(getResources().getDrawable(R.drawable.record_growth_bg));
1✔
1351
                    recordWeightCheck.setVisibility(View.GONE);
1✔
1352
                }
1353
            }
1354
        }
1355
    }
1✔
1356

1357
    private void showGrowthDialog(View view) {
1358
        FragmentTransaction fragmentTransaction = this.getSupportFragmentManager().beginTransaction();
×
1359
        Fragment prev = this.getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
1360
        if (prev != null) {
×
1361
            return;
×
1362
        }
1363
        fragmentTransaction.addToBackStack(null);
×
1364

1365
        showProgressDialog(getString(R.string.loading), getString(R.string.loading_form_message));
×
1366

1367
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1368
        Date dob = Utils.dobStringToDate(dobString);
×
1369
        if (dob == null) {
×
1370
            dob = Calendar.getInstance().getTime();
×
1371
        }
1372

1373
        WeightWrapper weightWrapper = (WeightWrapper) view.getTag(R.id.weight_wrapper);
×
1374
        HeightWrapper heightWrapper = null;
×
1375
        if (monitorGrowth) {
×
1376
            heightWrapper = (HeightWrapper) view.getTag(R.id.height_wrapper);
×
1377
        }
1378

1379
        boolean isGrowthEdit = (boolean) view.getTag(R.id.growth_edit_flag);
×
1380
        if (isGrowthEdit) {
×
1381
            EditGrowthDialogFragment editWeightDialogFragment = EditGrowthDialogFragment.newInstance(dob, weightWrapper, heightWrapper);
×
1382
            editWeightDialogFragment.show(fragmentTransaction, DIALOG_TAG);
×
1383
        } else {
×
1384
            RecordGrowthDialogFragment recordWeightDialogFragment = RecordGrowthDialogFragment.newInstance(dob, weightWrapper, heightWrapper);
×
1385
            recordWeightDialogFragment.show(fragmentTransaction, DIALOG_TAG);
×
1386
        }
1387

1388
        hideProgressDialog();
×
1389
    }
×
1390

1391
    @Override
1392
    public void onLocationChanged(final String newLocation) {
1393
        Utils.refreshDataCaptureStrategyBanner(this, newLocation);
×
1394
    }
×
1395

1396
    @Override
1397
    public void onGrowthRecorded(WeightWrapper weightWrapper, HeightWrapper heightWrapper) {
1398
        String genderString = Utils.getValue(childDetails, AllConstants.ChildRegistrationFields.GENDER, false);
×
1399
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1400

1401
        if (weightWrapper != null && weightWrapper.getUpdatedWeightDate() != null) {
×
1402
            weightWrapper.setGender(genderString);
×
1403
            weightWrapper.setDob(dobString);
×
1404
            Utils.recordWeight(GrowthMonitoringLibrary.getInstance().weightRepository(), weightWrapper, BaseRepository.TYPE_Unsynced);
×
1405
        }
1406

1407
        if (monitorGrowth && heightWrapper != null && heightWrapper.getUpdatedHeightDate() != null) {
×
1408
            heightWrapper.setGender(genderString);
×
1409
            heightWrapper.setDob(dobString);
×
1410
            Utils.recordHeight(GrowthMonitoringLibrary.getInstance().heightRepository(), heightWrapper, BaseRepository.TYPE_Unsynced);
×
1411
        }
1412

1413
        setLastModified(true);
×
1414
        startUpdateViewTask();
×
1415
    }
×
1416

1417
    @Override
1418
    public void onVaccinateToday(ArrayList<VaccineWrapper> tags, View v) {
1419
        if (tags != null && !tags.isEmpty()) {
×
1420
            View view = getLastOpenedView();
×
1421
            saveVaccine(tags, view);
×
1422
        }
1423
    }
×
1424

1425
    @Override
1426
    public void onVaccinateEarlier(ArrayList<VaccineWrapper> tags, View v) {
1427
        if (tags != null && !tags.isEmpty()) {
×
1428
            View view = getLastOpenedView();
×
1429
            saveVaccine(tags, view);
×
1430
        }
1431
    }
×
1432

1433
    @Override
1434
    public void onUndoVaccination(VaccineWrapper tag, View view) {
1435

1436
        Utils.startAsyncTask(new UndoVaccineTask(presenter, tag, childDetails, getOpenSRPContext().alertService()), null);
×
1437
    }
×
1438

1439
    @Override
1440
    public VaccineGroup getLastOpenedView() {
1441
        if (vaccineGroups == null) {
×
1442
            return null;
×
1443
        }
1444

1445
        for (VaccineGroup vaccineGroup : vaccineGroups) {
×
1446
            if (vaccineGroup.isModalOpen()) {
×
1447
                return vaccineGroup;
×
1448
            }
1449
        }
×
1450

1451
        return null;
×
1452
    }
1453

1454
    private void saveVaccine(ArrayList<VaccineWrapper> tags, final View view) {
1455
        if (tags.isEmpty()) {
×
1456
            return;
×
1457
        }
1458

1459
        VaccineWrapper[] arrayTags = tags.toArray(new VaccineWrapper[tags.size()]);
×
1460
        SaveVaccinesTask backgroundTask = new SaveVaccinesTask();
×
1461
        backgroundTask.setVaccineRepository(ImmunizationLibrary.getInstance().vaccineRepository());
×
1462
        backgroundTask.setView(view);
×
1463
        Utils.startAsyncTask(backgroundTask, arrayTags);
×
1464

1465
    }
×
1466

1467
    private void performRegisterActions() {
1468
        if (registerClickables != null) {
×
1469
            if (registerClickables.isRecordWeight()) {
×
1470
                recordGrowth.post(new Runnable() {
×
1471
                    @Override
1472
                    public void run() {
1473
                        recordGrowth.performClick();
×
1474
                    }
×
1475
                });
1476
            } else if (registerClickables.isRecordAll()) {
×
1477
                performRecordAllClick(0);
×
1478
            }
1479

1480
            //Reset register actions
1481
            registerClickables.setRecordAll(false);
×
1482
            registerClickables.setRecordWeight(false);
×
1483
        }
1484
    }
×
1485

1486
    private void performRecordAllClick(final int index) {
1487
        if (vaccineGroups != null && vaccineGroups.size() > index) {
×
1488
            final VaccineGroup vaccineGroup = vaccineGroups.get(index);
×
1489
            vaccineGroup.post(() -> vaccineGroup.setVaccineCardAdapterLoadingListener(() -> {
×
1490
                ArrayList<VaccineWrapper> vaccineWrappers = vaccineGroup.getDueVaccines();
×
1491
                if (!vaccineWrappers.isEmpty()) {
×
1492
                    final TextView recordAllTV = vaccineGroup.findViewById(R.id.record_all_tv);
×
1493
                    recordAllTV.post(new Runnable() {
×
1494
                        @Override
1495
                        public void run() {
1496
                            recordAllTV.performClick();
×
1497
                        }
×
1498
                    });
1499
                } else {
×
1500
                    performRecordAllClick(index + 1);
×
1501
                }
1502
            }));
×
1503
        }
1504
    }
×
1505

1506
    private void saveVaccine(VaccineRepository vaccineRepository, VaccineWrapper tag) {
1507
        if (tag.getUpdatedVaccineDate() == null) {
×
1508
            return;
×
1509
        }
1510

1511
        boolean isOutOfCatchmentVaccine = Constants.BOOLEAN_STRING.TRUE.equals(Utils.getValue(childDetails.getColumnmaps(), Constants.Client.IS_OUT_OF_CATCHMENT, false));
×
1512
        Vaccine vaccine = new Vaccine();
×
1513
        if (tag.getDbKey() != null) {
×
1514
            vaccine = vaccineRepository.find(tag.getDbKey());
×
1515
        }
1516

1517
        if (StringUtils.isNotEmpty(childDetails.entityId())) {
×
1518
            vaccine.setBaseEntityId(childDetails.entityId());
×
1519
        } else {
1520
            vaccine.setBaseEntityId(isOutOfCatchmentVaccine && !BaseRepository.TYPE_Synced.equals(vaccine.getSyncStatus()) ? "" : childDetails.entityId());
×
1521
        }
1522

1523
        vaccine.setName(tag.getName());
×
1524
        vaccine.setDate(tag.getUpdatedVaccineDate().toDate());
×
1525
        vaccine.setAnmId(getOpenSRPContext().allSharedPreferences().fetchRegisteredANM());
×
1526
        vaccine.setLocationId(ChildJsonFormUtils.getProviderLocationId(this));
×
1527
        vaccine.setChildLocationId(ChildJsonFormUtils.getChildLocationId(getOpenSRPContext().allSharedPreferences().fetchDefaultLocalityId(vaccine.getAnmId()), getOpenSRPContext().allSharedPreferences()));
×
1528

1529
        String lastChar = vaccine.getName().substring(vaccine.getName().length() - 1);
×
1530
        if (StringUtils.isNumeric(lastChar)) {
×
1531
            vaccine.setCalculation(Integer.valueOf(lastChar));
×
1532
        } else {
1533
            vaccine.setCalculation(-1);
×
1534
        }
1535

1536
        vaccine.setOutOfCatchment(isOutOfCatchmentVaccine ? 1 : 0);
×
1537

1538
        if (isOutOfCatchmentVaccine && StringUtils.isEmpty(vaccine.getProgramClientId())) {
×
1539
            vaccine.setProgramClientId(tag.getPatientNumber());
×
1540
        }
1541

1542
        Utils.addVaccine(vaccineRepository, vaccine);
×
1543
        tag.setDbKey(vaccine.getId());
×
1544
        setLastModified(true);
×
1545
    }
×
1546

1547
    private void updateVaccineGroupViews(View view, final List<VaccineWrapper> wrappers, List<Vaccine> vaccineList) {
1548
        updateVaccineGroupViews(view, wrappers, vaccineList, false);
×
1549
    }
×
1550

1551
    @Override
1552
    public void updateVaccineGroupViews(View view, final List<VaccineWrapper> wrappers, final List<Vaccine> vaccineList, final boolean undo) {
1553
        if (!(view instanceof VaccineGroup)) {
×
1554
            return;
×
1555
        }
1556
        final VaccineGroup vaccineGroup = (VaccineGroup) view;
×
1557
        vaccineGroup.setModalOpen(false);
×
1558

1559
        if (Looper.myLooper() == Looper.getMainLooper()) {
×
1560
            if (undo) {
×
1561
                vaccineGroup.setVaccineList(vaccineList);
×
1562
                vaccineGroup.updateWrapperStatus((ArrayList<VaccineWrapper>) wrappers, Constants.KEY.CHILD);
×
1563
            }
1564
            vaccineGroup.updateViews((ArrayList<VaccineWrapper>) wrappers);
×
1565

1566
        } else {
1567
            Handler handler = new Handler(Looper.getMainLooper());
×
1568
            handler.post(() -> {
×
1569
                if (undo) {
×
1570
                    vaccineGroup.setVaccineList(vaccineList);
×
1571
                    vaccineGroup.updateWrapperStatus((ArrayList<VaccineWrapper>) wrappers, Constants.KEY.CHILD);
×
1572
                }
1573
                vaccineGroup.updateViews((ArrayList<VaccineWrapper>) wrappers);
×
1574
            });
×
1575
        }
1576
    }
×
1577

1578
    private void showRecordWeightNotification() {
1579
        if (!weightNotificationShown) {
×
1580
            weightNotificationShown = true;
×
1581
            showNotification(R.string.record_growth_notification, R.drawable.ic_weight_notification, R.string.record_growth,
×
1582
                    v -> {
1583
                        showGrowthDialog(recordGrowth);
×
1584
                        hideNotification();
×
1585
                        weightNotificationShown = false;
×
1586
                    }, R.string.cancel, v -> {
×
1587
                        weightNotificationShown = false;
×
1588
                        hideNotification();
×
1589
                    }, null);
×
1590
        }
1591
    }
×
1592

1593
    @Override
1594
    public void updateVaccineGroupsUsingAlerts(List<String> affectedVaccines, List<Vaccine> vaccineList, List<Alert> alerts) {
1595
        if (affectedVaccines != null && vaccineList != null && vaccineGroups != null) {
×
1596
            // Update all other affected vaccine groups
1597
            HashMap<VaccineGroup, ArrayList<VaccineWrapper>> affectedGroups = new HashMap<>();
×
1598
            for (String curAffectedVaccineName : affectedVaccines) {
×
1599
                boolean viewFound = false;
×
1600
                // Check what group it is in
1601
                for (VaccineGroup curGroup : vaccineGroups) {
×
1602
                    ArrayList<VaccineWrapper> groupWrappers = curGroup.getAllVaccineWrappers();
×
1603
                    if (groupWrappers == null) groupWrappers = new ArrayList<>();
×
1604
                    for (VaccineWrapper curWrapper : groupWrappers) {
×
1605
                        String curWrapperName = curWrapper.getName().trim();
×
1606
                        // Check if current wrapper is one of the combined vaccines
1607
                        if (ImmunizationLibrary.COMBINED_VACCINES.contains(curWrapperName)) {
×
1608
                            // Check if any of the sister vaccines is currAffectedVaccineName
1609
                            String[] allSisters = ImmunizationLibrary.COMBINED_VACCINES_MAP.get(curWrapperName).split(" / ");
×
1610
                            for (String allSister : allSisters) {
×
1611
                                if (VaccinatorUtils.cleanVaccineName(allSister).equalsIgnoreCase(VaccinatorUtils.cleanVaccineName(curAffectedVaccineName))) {
×
1612
                                    curWrapperName = allSister;
×
1613
                                    break;
×
1614
                                }
1615
                            }
1616
                        }
1617

1618
                        if (VaccinatorUtils.cleanVaccineName(curWrapperName).contains(VaccinatorUtils.cleanVaccineName(curAffectedVaccineName))) {
×
1619
                            if (!affectedGroups.containsKey(curGroup)) {
×
1620
                                affectedGroups.put(curGroup, new ArrayList<>());
×
1621
                            }
1622

1623
                            affectedGroups.get(curGroup).add(curWrapper);
×
1624
                            viewFound = true;
×
1625
                        }
1626

1627
                        if (viewFound) break;
×
1628
                    }
×
1629

1630
                    if (viewFound) break;
×
1631
                }
×
1632
            }
×
1633

1634
            addVaccineGroups(vaccineList, alerts, affectedGroups);
×
1635
        }
1636
    }
×
1637

1638
    private void addVaccineGroups(List<Vaccine> vaccineList, List<Alert> alerts, HashMap<VaccineGroup, ArrayList<VaccineWrapper>> affectedGroups) {
1639
        for (VaccineGroup curGroup : affectedGroups.keySet()) {
×
1640
            try {
1641
                vaccineGroups.remove(curGroup);
×
1642
                addVaccineGroup(Integer.parseInt((String) curGroup.getTag(R.id.vaccine_group_parent_id)), curGroup.getVaccineData(), vaccineList, alerts);
×
1643
            } catch (Exception e) {
×
1644
                Timber.e(e);
×
1645
            }
×
1646
        }
×
1647
    }
×
1648

1649
    //Recurring Service
1650
    @Override
1651
    public void onGiveToday(ServiceWrapper tag, View v) {
1652
        if (tag != null) {
×
1653
            View view = RecurringServiceUtils.getLastOpenedServiceView(serviceGroups);
×
1654
            saveService(tag, view);
×
1655
        }
1656
    }
×
1657

1658
    @Override
1659
    public void onGiveEarlier(ServiceWrapper tag, View v) {
1660
        if (tag != null) {
×
1661
            View view = RecurringServiceUtils.getLastOpenedServiceView(serviceGroups);
×
1662
            saveService(tag, view);
×
1663
        }
1664
    }
×
1665

1666
    @Override
1667
    public void onUndoService(ServiceWrapper tag, View v) {
1668
        Utils.startAsyncTask(new UndoServiceTask(tag), null);
×
1669
    }
×
1670

1671
    private void saveService(ServiceWrapper tag, final View view) {
1672
        if (tag == null) {
×
1673
            return;
×
1674
        }
1675

1676
        ServiceWrapper[] arrayTags = {tag};
×
1677
        SaveServiceTask backgroundTask = new SaveServiceTask();
×
1678
        String providerId = getOpenSRPContext().allSharedPreferences().fetchRegisteredANM();
×
1679
        String locationId = ChildJsonFormUtils.getProviderLocationId(this);
×
1680
        String childLocationId = ChildJsonFormUtils.getChildLocationId(locationId, getOpenSRPContext().allSharedPreferences());
×
1681
        String team = getOpenSRPContext().allSharedPreferences().fetchDefaultTeam(providerId);
×
1682
        String teamId = getOpenSRPContext().allSharedPreferences().fetchDefaultTeamId(providerId);
×
1683

1684
        backgroundTask.setProviderId(providerId);
×
1685
        backgroundTask.setLocationId(locationId);
×
1686
        backgroundTask.setChildLocationId(childLocationId);
×
1687
        backgroundTask.setTeam(team);
×
1688
        backgroundTask.setTeamId(teamId);
×
1689
        backgroundTask.setView(view);
×
1690
        Utils.startAsyncTask(backgroundTask, arrayTags);
×
1691
    }
×
1692

1693
    public Vaccine getVaccineAquiredByName(@NonNull List<Vaccine> vaccineList, @NonNull String name) {
1694

1695
        for (Vaccine vaccine : vaccineList) {
×
1696
            if (vaccine.getName().equals(name)) return vaccine;
×
1697
        }
×
1698
        return null;
×
1699
    }
1700

1701
    public String getCurrentLocation() {
1702
        return toolbar.getCurrentLocation();
×
1703
    }
1704

1705
    @Override
1706
    public abstract void onClick(View view);
1707

1708
    @Override
1709
    public CommonPersonObjectClient getChildDetails() {
1710
        return childDetails;
1✔
1711
    }
1712

1713
    @Override
1714
    public void showGrowthDialogFragment(Map<String, List> growthMonitoring) {
1715
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
×
1716
        Fragment prev = getSupportFragmentManager().findFragmentByTag(BaseChildImmunizationActivity.DIALOG_TAG);
×
1717
        if (prev != null) {
×
1718
            return;
×
1719
        }
1720
        fragmentTransaction.addToBackStack(null);
×
1721

1722
        showProgressDialog(getString(R.string.loading), getString(R.string.loading_form_message));
×
1723

1724
        List<Weight> weights = new ArrayList<>();
×
1725
        List<Height> heights = new ArrayList<>();
×
1726

1727
        if (growthMonitoring == null || growthMonitoring.isEmpty()) {
×
1728
            Utils.showToast(this, getString(R.string.record_growth_details));
×
1729
        } else {
1730
            if (growthMonitoring.containsKey(Constants.WEIGHT)) {
×
1731
                weights = growthMonitoring.get(Constants.WEIGHT);
×
1732
            }
1733

1734
            if (growthMonitoring.containsKey(Constants.HEIGHT)) {
×
1735
                heights = growthMonitoring.get(Constants.HEIGHT);
×
1736
            }
1737
        }
1738

1739
        GrowthDialogFragment growthDialogFragment = GrowthDialogFragment.newInstance(childDetails, weights, heights);
×
1740
        growthDialogFragment.show(fragmentTransaction, BaseChildImmunizationActivity.DIALOG_TAG);
×
1741

1742
        hideProgressDialog();
×
1743
    }
×
1744

1745
    ////////////////////////////////////////////////////////////////
1746
    // Inner classes
1747
    ////////////////////////////////////////////////////////////////
1748

1749
    public void updateScheduleDate() {
1750
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1751
        DateTime dateTime = Utils.dobStringToDateTime(dobString);
×
1752
        if (dateTime != null) {
×
1753
            VaccineSchedule.updateOfflineAlertsOnly(childDetails.entityId(), dateTime, Constants.KEY.CHILD);
×
1754
            if (recurringServiceEnabled) {
×
1755
                ServiceSchedule.updateOfflineAlerts(childDetails.entityId(), dateTime);
×
1756
            }
1757
        }
1758
    }
×
1759

1760
    @NotNull
1761
    private Map<String, NamedObject<?>> getStringNamedObjectMap(List<Vaccine> vaccineList, Weight weight, Height height, Map<String, List<ServiceType>> serviceTypeMap, List<ServiceRecord> serviceRecords, List<Alert> alertList) {
1762
        Map<String, NamedObject<?>> map = new HashMap<>();
1✔
1763

1764
        NamedObject<List<Vaccine>> vaccineNamedObject = new NamedObject<>(Vaccine.class.getName(), vaccineList);
1✔
1765
        map.put(vaccineNamedObject.name, vaccineNamedObject);
1✔
1766

1767
        NamedObject<Weight> weightNamedObject = new NamedObject<>(Weight.class.getName(), weight);
1✔
1768
        map.put(weightNamedObject.name, weightNamedObject);
1✔
1769

1770
        NamedObject<Height> heightNamedObject = new NamedObject<>(Height.class.getName(), height);
1✔
1771
        map.put(heightNamedObject.name, heightNamedObject);
1✔
1772

1773
        NamedObject<Map<String, List<ServiceType>>> serviceTypeNamedObject =
1✔
1774
                new NamedObject<>(ServiceType.class.getName(), serviceTypeMap);
1✔
1775
        map.put(serviceTypeNamedObject.name, serviceTypeNamedObject);
1✔
1776

1777
        NamedObject<List<ServiceRecord>> serviceRecordNamedObject =
1✔
1778
                new NamedObject<>(ServiceRecord.class.getName(), serviceRecords);
1✔
1779
        map.put(serviceRecordNamedObject.name, serviceRecordNamedObject);
1✔
1780

1781
        NamedObject<List<Alert>> alertsNamedObject = new NamedObject<>(Alert.class.getName(), alertList);
1✔
1782
        map.put(alertsNamedObject.name, alertsNamedObject);
1✔
1783

1784
        return map;
1✔
1785
    }
1786

1787
    private class UpdateViewTask extends AsyncTask<Void, Void, Map<String, NamedObject<?>>> {
1✔
1788

1789
        private VaccineRepository vaccineRepository;
1790
        private WeightRepository weightRepository;
1791
        private HeightRepository heightRepository;
1792
        private RecurringServiceTypeRepository recurringServiceTypeRepository;
1793
        private RecurringServiceRecordRepository recurringServiceRecordRepository;
1794
        private AlertService alertService;
1795

1796
        public void setVaccineRepository(VaccineRepository vaccineRepository) {
1797
            this.vaccineRepository = vaccineRepository;
1✔
1798
        }
1✔
1799

1800
        public void setWeightRepository(WeightRepository weightRepository) {
1801
            this.weightRepository = weightRepository;
1✔
1802
        }
1✔
1803

1804
        public void setHeightRepository(HeightRepository heightRepository) {
1805
            this.heightRepository = heightRepository;
×
1806
        }
×
1807

1808
        public void setRecurringServiceTypeRepository(RecurringServiceTypeRepository recurringServiceTypeRepository) {
1809
            this.recurringServiceTypeRepository = recurringServiceTypeRepository;
×
1810
        }
×
1811

1812
        public void setRecurringServiceRecordRepository(RecurringServiceRecordRepository recurringServiceRecordRepository) {
1813
            this.recurringServiceRecordRepository = recurringServiceRecordRepository;
×
1814
        }
×
1815

1816
        public void setAlertService(AlertService alertService) {
1817
            this.alertService = alertService;
1✔
1818
        }
1✔
1819

1820
        @Override
1821
        protected Map<String, NamedObject<?>> doInBackground(Void... voids) {
1822
            updateScheduleDate();
1✔
1823

1824
            List<Vaccine> vaccineList = new ArrayList<>();
1✔
1825
            Weight weight = null;
1✔
1826
            Height height = null;
1✔
1827

1828
            Map<String, List<ServiceType>> serviceTypeMap = new LinkedHashMap<>();
1✔
1829
            List<ServiceRecord> serviceRecords = new ArrayList<>();
1✔
1830

1831
            List<Alert> alertList = new ArrayList<>();
1✔
1832
            if (vaccineRepository != null) {
1✔
1833
                vaccineList = vaccineRepository.findByEntityId(childDetails.entityId());
1✔
1834
            }
1835

1836
            if (weightRepository != null) {
1✔
1837
                weight = weightRepository.findUnSyncedByEntityId(childDetails.entityId());
×
1838
            }
1839

1840
            if (heightRepository != null) {
1✔
1841
                height = heightRepository.findUnSyncedByEntityId(childDetails.entityId());
×
1842
            }
1843

1844
            if (Boolean.parseBoolean(ChildLibrary.getInstance().getProperties()
1✔
1845
                    .getProperty(ChildAppProperties.KEY.FEATURE_RECURRING_SERVICE_ENABLED, "true"))
1✔
1846
                    && recurringServiceRecordRepository != null) {
1847
                serviceRecords = recurringServiceRecordRepository.findByEntityId(childDetails.entityId());
×
1848
            }
1849

1850
            if (recurringServiceEnabled
1✔
1851
                    && recurringServiceTypeRepository != null) {
1852
                List<ServiceType> serviceTypes = recurringServiceTypeRepository.fetchAll();
×
1853
                for (ServiceType serviceType : serviceTypes) {
×
1854
                    String type = serviceType.getType();
×
1855
                    List<ServiceType> serviceTypeList = serviceTypeMap.get(type);
×
1856
                    if (serviceTypeList == null) {
×
1857
                        serviceTypeList = new ArrayList<>();
×
1858
                    }
1859
                    serviceTypeList.add(serviceType);
×
1860
                    serviceTypeMap.put(type, serviceTypeList);
×
1861
                }
×
1862
            }
1863

1864
            if (alertService != null) {
1✔
1865
                alertList = alertService.findByEntityId(childDetails.entityId());
×
1866
            }
1867

1868
            return getStringNamedObjectMap(vaccineList, weight, height, serviceTypeMap, serviceRecords, alertList);
1✔
1869
        }
1870

1871
        @Override
1872
        protected void onPreExecute() {
1873
            showProgressDialog(getString(R.string.updating_dialog_title), null);
1✔
1874
        }
1✔
1875

1876
        @Override
1877
        protected void onPostExecute(Map<String, NamedObject<?>> map) {
1878

1879
            List<Vaccine> vaccineList = AsyncTaskUtils.extractVaccines(map);
×
1880
            Map<String, List<ServiceType>> serviceTypeMap = AsyncTaskUtils.extractServiceTypes(map);
×
1881
            List<ServiceRecord> serviceRecords = AsyncTaskUtils.extractServiceRecords(map);
×
1882
            List<Alert> alertList = AsyncTaskUtils.extractAlerts(map);
×
1883
            Weight weight = AsyncTaskUtils.retrieveWeight(map);
×
1884
            Height height = ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.MONITOR_HEIGHT) ? AsyncTaskUtils.retrieveHeight(map) : null;
×
1885

1886
            updateGrowthViews(weight, height, isChildActive);
×
1887
            updateServiceViews(serviceTypeMap, serviceRecords, alertList);
×
1888
            updateVaccinationViews(vaccineList, alertList);
×
1889
            performRegisterActions();
×
1890

1891
            hideProgressDialog();
×
1892
        }
×
1893
    }
1894

1895
    public class SaveServiceTask extends AsyncTask<ServiceWrapper, Void, Triple<ArrayList<ServiceWrapper>,
×
1896
            List<ServiceRecord>, List<Alert>>> {
1897

1898
        private View view;
1899
        private String providerId;
1900
        private String locationId;
1901
        private String team;
1902
        private String teamId;
1903
        private String childLocationId;
1904

1905
        public void setView(View view) {
1906
            this.view = view;
×
1907
        }
×
1908

1909
        public void setProviderId(String providerId) {
1910
            this.providerId = providerId;
×
1911
        }
×
1912

1913
        public void setLocationId(String locationId) {
1914
            this.locationId = locationId;
×
1915
        }
×
1916

1917
        public void setChildLocationId(String childLocationId) {
1918
            this.childLocationId = childLocationId;
×
1919
        }
×
1920

1921
        public void setTeamId(String teamId) {
1922
            this.teamId = teamId;
×
1923
        }
×
1924

1925
        public void setTeam(String team) {
1926
            this.team = team;
×
1927
        }
×
1928

1929
        @Override
1930
        protected Triple<ArrayList<ServiceWrapper>, List<ServiceRecord>, List<Alert>> doInBackground(
1931
                ServiceWrapper... params) {
1932

1933
            ArrayList<ServiceWrapper> list = new ArrayList<>();
×
1934

1935
            for (ServiceWrapper tag : params) {
×
1936
                RecurringServiceUtils.saveService(tag, childDetails.entityId(), providerId, locationId,
×
1937
                        team, teamId, childLocationId);
1938
                setLastModified(true);
×
1939
                list.add(tag);
×
1940

1941
                ServiceSchedule.updateOfflineAlerts(tag.getType(), childDetails.entityId(), Utils.dobToDateTime(childDetails));
×
1942
            }
1943

1944
            List<ServiceRecord> serviceRecordList = ImmunizationLibrary.getInstance().recurringServiceRecordRepository()
×
1945
                    .findByEntityId(childDetails.entityId());
×
1946

1947
            AlertService alertService = getOpenSRPContext().alertService();
×
1948
            List<Alert> alertList = alertService.findByEntityId(childDetails.entityId());
×
1949

1950
            Utils.postEvent(new ClientDirtyFlagEvent(childDetails.entityId(), RecurringIntentService.EVENT_TYPE));
×
1951

1952
            return Triple.of(list, serviceRecordList, alertList);
×
1953

1954
        }
1955

1956
        @Override
1957
        protected void onPreExecute() {
1958
            showProgressDialog();
×
1959
        }
×
1960

1961
        @Override
1962
        protected void onPostExecute(Triple<ArrayList<ServiceWrapper>, List<ServiceRecord>, List<Alert>> triple) {
1963
            hideProgressDialog();
×
1964
            RecurringServiceUtils.updateServiceGroupViews(view, triple.getLeft(), triple.getMiddle(), triple.getRight());
×
1965
        }
×
1966
    }
1967

1968
    private class UndoServiceTask extends AsyncTask<Void, Void, Void> {
1969

1970
        private final View view;
1971
        private final ServiceWrapper tag;
1972
        private List<ServiceRecord> serviceRecordList;
1973
        private ArrayList<ServiceWrapper> wrappers;
1974
        private List<Alert> alertList;
1975

1976
        public UndoServiceTask(ServiceWrapper tag) {
×
1977
            this.tag = tag;
×
1978
            this.view = RecurringServiceUtils.getLastOpenedServiceView(serviceGroups);
×
1979
        }
×
1980

1981
        @Override
1982
        protected Void doInBackground(Void... params) {
1983
            if (tag != null && tag.getDbKey() != null) {
×
1984
                Long dbKey = tag.getDbKey();
×
1985
                ImmunizationLibrary.getInstance().recurringServiceRecordRepository().deleteServiceRecord(dbKey);
×
1986

1987
                serviceRecordList = ImmunizationLibrary.getInstance().recurringServiceRecordRepository().findByEntityId(childDetails.entityId());
×
1988

1989
                wrappers = new ArrayList<>();
×
1990
                wrappers.add(tag);
×
1991

1992
                ServiceSchedule.updateOfflineAlerts(tag.getType(), childDetails.entityId(), Utils.dobToDateTime(childDetails));
×
1993

1994
                AlertService alertService = getOpenSRPContext().alertService();
×
1995
                alertList = alertService.findByEntityId(childDetails.entityId());
×
1996

1997
            }
1998
            return null;
×
1999
        }
2000

2001
        @Override
2002
        protected void onPreExecute() {
2003
            showProgressDialog(getString(R.string.updating_dialog_title), null);
×
2004
        }
×
2005

2006
        @Override
2007
        protected void onPostExecute(Void params) {
2008
            super.onPostExecute(params);
×
2009
            hideProgressDialog();
×
2010

2011
            tag.setUpdatedVaccineDate(null, false);
×
2012
            tag.setDbKey(null);
×
2013

2014
            RecurringServiceUtils.updateServiceGroupViews(view, wrappers, serviceRecordList, alertList, true);
×
2015
        }
×
2016
    }
2017

2018
    private class SaveVaccinesTask extends AsyncTask<VaccineWrapper, Void, List<VaccineWrapper>> {
×
2019

2020
        private View view;
2021
        private VaccineRepository vaccineRepository;
2022
        private AlertService alertService;
2023
        private List<String> affectedVaccines;
2024
        private List<Vaccine> vaccineList;
2025
        private List<Alert> alertList;
2026

2027
        public void setView(View view) {
2028
            getSupportFragmentManager();
×
2029
            this.view = view;
×
2030
        }
×
2031

2032
        public void setVaccineRepository(VaccineRepository vaccineRepository) {
2033
            this.vaccineRepository = vaccineRepository;
×
2034
            alertService = getOpenSRPContext().alertService();
×
2035
            affectedVaccines = new ArrayList<>();
×
2036
        }
×
2037

2038
        @Override
2039
        protected List<VaccineWrapper> doInBackground(VaccineWrapper... vaccineWrappers) {
2040

2041
            ArrayList<VaccineWrapper> list = new ArrayList<>();
×
2042
            if (vaccineRepository != null) {
×
2043
                for (VaccineWrapper tag : vaccineWrappers) {
×
2044
                    saveVaccine(vaccineRepository, tag);
×
2045
                    list.add(tag);
×
2046
                }
2047
            }
2048

2049
            String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
2050
            DateTime dateTime = Utils.dobStringToDateTime(dobString);
×
2051
            if (dateTime != null) {
×
2052
                affectedVaccines = VaccineSchedule.updateOfflineAlertsAndReturnAffectedVaccineNames(childDetails.entityId(), dateTime, Constants.KEY.CHILD);
×
2053
            }
2054
            vaccineList = vaccineRepository.findByEntityId(childDetails.entityId());
×
2055
            alertList = alertService.findByEntityId(childDetails.entityId());
×
2056

2057
            //Schedule stuff if we support the next appointment event
2058

2059
            if (ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.NEXT_APPOINTMENT_EVENT_ENABLED)) {
×
2060

2061
                Map<String, Date> receivedVaccines = receivedVaccines(vaccineList);
×
2062
                List<Map<String, Object>> generatedScheduleList = VaccinatorUtils.generateScheduleList(Constants.KEY.CHILD, dateTime, receivedVaccines, alertList);
×
2063

2064
                Vaccine previousVaccineGiven = null;
×
2065
                Date lastVaccineDate = null;
×
2066
                if (!vaccineList.isEmpty()) {
×
2067
                    previousVaccineGiven = vaccineList.get(vaccineList.size() - 1);
×
2068
                    lastVaccineDate = previousVaccineGiven.getDate();
×
2069
                }
2070

2071
                Map<String, Object> nextVaccineMap = VaccinatorUtils.nextVaccineDue(generatedScheduleList, lastVaccineDate);
×
2072
                Alert nextVaccineAlert = nextVaccineMap != null ? ((Alert) nextVaccineMap.get(Constants.KEY.ALERT)) : null;
×
2073

2074
                List<Observation> observationList = new ArrayList<>();
×
2075

2076
                if (previousVaccineGiven != null) {
×
2077
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.TREATMENT_PROVIDED, previousVaccineGiven.getName().toUpperCase(), Observation.TYPE.TEXT));
×
2078
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.IS_OUT_OF_CATCHMENT, String.valueOf(previousVaccineGiven.getOutOfCatchment() == 1), Observation.TYPE.TEXT));
×
2079
                }
2080
                if (nextVaccineAlert != null) {
×
2081
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.NEXT_APPOINTMENT_DATE, nextVaccineAlert.startDate(), Observation.TYPE.DATE));
×
2082
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.NEXT_SERVICE_EXPECTED, nextVaccineAlert.scheduleName(), Observation.TYPE.TEXT));
×
2083
                }
2084

2085
                processNextVaccineDate(childDetails.entityId(), observationList);
×
2086
            }
2087

2088
            return list;
×
2089
        }
2090

2091
        @Override
2092
        protected void onPreExecute() {
2093
            showProgressDialog();
×
2094
        }
×
2095

2096
        @Override
2097
        protected void onPostExecute(List<VaccineWrapper> list) {
2098
            hideProgressDialog();
×
2099
            updateVaccineGroupViews(view, list, vaccineList);
×
2100
            WeightWrapper weightWrapper = (WeightWrapper) recordGrowth.getTag(R.id.weight_wrapper);
×
2101
            if ((ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED) &&
×
2102
                    ChildLibrary.getInstance().getProperties()
×
2103
                            .getPropertyBoolean(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED)) &&
×
2104
                    (weightWrapper == null || weightWrapper.getWeight() == null)) {
×
2105
                showRecordWeightNotification();
×
2106
            }
2107

2108
            updateVaccineGroupsUsingAlerts(affectedVaccines, vaccineList, alertList);
×
2109
            showVaccineNotifications(vaccineList, alertList);
×
2110
        }
×
2111
    }
2112

2113
    public void processNextVaccineDate(String baseEntityId, List<Observation> observationList) {
2114
        try {
2115

2116
            List<EventClient> eventClients = ChildLibrary.getInstance().eventClientRepository().getEventsByBaseEntityIdsAndSyncStatus(BaseRepository.TYPE_Unprocessed, Collections.singletonList(baseEntityId));
×
2117

2118
            String formSubmissionId = null;
×
2119

2120
            for (EventClient eventClient : eventClients) {
×
2121
                if (Constants.EventType.NEXT_APPOINTMENT.equalsIgnoreCase(eventClient.getEvent().getEventType())) {
×
2122

2123
                    formSubmissionId = eventClient.getEvent().getFormSubmissionId();
×
2124

2125
                    break;
×
2126
                }
2127
            }
×
2128

2129
            Event nextVaccineDateEvent = ChildJsonFormUtils.createNextAppointmentEvent(baseEntityId, observationList, formSubmissionId);
×
2130
            ChildJsonFormUtils.convertAndPersistEvent(nextVaccineDateEvent);
×
2131

2132
        } catch (JSONException e) {
×
2133
            Timber.e(e);
×
2134
        }
×
2135
    }
×
2136

2137
    protected void updateFloatingActionButtonBasedOnChildStatus() {
2138
        if (ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.FEATURE_NFC_CARD_ENABLED)) {
1✔
2139
            if (!Utils.hasCompassRelationshipId(childDetails.getColumnmaps())) {
1✔
2140
                configureFloatingActionBackground(R.drawable.pill_background_unregistered, getResources().getString(R.string.enroll_caregiver));
1✔
2141
            } else {
2142
                if (!Utils.isChildHasNFCCard(childDetails.getColumnmaps())) {
1✔
2143
                    configureFloatingActionBackground(R.drawable.pill_background_unregistered, getResources().getString(R.string.activate_new_card));
1✔
2144
                } else {
2145
                    configureFloatingActionBackground(getGenderButtonColor(childDetails.getColumnmaps().get(Constants.KEY.GENDER)), getResources().getString(R.string.write_to_card));
1✔
2146
                }
2147
            }
2148
        }
2149
    }
1✔
2150
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc