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

OpenSRP / opensrp-client-child / #798

pending completion
#798

Pull #302

github-actions

web-flow
Merge 67ae6b5c4 into c099d4f8b
Pull Request #302: Migrate core to 6 - Memory Leak Fixes

4929 of 9038 relevant lines covered (54.54%)

0.55 hits per line

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

33.45
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.RegisterClickables;
48
import org.smartregister.child.event.ClientDirtyFlagEvent;
49
import org.smartregister.child.presenter.BaseChildImmunizationPresenter;
50
import org.smartregister.child.task.GetSiblingsTask;
51
import org.smartregister.child.task.SaveChildStatusTask;
52
import org.smartregister.child.task.ShowGrowthChartTask;
53
import org.smartregister.child.task.UndoVaccineTask;
54
import org.smartregister.child.toolbar.LocationSwitcherToolbar;
55
import org.smartregister.child.util.AsyncTaskUtils;
56
import org.smartregister.child.util.ChildAppProperties;
57
import org.smartregister.child.util.ChildDbUtils;
58
import org.smartregister.child.util.ChildJsonFormUtils;
59
import org.smartregister.child.util.Constants;
60
import org.smartregister.child.util.DBConstants;
61
import org.smartregister.child.util.Utils;
62
import org.smartregister.child.view.BCGNotificationDialog;
63
import org.smartregister.child.view.SiblingPicturesGroup;
64
import org.smartregister.clientandeventmodel.Event;
65
import org.smartregister.commonregistry.CommonPersonObjectClient;
66
import org.smartregister.domain.Alert;
67
import org.smartregister.domain.Observation;
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
    public static final String DIALOG_TAG = "ChildImmunoActivity_DIALOG_TAG";
140
    private static final int RANDOM_MAX_RANGE = 4232;
141
    private static final int RANDOM_MIN_RANGE = 213;
142
    private static final int RECORD_WEIGHT_BUTTON_ACTIVE_MIN = 12;
143
    private static Boolean monitorGrowth = false;
1✔
144
    protected LinearLayout floatingActionButton;
145
    // Data
146
    protected RegisterClickables registerClickables;
147
    private boolean recurringServiceEnabled;
148
    private ArrayList<VaccineGroup> vaccineGroups;
149
    private ArrayList<ServiceGroup> serviceGroups;
150
    private boolean bcgScarNotificationShown;
151
    private boolean weightNotificationShown;
152
    // Views
153
    private LocationSwitcherToolbar toolbar;
154
    private boolean dialogOpen = false;
1✔
155
    private boolean isGrowthEdit = false;
1✔
156
    private boolean isChildActive = false;
1✔
157
    private View recordGrowth;
158
    private TextView recordWeightText;
159
    private ImageView profileImageIV;
160
    private TextView childSiblingsTV;
161
    private ImageView recordWeightCheck;
162
    private TextView dobTV;
163
    private TextView ageTV;
164
    private TextView nameTV;
165
    private TextView childIdTV;
166
    private TextView systemOfRegistrationTV;
167
    private LinearLayout vaccineGroupCanvasLL;
168
    private LinearLayout profileNamelayout;
169
    private LinearLayout serviceGroupCanvasLL;
170
    private LinearLayout someLayout;
171
    private CustomFontTextView nextAppointmentDateView;
172
    private ImageButton growthChartButton;
173
    private SiblingPicturesGroup siblingPicturesGroup;
174
    private ChildImmunizationContract.Presenter presenter;
175

176
    public static void launchActivity(Context fromContext, CommonPersonObjectClient childDetails, RegisterClickables registerClickables) {
177
        launchActivity(fromContext, childDetails, registerClickables, Utils.metadata().childImmunizationActivity);
×
178
    }
×
179

180
    /**
181
     * Helper method to launch the Base Child Immunization Activity from anywhere
182
     *
183
     * @param fromContext               - current context , 1st parameter to Intent
184
     * @param childDetails              - the map with the client details
185
     * @param registerClickables        - serializable class with the click handler parameters
186
     * @param activityClassToNavigateTo - the activity to navigate to (2nd Parameter to Intent object)
187
     */
188
    protected static void launchActivity(Context fromContext, CommonPersonObjectClient childDetails, RegisterClickables registerClickables, Class<?> activityClassToNavigateTo) {
189
        Intent intent = new Intent(fromContext, activityClassToNavigateTo);
1✔
190
        Bundle bundle = new Bundle();
1✔
191
        bundle.putSerializable(Constants.INTENT_KEY.BASE_ENTITY_ID, childDetails.getCaseId());
1✔
192
        bundle.putSerializable(Constants.INTENT_KEY.EXTRA_REGISTER_CLICKABLES, registerClickables);
1✔
193

194
        // load the child details
195
        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✔
196
            bundle.putSerializable(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS, childDetails);
×
197
        }
198

199
        bundle.putSerializable(Constants.INTENT_KEY.NEXT_APPOINTMENT_DATE,
1✔
200
                registerClickables != null && !TextUtils.isEmpty(registerClickables.getNextAppointmentDate()) ?
1✔
201
                        registerClickables.getNextAppointmentDate() : "");
1✔
202
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
1✔
203
        intent.putExtras(bundle);
1✔
204

205
        fromContext.startActivity(intent);
1✔
206
    }
1✔
207

208
    public static Object clone(@NonNull Object object) {
209

210
        Gson gson = new Gson();
×
211
        String serializedObject = gson.toJson(object);
×
212

213
        return gson.fromJson(serializedObject, object.getClass());
×
214
    }
215

216
    @Override
217
    protected void onCreate(Bundle savedInstanceState) {
218
        super.onCreate(savedInstanceState);
1✔
219

220
        monitorGrowth = ChildLibrary.getInstance().getProperties().isTrue(org.smartregister.growthmonitoring.util.AppProperties.KEY.MONITOR_GROWTH);
1✔
221
        recurringServiceEnabled = Boolean.parseBoolean(ChildLibrary.getInstance().getProperties().getProperty(ChildAppProperties.KEY.FEATURE_RECURRING_SERVICE_ENABLED, "true"));
1✔
222

223
        presenter = new BaseChildImmunizationPresenter(this);
1✔
224

225
        setUpToolbar();
1✔
226
        setUpViews();
1✔
227

228
        // Get child details from bundled data
229
        Bundle extras = this.getIntent().getExtras();
1✔
230
        if (extras != null) {
1✔
231
            String caseId = extras.getString(Constants.INTENT_KEY.BASE_ENTITY_ID);
1✔
232
            childDetails = getChildDetails(caseId);
1✔
233

234
            CommonPersonObjectClient cardChildDetails = null;
1✔
235
            if (extras.containsKey(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS) && childDetails == null) {
1✔
236
                cardChildDetails = (CommonPersonObjectClient) extras.get(Constants.INTENT_KEY.EXTRA_CHILD_DETAILS);
×
237
            }
238

239
            if (childDetails == null) {
1✔
240
                childDetails = cardChildDetails;
×
241
            } else {
242
                if (cardChildDetails != null) {
1✔
243
                    // card last update
244
                    String cardTxDateTime = cardChildDetails.getColumnmaps().getOrDefault(Constants.KEY.NFC_LAST_PROCESSED_TIMESTAMP, "0");
×
245
                    long lastCardTxDateTime = Long.parseLong(cardTxDateTime != null ? cardTxDateTime : "0");
×
246
                    // device last update
247
                    String lastDeviceInteraction = childDetails.getColumnmaps().getOrDefault(Constants.KEY.LAST_INTERACTED_WITH, "0");
×
248
                    long lastInteractedWith = Long.parseLong(lastDeviceInteraction != null ? lastDeviceInteraction : "0");
×
249

250
                    if (lastCardTxDateTime > lastInteractedWith) {
×
251
                        childDetails = cardChildDetails;
×
252
                    }
253
                }
254
            }
255
        }
256

257
        Serializable serializable = extras.getSerializable(Constants.INTENT_KEY.EXTRA_REGISTER_CLICKABLES);
1✔
258
        if (serializable != null && serializable instanceof RegisterClickables) {
1✔
259
            registerClickables = (RegisterClickables) serializable;
1✔
260
        }
261

262
        bcgScarNotificationShown =
1✔
263
                ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.NOTIFICATIONS_BCG_ENABLED) &&
1✔
264
                        !ChildLibrary.getInstance().getProperties()
1✔
265
                                .getPropertyBoolean(ChildAppProperties.KEY.NOTIFICATIONS_BCG_ENABLED);
×
266
        weightNotificationShown = false;
1✔
267
//        ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED)
268
//                ? ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED)
269
//                : false;
270

271
        setLastModified(false);
1✔
272

273
        setUpFloatingActionButton();
1✔
274
        Utils.refreshDataCaptureStrategyBanner(this, getOpenSRPContext().allSharedPreferences().fetchCurrentLocality());
1✔
275
    }
1✔
276

277
    @VisibleForTesting
278
    protected CommonPersonObjectClient getChildDetails(String caseId) {
279
        return ChildDbUtils.fetchCommonPersonObjectClientByBaseEntityId(caseId);
×
280
    }
281

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

303
    private void setUpToolbar() {
304
        if (getSupportActionBar() != null) {
1✔
305
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
1✔
306
        }
307

308
        toolbar = (LocationSwitcherToolbar) getToolbar();
1✔
309
        toolbar.setNavigationOnClickListener(v -> goToRegisterPage());
1✔
310
        toolbar.setOnLocationChangeListener(this);
1✔
311
        toolbar.init(this);
1✔
312
    }
1✔
313

314
    private void setUpFloatingActionButton() {
315

316
        if (ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.FEATURE_NFC_CARD_ENABLED)) {
1✔
317

318
            floatingActionButton.setOnClickListener(this);
1✔
319

320
            configureFloatingActionBackground(getGenderButtonColor(childDetails.getColumnmaps().get(Constants.KEY.GENDER)),
1✔
321
                    null);
322

323
            someLayout.setPadding(someLayout.getPaddingLeft(), someLayout.getPaddingTop(), someLayout.getPaddingRight(),
1✔
324
                    someLayout.getPaddingBottom() + 80);
1✔
325
        }
326
    }
1✔
327

328
    public LinearLayout getServiceGroupCanvasLL() {
329
        return serviceGroupCanvasLL;
×
330
    }
331

332

333
    protected abstract void goToRegisterPage();
334

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

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

358
        if (title != null) {
1✔
359
            fabText.setText(title);
×
360
        }
361

362
        floatingActionButton.setVisibility(View.VISIBLE);
1✔
363
    }
1✔
364

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

381
        return imageResource;
1✔
382
    }
383

384
    @Override
385
    protected int getContentView() {
386
        return R.layout.activity_child_immunization;
1✔
387
    }
388

389
    @Override
390
    protected int getToolbarId() {
391
        return LocationSwitcherToolbar.TOOLBAR_ID;
1✔
392
    }
393

394
    @Override
395
    protected abstract int getDrawerLayoutId();//Navigation drawer ID ?
396

397
    @Override
398
    protected int[] updateGenderViews(Gender gender) {
399
        int[] selectedColor = super.updateGenderViews(gender);
×
400

401
        String identifier = getString(R.string.neutral_sex_id);
×
402
        int toolbarResource = R.drawable.vertical_separator_neutral;
×
403
        if (gender.equals(Gender.FEMALE)) {
×
404
            toolbarResource = R.drawable.vertical_separator_female;
×
405
            identifier = getString(R.string.female_sex_id);
×
406
        } else if (gender.equals(Gender.MALE)) {
×
407
            toolbarResource = R.drawable.vertical_separator_male;
×
408
            identifier = getString(R.string.male_sex_id);
×
409
        }
410

411
        if (Locale.getDefault().toString().equalsIgnoreCase("ar") || Locale.getDefault().toString().equalsIgnoreCase("fr")) {
×
412
            identifier = "";
×
413
        }
414
        toolbar.updateSeparatorView(toolbarResource);
×
415
        childSiblingsTV.setText(String.format(getString(R.string.child_siblings), identifier).toUpperCase());
×
416

417
        updateProfilePicture(gender);
×
418
        return selectedColor;
×
419
    }
420

421
    @Override
422
    protected void onResume() {
423
        super.onResume();
×
424
        if (vaccineGroups != null) {
×
425
            vaccineGroupCanvasLL.removeAllViews();
×
426
            vaccineGroups = null;
×
427
        }
428

429
        if (serviceGroups != null) {
×
430
            serviceGroupCanvasLL.removeAllViews();
×
431
            serviceGroups = null;
×
432
        }
433

434
        updateViews();
×
435

436
        if (!recurringServiceEnabled) {
×
437
            getServiceGroupCanvasLL().setVisibility(View.GONE);
×
438
        }
439
    }
×
440

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

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

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

457
        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✔
458
            CommonPersonObjectClient objectClient = ChildDbUtils.fetchCommonPersonObjectClientByBaseEntityId(childDetails.getColumnmaps().get(DBConstants.KEY.BASE_ENTITY_ID));
×
459
            if (objectClient != null) {
×
460
                childDetails = objectClient;
×
461
            } else {
462
                Timber.e("fetchCommonPersonObjectClientByBaseEntityId is null, child record is not n the database.");
×
463
            }
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
    }
1✔
483

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

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

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

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

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

507
    protected abstract Activity getActivity();
508

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

514
    @VisibleForTesting
515
    protected void updateGenderViews() {
516
        Gender gender = isDataOk() ? Utils.getGenderEnum(childDetails.getColumnmaps()) : Gender.UNKNOWN;
×
517

518
        int[] colors = updateGenderViews(gender);
×
519
        int normalShade = colors[1];
×
520
        findViewById(R.id.advanced_data_capture_strategy_wrapper).setBackground(new ColorDrawable(getResources().getColor(normalShade)));
×
521
    }
×
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 ):
×
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());
×
583
            DrishtiApplication.getCachedImageLoaderInstance().getImageByClientId(childDetails.entityId(),
×
584
                    OpenSRPImageLoader
585
                            .getStaticImageListener(profileImageIV, ImageUtils.profileImageResourceByGender(gender),
×
586
                                    ImageUtils.profileImageResourceByGender(gender)));
×
587

588
        }
589
    }
×
590

591
    @Override
592
    protected Class onBackActivity() {
593
        return BaseChildRegisterActivity.class;
×
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(getProviderLocationId());
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
    @VisibleForTesting
952
    protected String getProviderLocationId() {
953
        return ChildJsonFormUtils.getProviderLocationId(this);
×
954
    }
955

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

967
            dialogOpen = true;
×
968
            if (isChildActive) {
×
969
                addVaccinationDialogFragment(dueVaccines, vaccineGroup);
×
970
            } else {
971
                showActivateChildStatusDialogBox();
×
972
            }
973
        });
×
974
        curGroup.setOnVaccineClickedListener((vaccineGroup, vaccine) -> {
×
975
            if (dialogOpen) {
×
976
                return;
×
977
            }
978

979
            dialogOpen = true;
×
980
            if (isChildActive) {
×
981
                ArrayList<VaccineWrapper> vaccineWrappers = new ArrayList<>();
×
982
                vaccineWrappers.add(vaccine);
×
983
                addVaccinationDialogFragment(vaccineWrappers, vaccineGroup);
×
984
            } else {
×
985
                showActivateChildStatusDialogBox();
×
986
            }
987
        });
×
988
        curGroup.setOnVaccineUndoClickListener((vaccineGroup, vaccine) -> {
×
989
            if (dialogOpen) {
×
990
                return;
×
991
            }
992

993
            dialogOpen = true;
×
994
            if (isChildActive) {
×
995
                addVaccineUndoDialogFragment(vaccineGroup, vaccine);
×
996
            } else {
997
                showActivateChildStatusDialogBox();
×
998
            }
999
        });
×
1000

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

1019
    @Override
1020
    public void showVaccineNotifications(List<Vaccine> vaccineList, List<Alert> alerts) {
1021

1022
        Map<String, String> details = childDetails.getDetails();
1✔
1023

1024
        if (details.get(Constants.SHOW_BCG2_REMINDER) != null || details.get(Constants.SHOW_BCG_SCAR) != null) {
1✔
1025
            return;
1✔
1026
        }
1027

1028
        // This fixes the possibility of multiple popups
1029
        if (registerClickables != null && (registerClickables.isRecordAll()
1✔
1030
                || registerClickables.isRecordWeight())) {
1✔
1031
            return;
×
1032
        }
1033

1034
        if (VaccinateActionUtils.hasVaccine(vaccineList, VaccineRepo.Vaccine.bcg2)) {
1✔
1035
            return;
1✔
1036
        }
1037

1038
        Vaccine bcg = VaccinateActionUtils.getVaccine(vaccineList, VaccineRepo.Vaccine.bcg);
1✔
1039
        if (bcg == null) {
1✔
1040
            return;
1✔
1041
        }
1042

1043
        Alert alert = VaccinateActionUtils.getAlert(alerts, VaccineRepo.Vaccine.bcg2);
1✔
1044
        if (alert == null || alert.isComplete()) {
1✔
1045
            return;
1✔
1046
        }
1047

1048
        /*int bcgOffsetInWeeks = 12;
1049
        Calendar twelveWeeksLaterDate = Calendar.getInstance();
1050
        twelveWeeksLaterDate.setTime(bcg.getDate());
1051
        twelveWeeksLaterDate.add(Calendar.WEEK_OF_YEAR, bcgOffsetInWeeks);
1052

1053
        Calendar today = Calendar.getInstance();
1054

1055
        if (today.getTime().after(twelveWeeksLaterDate.getTime()) || DateUtils.isSameDay(twelveWeeksLaterDate, today)) {
1056
            showCheckBcgScarNotification(alert);
1057
        }*/
1058

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

1061

1062
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
1✔
1063
        Date dob = Utils.dobStringToDate(dobString);
1✔
1064

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

1073
                break;
1074
            }
1075
        }
×
1076
    }
1✔
1077

1078
    @VisibleForTesting
1079
    protected boolean isVaccineDue(@NonNull List<Vaccine> vaccineList, @NonNull Date dob, @NonNull org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine, boolean allowedExpiredVaccineEntry) {
1080
        return Utils.isVaccineDue(vaccineList, dob, vaccine, allowedExpiredVaccineEntry);
×
1081
    }
1082

1083
    private void addVaccinationDialogFragment(ArrayList<VaccineWrapper> vaccineWrappers, VaccineGroup vaccineGroup) {
1084
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
×
1085
        Fragment prev = this.getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
1086
        if (prev != null) {
×
1087
            return;
×
1088
        }
1089
        ft.addToBackStack(null);
×
1090

1091
        vaccineGroup.setModalOpen(true);
×
1092
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1093
        Date dob = Utils.dobStringToDate(dobString);
×
1094
        if (dob == null) {
×
1095
            dob = Calendar.getInstance().getTime();
×
1096
        }
1097

1098
        List<Vaccine> vaccineList =
1099
                ImmunizationLibrary.getInstance().vaccineRepository().findByEntityId(childDetails.entityId());
×
1100
        if (vaccineList == null) {
×
1101
            vaccineList = new ArrayList<>();
×
1102
        }
1103

1104
        VaccinationDialogFragment vaccinationDialogFragment =
×
1105
                VaccinationDialogFragment.newInstance(dob, vaccineList, vaccineWrappers, true);
×
1106
        vaccinationDialogFragment.show(ft, DIALOG_TAG);
×
1107
        vaccinationDialogFragment.setOnDismissListener(dialog -> dialogOpen = false);
×
1108

1109
    }
×
1110

1111
    private void addVaccineUndoDialogFragment(VaccineGroup vaccineGroup, VaccineWrapper vaccineWrapper) {
1112
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
×
1113
        Fragment prev = getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
1114
        if (prev != null) {
×
1115
            return;
×
1116
        }
1117
        fragmentTransaction.addToBackStack(null);
×
1118

1119
        vaccineGroup.setModalOpen(true);
×
1120

1121
        UndoVaccinationDialogFragment undoVaccinationDialogFragment = UndoVaccinationDialogFragment.newInstance(vaccineWrapper);
×
1122
        undoVaccinationDialogFragment.show(fragmentTransaction, DIALOG_TAG);
×
1123
        undoVaccinationDialogFragment.setOnDismissListener(dialog -> dialogOpen = false);
×
1124
    }
×
1125

1126
    private void showCheckBcgScarNotification() {
1127
        if (!bcgScarNotificationShown) {
1✔
1128
            bcgScarNotificationShown = true;
1✔
1129
            final ViewGroup rootView = (ViewGroup) ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
1✔
1130

1131
            new BCGNotificationDialog(this, (dialog, which) -> {
1✔
1132
                onBcgReminderOptionSelected(Constants.SHOW_BCG_SCAR);
×
1133
                Snackbar.make(rootView, R.string.turn_off_reminder_notification_message, Snackbar.LENGTH_LONG).show();
×
1134
            }, (dialog, which) -> {
×
1135
                onBcgReminderOptionSelected(Constants.SHOW_BCG2_REMINDER);
×
1136
                Snackbar.make(rootView, R.string.create_reminder_notification_message, Snackbar.LENGTH_LONG).show();
×
1137
            }).show();
1✔
1138
        }
1139
    }
1✔
1140

1141
    public void onBcgReminderOptionSelected(String option) {
1142
        final long DATE = new Date().getTime();
×
1143
        switch (option) {
×
1144
            case Constants.SHOW_BCG2_REMINDER:
1145
                ChildDbUtils.updateChildDetailsValue(Constants.SHOW_BCG2_REMINDER, Boolean.TRUE.toString(), childDetails.entityId());
×
1146
                break;
×
1147

1148
            case Constants.SHOW_BCG_SCAR:
1149
                ChildDbUtils.updateChildDetailsValue(Constants.SHOW_BCG_SCAR, String.valueOf(DATE), childDetails.entityId());
×
1150
                String providerId = getOpenSRPContext().allSharedPreferences().fetchRegisteredANM();
×
1151
                String locationId = Utils.context().allSharedPreferences().getPreference(AllConstants.CURRENT_LOCATION_ID);
×
1152
                ChildJsonFormUtils.createBCGScarEvent(getActivity(), childDetails.entityId(), providerId, locationId);
×
1153
                break;
×
1154

1155
            default:
1156
                break;
1157
        }
1158

1159
        vaccineGroupCanvasLL.removeAllViews();
×
1160
        vaccineGroups = null;
×
1161
        updateViews();
×
1162
    }
×
1163

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

1172
        String openSrpId = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.ZEIR_ID, false);
1✔
1173
        String duration = "";
1✔
1174
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
1✔
1175
        DateTime dateTime = Utils.dobStringToDateTime(dobString);
1✔
1176
        if (dateTime != null) {
1✔
1177
            duration = DateUtil.getDuration(dateTime);
1✔
1178
        }
1179

1180
        Photo photo = getProfilePhotoByClient(childDetails);
1✔
1181

1182
        WeightWrapper weightWrapper = getWeightWrapper(lastUnsyncedWeight, childName, gender, openSrpId, duration, photo);
1✔
1183
        if (weightWrapper != null) {
1✔
1184
            weightWrapper.setDob(dobString);
1✔
1185
        }
1186

1187
        HeightWrapper heightWrapper = null;
1✔
1188
        if (monitorGrowth) {
1✔
1189
            heightWrapper = getHeightWrapper(lastUnsyncedHeight, childName, gender, openSrpId, duration, photo);
1✔
1190
            heightWrapper.setDob(dobString);
1✔
1191
        }
1192
        updateRecordGrowthMonitoringViews(weightWrapper, heightWrapper, isActive);
1✔
1193

1194
        growthChartButton.setOnClickListener(v -> Utils.startAsyncTask(new ShowGrowthChartTask(presenter, childDetails), null));
1✔
1195
    }
1✔
1196

1197
    @VisibleForTesting
1198
    protected Photo getProfilePhotoByClient(CommonPersonObjectClient childDetails) {
1199
        return ImageUtils.profilePhotoByClient(childDetails);
×
1200
    }
1201

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

1214
        if (lastUnsyncedWeight != null) {
1✔
1215
            weightWrapper.setWeight(lastUnsyncedWeight.getKg());
1✔
1216
            weightWrapper.setDbKey(lastUnsyncedWeight.getId());
1✔
1217
            weightWrapper.setUpdatedWeightDate(new DateTime(lastUnsyncedWeight.getDate()), false);
1✔
1218
        }
1219
        return weightWrapper;
1✔
1220
    }
1221

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

1234
        if (lastUnsyncedHeight != null) {
1✔
1235
            heightWrapper.setHeight(lastUnsyncedHeight.getCm());
1✔
1236
            heightWrapper.setDbKey(lastUnsyncedHeight.getId());
1✔
1237
            heightWrapper.setUpdatedHeightDate(new DateTime(lastUnsyncedHeight.getDate()), false);
1✔
1238
        }
1239
        return heightWrapper;
1✔
1240
    }
1241

1242
    @VisibleForTesting
1243
    protected void updateRecordGrowthMonitoringViews(WeightWrapper weightWrapper, HeightWrapper heightWrapper, final boolean isActive) {
1244

1245
        recordWeightText.setText(R.string.record_growth);
1✔
1246
        recordWeightText.setTextColor(!isActive ? getResources().getColor(R.color.inactive_text_color) : getResources().getColor(R.color.text_black));
1✔
1247
        recordWeightCheck.setVisibility(View.GONE);
1✔
1248

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

1251
        if (weightWrapper != null) {
1✔
1252
            updateWeightWrapper(weightWrapper, recordGrowth, recordWeightText, recordWeightCheck);
1✔
1253
        }
1254

1255
        if (monitorGrowth) {
1✔
1256
            updateHeightWrapper(heightWrapper, recordGrowth, recordWeightCheck);
1✔
1257
        }
1258

1259
        updateRecordWeightText(weightWrapper, heightWrapper);
1✔
1260
        updateRecordGrowth(weightWrapper, heightWrapper, isActive);
1✔
1261

1262
    }
1✔
1263

1264
    private void updateRecordWeightText(WeightWrapper weightWrapper, HeightWrapper heightWrapper) {
1265
        String weight = "";
1✔
1266
        String height = "";
1✔
1267
        if ((weightWrapper != null && weightWrapper.getDbKey() != null && weightWrapper.getWeight() != null) || (heightWrapper != null && heightWrapper.getDbKey() != null && heightWrapper.getHeight() != null)) {
1✔
1268
            if (weightWrapper != null && weightWrapper.getWeight() != null) {
1✔
1269
                weight = Utils.kgStringSuffix(weightWrapper.getWeight());
1✔
1270
            }
1271
            if (monitorGrowth && heightWrapper != null && heightWrapper.getHeight() != null) {
1✔
1272
                height = Utils.cmStringSuffix(heightWrapper.getHeight());
1✔
1273
            }
1274

1275
            isGrowthEdit = true;
1✔
1276
            if (monitorGrowth) {
1✔
1277
                recordWeightText.setText(getGrowthMonitoringValues(height, weight));
1✔
1278
            } else {
1279
                recordWeightText.setText(weight);
1✔
1280
            }
1281
        } else {
1282
            isGrowthEdit = false;
×
1283
        }
1284
    }
1✔
1285

1286
    private String getGrowthMonitoringValues(String height, String weight) {
1287
        String seperator = !TextUtils.isEmpty(height) && !TextUtils.isEmpty(weight) ? ", " : "";
1✔
1288
        return weight + seperator + height;
1✔
1289
    }
1290

1291
    private void updateRecordGrowth(WeightWrapper weightWrapper, HeightWrapper heightWrapper, final boolean isActive) {
1292
        recordGrowth.setClickable(true);
1✔
1293
        recordGrowth.setBackground(getResources().getDrawable(R.drawable.record_growth_bg));
1✔
1294
        recordGrowth.setTag(R.id.weight_wrapper, weightWrapper);
1✔
1295
        if (monitorGrowth) {
1✔
1296
            recordGrowth.setTag(R.id.height_wrapper, heightWrapper);
1✔
1297
        }
1298

1299
        recordGrowth.setTag(R.id.growth_edit_flag, isGrowthEdit);
1✔
1300
        recordGrowth.setOnClickListener(new View.OnClickListener() {
1✔
1301
            @Override
1302
            public void onClick(View view) {
1303
                if (isActive) {
×
1304
                    showGrowthDialog(view);
×
1305
                } else {
1306
                    showActivateChildStatusDialogBox();
×
1307
                }
1308
            }
×
1309
        });
1310
    }
1✔
1311

1312
    private void updateWeightWrapper(WeightWrapper weightWrapper, View recordGrowth, TextView recordWeightText, ImageView recordWeightCheck) {
1313
        if (weightWrapper != null && weightWrapper.getDbKey() != null && weightWrapper.getWeight() != null) {
1✔
1314
            recordWeightCheck.setVisibility(View.VISIBLE);
1✔
1315

1316
            if (weightWrapper.getUpdatedWeightDate() != null) {
1✔
1317
                long timeDiff = Calendar.getInstance().getTimeInMillis() - weightWrapper.getUpdatedWeightDate().getMillis();
1✔
1318

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

1332
                    // Reset the edit flag since this
1333
                    isGrowthEdit = false;
1✔
1334
                }
1335
            }
1336
        }
1337
    }
1✔
1338

1339
    private void updateHeightWrapper(HeightWrapper heightWrapper, View recordGrowth, ImageView recordWeightCheck) {
1340
        if (heightWrapper != null && heightWrapper.getDbKey() != null && heightWrapper.getHeight() != null) {
1✔
1341
            recordWeightCheck.setVisibility(View.VISIBLE);
1✔
1342

1343
            if (heightWrapper.getUpdatedHeightDate() != null) {
1✔
1344
                long timeDiff = Calendar.getInstance().getTimeInMillis() - heightWrapper.getUpdatedHeightDate().getMillis();
1✔
1345

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

1362
    private void showGrowthDialog(View view) {
1363
        FragmentTransaction fragmentTransaction = this.getSupportFragmentManager().beginTransaction();
×
1364
        Fragment prev = this.getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
×
1365
        if (prev != null) {
×
1366
            return;
×
1367
        }
1368
        fragmentTransaction.addToBackStack(null);
×
1369

1370
        showProgressDialog(getString(R.string.loading), getString(R.string.loading_form_message));
×
1371

1372
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1373
        Date dob = Utils.dobStringToDate(dobString);
×
1374
        if (dob == null) {
×
1375
            dob = Calendar.getInstance().getTime();
×
1376
        }
1377

1378
        WeightWrapper weightWrapper = (WeightWrapper) view.getTag(R.id.weight_wrapper);
×
1379
        HeightWrapper heightWrapper = null;
×
1380
        if (monitorGrowth) {
×
1381
            heightWrapper = (HeightWrapper) view.getTag(R.id.height_wrapper);
×
1382
        }
1383

1384
        boolean isGrowthEdit = (boolean) view.getTag(R.id.growth_edit_flag);
×
1385
        if (isGrowthEdit) {
×
1386
            EditGrowthDialogFragment editWeightDialogFragment = EditGrowthDialogFragment.newInstance(dob, weightWrapper, heightWrapper);
×
1387
            editWeightDialogFragment.show(fragmentTransaction, DIALOG_TAG);
×
1388
        } else {
×
1389
            RecordGrowthDialogFragment recordWeightDialogFragment = RecordGrowthDialogFragment.newInstance(dob, weightWrapper, heightWrapper);
×
1390
            recordWeightDialogFragment.show(fragmentTransaction, DIALOG_TAG);
×
1391
        }
1392

1393
        hideProgressDialog();
×
1394
    }
×
1395

1396
    @Override
1397
    public void onLocationChanged(final String newLocation) {
1398
        Utils.refreshDataCaptureStrategyBanner(this, newLocation);
×
1399
    }
×
1400

1401
    @Override
1402
    public void onGrowthRecorded(WeightWrapper weightWrapper, HeightWrapper heightWrapper) {
1403
        String genderString = Utils.getValue(childDetails, AllConstants.ChildRegistrationFields.GENDER, false);
×
1404
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1405

1406
        if (weightWrapper != null && weightWrapper.getUpdatedWeightDate() != null) {
×
1407
            weightWrapper.setGender(genderString);
×
1408
            weightWrapper.setDob(dobString);
×
1409
            Utils.recordWeight(GrowthMonitoringLibrary.getInstance().weightRepository(), weightWrapper, BaseRepository.TYPE_Unsynced);
×
1410
        }
1411

1412
        if (monitorGrowth && heightWrapper != null && heightWrapper.getUpdatedHeightDate() != null) {
×
1413
            heightWrapper.setGender(genderString);
×
1414
            heightWrapper.setDob(dobString);
×
1415
            Utils.recordHeight(GrowthMonitoringLibrary.getInstance().heightRepository(), heightWrapper, BaseRepository.TYPE_Unsynced);
×
1416
        }
1417

1418
        setLastModified(true);
×
1419
        startUpdateViewTask();
×
1420
    }
×
1421

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

1430
    @Override
1431
    public void onVaccinateEarlier(ArrayList<VaccineWrapper> tags, View v) {
1432
        if (tags != null && !tags.isEmpty()) {
×
1433
            View view = getLastOpenedView();
×
1434
            saveVaccine(tags, view);
×
1435
        }
1436
    }
×
1437

1438
    @Override
1439
    public void onUndoVaccination(VaccineWrapper tag, View view) {
1440

1441
        Utils.startAsyncTask(new UndoVaccineTask(presenter, tag, childDetails, getOpenSRPContext().alertService()), null);
×
1442
    }
×
1443

1444
    @Override
1445
    public VaccineGroup getLastOpenedView() {
1446
        if (vaccineGroups == null) {
×
1447
            return null;
×
1448
        }
1449

1450
        for (VaccineGroup vaccineGroup : vaccineGroups) {
×
1451
            if (vaccineGroup.isModalOpen()) {
×
1452
                return vaccineGroup;
×
1453
            }
1454
        }
×
1455

1456
        return null;
×
1457
    }
1458

1459
    private void saveVaccine(ArrayList<VaccineWrapper> tags, final View view) {
1460
        if (tags.isEmpty()) {
×
1461
            return;
×
1462
        }
1463

1464
        VaccineWrapper[] arrayTags = tags.toArray(new VaccineWrapper[tags.size()]);
×
1465
        SaveVaccinesTask backgroundTask = new SaveVaccinesTask();
×
1466
        backgroundTask.setVaccineRepository(ImmunizationLibrary.getInstance().vaccineRepository());
×
1467
        backgroundTask.setView(view);
×
1468
        Utils.startAsyncTask(backgroundTask, arrayTags);
×
1469

1470
    }
×
1471

1472
    private void performRegisterActions() {
1473
        if (registerClickables != null) {
×
1474
            if (registerClickables.isRecordWeight()) {
×
1475
                recordGrowth.post(new Runnable() {
×
1476
                    @Override
1477
                    public void run() {
1478
                        recordGrowth.performClick();
×
1479
                    }
×
1480
                });
1481
            } else if (registerClickables.isRecordAll()) {
×
1482
                performRecordAllClick(0);
×
1483
            }
1484

1485
            //Reset register actions
1486
            registerClickables.setRecordAll(false);
×
1487
            registerClickables.setRecordWeight(false);
×
1488
        }
1489
    }
×
1490

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

1511
    private void saveVaccine(VaccineRepository vaccineRepository, VaccineWrapper tag) {
1512
        if (tag.getUpdatedVaccineDate() == null) {
×
1513
            return;
×
1514
        }
1515

1516
        boolean isOutOfCatchmentVaccine = Constants.BOOLEAN_STRING.TRUE.equals(Utils.getValue(childDetails.getColumnmaps(), Constants.Client.IS_OUT_OF_CATCHMENT, false));
×
1517
        Vaccine vaccine = new Vaccine();
×
1518
        if (tag.getDbKey() != null) {
×
1519
            vaccine = vaccineRepository.find(tag.getDbKey());
×
1520
        }
1521

1522
        if (StringUtils.isNotEmpty(childDetails.entityId())) {
×
1523
            vaccine.setBaseEntityId(childDetails.entityId());
×
1524
        } else {
1525
            vaccine.setBaseEntityId(isOutOfCatchmentVaccine && !BaseRepository.TYPE_Synced.equals(vaccine.getSyncStatus()) ? "" : childDetails.entityId());
×
1526
        }
1527

1528
        vaccine.setName(tag.getName());
×
1529
        vaccine.setDate(tag.getUpdatedVaccineDate().toDate());
×
1530
        vaccine.setAnmId(getOpenSRPContext().allSharedPreferences().fetchRegisteredANM());
×
1531
        vaccine.setLocationId(ChildJsonFormUtils.getProviderLocationId(this));
×
1532
        vaccine.setChildLocationId(ChildJsonFormUtils.getChildLocationId(getOpenSRPContext().allSharedPreferences().fetchDefaultLocalityId(vaccine.getAnmId()), getOpenSRPContext().allSharedPreferences()));
×
1533

1534
        String lastChar = vaccine.getName().substring(vaccine.getName().length() - 1);
×
1535
        if (StringUtils.isNumeric(lastChar)) {
×
1536
            vaccine.setCalculation(Integer.valueOf(lastChar));
×
1537
        } else {
1538
            vaccine.setCalculation(-1);
×
1539
        }
1540

1541
        vaccine.setOutOfCatchment(isOutOfCatchmentVaccine ? 1 : 0);
×
1542

1543
        if (isOutOfCatchmentVaccine && StringUtils.isEmpty(vaccine.getProgramClientId())) {
×
1544
            vaccine.setProgramClientId(tag.getPatientNumber());
×
1545
        }
1546

1547
        Utils.addVaccine(vaccineRepository, vaccine);
×
1548
        tag.setDbKey(vaccine.getId());
×
1549
        setLastModified(true);
×
1550
    }
×
1551

1552
    private void updateVaccineGroupViews(View view, final List<VaccineWrapper> wrappers, List<Vaccine> vaccineList) {
1553
        updateVaccineGroupViews(view, wrappers, vaccineList, false);
×
1554
    }
×
1555

1556
    @Override
1557
    public void updateVaccineGroupViews(View view, final List<VaccineWrapper> wrappers, final List<Vaccine> vaccineList, final boolean undo) {
1558
        if (!(view instanceof VaccineGroup)) {
×
1559
            return;
×
1560
        }
1561
        final VaccineGroup vaccineGroup = (VaccineGroup) view;
×
1562
        vaccineGroup.setModalOpen(false);
×
1563

1564
        if (Looper.myLooper() == Looper.getMainLooper()) {
×
1565
            if (undo) {
×
1566
                vaccineGroup.setVaccineList(vaccineList);
×
1567
                vaccineGroup.updateWrapperStatus((ArrayList<VaccineWrapper>) wrappers, Constants.KEY.CHILD);
×
1568
            }
1569
            vaccineGroup.updateViews((ArrayList<VaccineWrapper>) wrappers);
×
1570

1571
        } else {
1572
            Handler handler = new Handler(Looper.getMainLooper());
×
1573
            handler.post(() -> {
×
1574
                if (undo) {
×
1575
                    vaccineGroup.setVaccineList(vaccineList);
×
1576
                    vaccineGroup.updateWrapperStatus((ArrayList<VaccineWrapper>) wrappers, Constants.KEY.CHILD);
×
1577
                }
1578
                vaccineGroup.updateViews((ArrayList<VaccineWrapper>) wrappers);
×
1579
            });
×
1580
        }
1581
    }
×
1582

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

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

1623
                        if (VaccinatorUtils.cleanVaccineName(curWrapperName).contains(VaccinatorUtils.cleanVaccineName(curAffectedVaccineName))) {
×
1624
                            if (!affectedGroups.containsKey(curGroup)) {
×
1625
                                affectedGroups.put(curGroup, new ArrayList<>());
×
1626
                            }
1627

1628
                            affectedGroups.get(curGroup).add(curWrapper);
×
1629
                            viewFound = true;
×
1630
                        }
1631

1632
                        if (viewFound) break;
×
1633
                    }
×
1634

1635
                    if (viewFound) break;
×
1636
                }
×
1637
            }
×
1638

1639
            addVaccineGroups(vaccineList, alerts, affectedGroups);
×
1640
        }
1641
    }
×
1642

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

1654
    //Recurring Service
1655
    @Override
1656
    public void onGiveToday(ServiceWrapper tag, View v) {
1657
        if (tag != null) {
×
1658
            View view = RecurringServiceUtils.getLastOpenedServiceView(serviceGroups);
×
1659
            saveService(tag, view);
×
1660
        }
1661
    }
×
1662

1663
    @Override
1664
    public void onGiveEarlier(ServiceWrapper tag, View v) {
1665
        if (tag != null) {
×
1666
            View view = RecurringServiceUtils.getLastOpenedServiceView(serviceGroups);
×
1667
            saveService(tag, view);
×
1668
        }
1669
    }
×
1670

1671
    @Override
1672
    public void onUndoService(ServiceWrapper tag, View v) {
1673
        Utils.startAsyncTask(new UndoServiceTask(tag), null);
×
1674
    }
×
1675

1676
    private void saveService(ServiceWrapper tag, final View view) {
1677
        if (tag == null) {
×
1678
            return;
×
1679
        }
1680

1681
        ServiceWrapper[] arrayTags = {tag};
×
1682
        SaveServiceTask backgroundTask = new SaveServiceTask();
×
1683
        String providerId = getOpenSRPContext().allSharedPreferences().fetchRegisteredANM();
×
1684
        String locationId = ChildJsonFormUtils.getProviderLocationId(this);
×
1685
        String childLocationId = ChildJsonFormUtils.getChildLocationId(locationId, getOpenSRPContext().allSharedPreferences());
×
1686
        String team = getOpenSRPContext().allSharedPreferences().fetchDefaultTeam(providerId);
×
1687
        String teamId = getOpenSRPContext().allSharedPreferences().fetchDefaultTeamId(providerId);
×
1688

1689
        backgroundTask.setProviderId(providerId);
×
1690
        backgroundTask.setLocationId(locationId);
×
1691
        backgroundTask.setChildLocationId(childLocationId);
×
1692
        backgroundTask.setTeam(team);
×
1693
        backgroundTask.setTeamId(teamId);
×
1694
        backgroundTask.setView(view);
×
1695
        Utils.startAsyncTask(backgroundTask, arrayTags);
×
1696
    }
×
1697

1698
    public Vaccine getVaccineAquiredByName(@NonNull List<Vaccine> vaccineList, @NonNull String name) {
1699

1700
        for (Vaccine vaccine : vaccineList) {
×
1701
            if (vaccine.getName().equals(name)) return vaccine;
×
1702
        }
×
1703
        return null;
×
1704
    }
1705

1706
    public String getCurrentLocation() {
1707
        return toolbar.getCurrentLocation();
×
1708
    }
1709

1710
    @Override
1711
    public abstract void onClick(View view);
1712

1713
    @Override
1714
    public CommonPersonObjectClient getChildDetails() {
1715
        return childDetails;
×
1716
    }
1717

1718
    @Override
1719
    public void setChildDetails(Map<String, String> detailsMap) {
1720
        childDetails.setColumnmaps(detailsMap);
×
1721
        childDetails.setDetails(detailsMap);
×
1722
    }
×
1723

1724
    @Override
1725
    public void showGrowthDialogFragment(Map<String, List> growthMonitoring) {
1726
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
×
1727
        Fragment prev = getSupportFragmentManager().findFragmentByTag(BaseChildImmunizationActivity.DIALOG_TAG);
×
1728
        if (prev != null) {
×
1729
            return;
×
1730
        }
1731
        fragmentTransaction.addToBackStack(null);
×
1732

1733
        showProgressDialog(getString(R.string.loading), getString(R.string.loading_form_message));
×
1734

1735
        List<Weight> weights = new ArrayList<>();
×
1736
        List<Height> heights = new ArrayList<>();
×
1737

1738
        if (growthMonitoring == null || growthMonitoring.isEmpty()) {
×
1739
            Utils.showToast(this, getString(R.string.record_growth_details));
×
1740
        } else {
1741
            if (growthMonitoring.containsKey(Constants.WEIGHT)) {
×
1742
                weights = growthMonitoring.get(Constants.WEIGHT);
×
1743
            }
1744

1745
            if (growthMonitoring.containsKey(Constants.HEIGHT)) {
×
1746
                heights = growthMonitoring.get(Constants.HEIGHT);
×
1747
            }
1748
        }
1749

1750
        GrowthDialogFragment growthDialogFragment = GrowthDialogFragment.newInstance(childDetails, weights, heights);
×
1751
        growthDialogFragment.show(fragmentTransaction, BaseChildImmunizationActivity.DIALOG_TAG);
×
1752

1753
        hideProgressDialog();
×
1754
    }
×
1755

1756
    ////////////////////////////////////////////////////////////////
1757
    // Inner classes
1758
    ////////////////////////////////////////////////////////////////
1759

1760
    public void updateScheduleDate() {
1761
        String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
1762
        DateTime dateTime = Utils.dobStringToDateTime(dobString);
×
1763
        if (dateTime != null) {
×
1764
            VaccineSchedule.updateOfflineAlertsOnly(childDetails.entityId(), dateTime, Constants.KEY.CHILD);
×
1765
            if (recurringServiceEnabled) {
×
1766
                ServiceSchedule.updateOfflineAlerts(childDetails.entityId(), dateTime);
×
1767
            }
1768
        }
1769
    }
×
1770

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

1775
        NamedObject<List<Vaccine>> vaccineNamedObject = new NamedObject<>(Vaccine.class.getName(), vaccineList);
1✔
1776
        map.put(vaccineNamedObject.name, vaccineNamedObject);
1✔
1777

1778
        NamedObject<Weight> weightNamedObject = new NamedObject<>(Weight.class.getName(), weight);
1✔
1779
        map.put(weightNamedObject.name, weightNamedObject);
1✔
1780

1781
        NamedObject<Height> heightNamedObject = new NamedObject<>(Height.class.getName(), height);
1✔
1782
        map.put(heightNamedObject.name, heightNamedObject);
1✔
1783

1784
        NamedObject<Map<String, List<ServiceType>>> serviceTypeNamedObject =
1✔
1785
                new NamedObject<>(ServiceType.class.getName(), serviceTypeMap);
1✔
1786
        map.put(serviceTypeNamedObject.name, serviceTypeNamedObject);
1✔
1787

1788
        NamedObject<List<ServiceRecord>> serviceRecordNamedObject =
1✔
1789
                new NamedObject<>(ServiceRecord.class.getName(), serviceRecords);
1✔
1790
        map.put(serviceRecordNamedObject.name, serviceRecordNamedObject);
1✔
1791

1792
        NamedObject<List<Alert>> alertsNamedObject = new NamedObject<>(Alert.class.getName(), alertList);
1✔
1793
        map.put(alertsNamedObject.name, alertsNamedObject);
1✔
1794

1795
        return map;
1✔
1796
    }
1797

1798
    public void processNextVaccineDate(String baseEntityId, List<Observation> observationList) {
1799
        try {
1800

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

1803
            String formSubmissionId = null;
×
1804

1805
            for (EventClient eventClient : eventClients) {
×
1806
                if (Constants.EventType.NEXT_APPOINTMENT.equalsIgnoreCase(eventClient.getEvent().getEventType())) {
×
1807

1808
                    formSubmissionId = eventClient.getEvent().getFormSubmissionId();
×
1809

1810
                    break;
×
1811
                }
1812
            }
×
1813

1814
            Event nextVaccineDateEvent = ChildJsonFormUtils.createNextAppointmentEvent(baseEntityId, observationList, formSubmissionId);
×
1815
            ChildJsonFormUtils.convertAndPersistEvent(nextVaccineDateEvent);
×
1816

1817
        } catch (JSONException e) {
×
1818
            Timber.e(e);
×
1819
        }
×
1820
    }
×
1821

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

1824
        private VaccineRepository vaccineRepository;
1825
        private WeightRepository weightRepository;
1826
        private HeightRepository heightRepository;
1827
        private RecurringServiceTypeRepository recurringServiceTypeRepository;
1828
        private RecurringServiceRecordRepository recurringServiceRecordRepository;
1829
        private AlertService alertService;
1830

1831
        public void setVaccineRepository(VaccineRepository vaccineRepository) {
1832
            this.vaccineRepository = vaccineRepository;
1✔
1833
        }
1✔
1834

1835
        public void setWeightRepository(WeightRepository weightRepository) {
1836
            this.weightRepository = weightRepository;
1✔
1837
        }
1✔
1838

1839
        public void setHeightRepository(HeightRepository heightRepository) {
1840
            this.heightRepository = heightRepository;
×
1841
        }
×
1842

1843
        public void setRecurringServiceTypeRepository(RecurringServiceTypeRepository recurringServiceTypeRepository) {
1844
            this.recurringServiceTypeRepository = recurringServiceTypeRepository;
×
1845
        }
×
1846

1847
        public void setRecurringServiceRecordRepository(RecurringServiceRecordRepository recurringServiceRecordRepository) {
1848
            this.recurringServiceRecordRepository = recurringServiceRecordRepository;
×
1849
        }
×
1850

1851
        public void setAlertService(AlertService alertService) {
1852
            this.alertService = alertService;
1✔
1853
        }
1✔
1854

1855
        @Override
1856
        protected Map<String, NamedObject<?>> doInBackground(Void... voids) {
1857
            updateScheduleDate();
1✔
1858

1859
            List<Vaccine> vaccineList = new ArrayList<>();
1✔
1860
            Weight weight = null;
1✔
1861
            Height height = null;
1✔
1862

1863
            Map<String, List<ServiceType>> serviceTypeMap = new LinkedHashMap<>();
1✔
1864
            List<ServiceRecord> serviceRecords = new ArrayList<>();
1✔
1865

1866
            List<Alert> alertList = new ArrayList<>();
1✔
1867
            if (vaccineRepository != null) {
1✔
1868
                vaccineList = vaccineRepository.findByEntityId(childDetails.entityId());
1✔
1869
            }
1870

1871
            if (weightRepository != null) {
1✔
1872
                weight = weightRepository.findUnSyncedByEntityId(childDetails.entityId());
×
1873
            }
1874

1875
            if (heightRepository != null) {
1✔
1876
                height = heightRepository.findUnSyncedByEntityId(childDetails.entityId());
×
1877
            }
1878

1879
            if (Boolean.parseBoolean(ChildLibrary.getInstance().getProperties()
1✔
1880
                    .getProperty(ChildAppProperties.KEY.FEATURE_RECURRING_SERVICE_ENABLED, "true"))
1✔
1881
                    && recurringServiceRecordRepository != null) {
1882
                serviceRecords = recurringServiceRecordRepository.findByEntityId(childDetails.entityId());
×
1883
            }
1884

1885
            if (recurringServiceEnabled
1✔
1886
                    && recurringServiceTypeRepository != null) {
1887
                List<ServiceType> serviceTypes = recurringServiceTypeRepository.fetchAll();
×
1888
                for (ServiceType serviceType : serviceTypes) {
×
1889
                    String type = serviceType.getType();
×
1890
                    List<ServiceType> serviceTypeList = serviceTypeMap.get(type);
×
1891
                    if (serviceTypeList == null) {
×
1892
                        serviceTypeList = new ArrayList<>();
×
1893
                    }
1894
                    serviceTypeList.add(serviceType);
×
1895
                    serviceTypeMap.put(type, serviceTypeList);
×
1896
                }
×
1897
            }
1898

1899
            if (alertService != null) {
1✔
1900
                alertList = alertService.findByEntityId(childDetails.entityId());
×
1901
            }
1902

1903
            return getStringNamedObjectMap(vaccineList, weight, height, serviceTypeMap, serviceRecords, alertList);
1✔
1904
        }
1905

1906
        @Override
1907
        protected void onPreExecute() {
1908
            showProgressDialog(getString(R.string.updating_dialog_title), null);
1✔
1909
        }
1✔
1910

1911
        @Override
1912
        protected void onPostExecute(Map<String, NamedObject<?>> map) {
1913

1914
            List<Vaccine> vaccineList = AsyncTaskUtils.extractVaccines(map);
×
1915
            Map<String, List<ServiceType>> serviceTypeMap = AsyncTaskUtils.extractServiceTypes(map);
×
1916
            List<ServiceRecord> serviceRecords = AsyncTaskUtils.extractServiceRecords(map);
×
1917
            List<Alert> alertList = AsyncTaskUtils.extractAlerts(map);
×
1918
            Weight weight = AsyncTaskUtils.retrieveWeight(map);
×
1919
            Height height = ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.MONITOR_HEIGHT) ? AsyncTaskUtils.retrieveHeight(map) : null;
×
1920

1921
            updateGrowthViews(weight, height, isChildActive);
×
1922
            updateServiceViews(serviceTypeMap, serviceRecords, alertList);
×
1923
            updateVaccinationViews(vaccineList, alertList);
×
1924
            performRegisterActions();
×
1925

1926
            hideProgressDialog();
×
1927
        }
×
1928
    }
1929

1930
    public class SaveServiceTask extends AsyncTask<ServiceWrapper, Void, Triple<ArrayList<ServiceWrapper>,
×
1931
            List<ServiceRecord>, List<Alert>>> {
1932

1933
        private View view;
1934
        private String providerId;
1935
        private String locationId;
1936
        private String team;
1937
        private String teamId;
1938
        private String childLocationId;
1939

1940
        public void setView(View view) {
1941
            this.view = view;
×
1942
        }
×
1943

1944
        public void setProviderId(String providerId) {
1945
            this.providerId = providerId;
×
1946
        }
×
1947

1948
        public void setLocationId(String locationId) {
1949
            this.locationId = locationId;
×
1950
        }
×
1951

1952
        public void setChildLocationId(String childLocationId) {
1953
            this.childLocationId = childLocationId;
×
1954
        }
×
1955

1956
        public void setTeamId(String teamId) {
1957
            this.teamId = teamId;
×
1958
        }
×
1959

1960
        public void setTeam(String team) {
1961
            this.team = team;
×
1962
        }
×
1963

1964
        @Override
1965
        protected Triple<ArrayList<ServiceWrapper>, List<ServiceRecord>, List<Alert>> doInBackground(
1966
                ServiceWrapper... params) {
1967

1968
            ArrayList<ServiceWrapper> list = new ArrayList<>();
×
1969

1970
            for (ServiceWrapper tag : params) {
×
1971
                RecurringServiceUtils.saveService(tag, childDetails.entityId(), providerId, locationId,
×
1972
                        team, teamId, childLocationId);
1973
                setLastModified(true);
×
1974
                list.add(tag);
×
1975

1976
                ServiceSchedule.updateOfflineAlerts(tag.getType(), childDetails.entityId(), Utils.dobToDateTime(childDetails));
×
1977
            }
1978

1979
            List<ServiceRecord> serviceRecordList = ImmunizationLibrary.getInstance().recurringServiceRecordRepository()
×
1980
                    .findByEntityId(childDetails.entityId());
×
1981

1982
            AlertService alertService = getOpenSRPContext().alertService();
×
1983
            List<Alert> alertList = alertService.findByEntityId(childDetails.entityId());
×
1984

1985
            Utils.postEvent(new ClientDirtyFlagEvent(childDetails.entityId(), RecurringIntentService.EVENT_TYPE));
×
1986

1987
            return Triple.of(list, serviceRecordList, alertList);
×
1988

1989
        }
1990

1991
        @Override
1992
        protected void onPreExecute() {
1993
            showProgressDialog();
×
1994
        }
×
1995

1996
        @Override
1997
        protected void onPostExecute(Triple<ArrayList<ServiceWrapper>, List<ServiceRecord>, List<Alert>> triple) {
1998
            hideProgressDialog();
×
1999
            RecurringServiceUtils.updateServiceGroupViews(view, triple.getLeft(), triple.getMiddle(), triple.getRight());
×
2000
        }
×
2001
    }
2002

2003
    private class UndoServiceTask extends AsyncTask<Void, Void, Void> {
2004

2005
        private final View view;
2006
        private final ServiceWrapper tag;
2007
        private List<ServiceRecord> serviceRecordList;
2008
        private ArrayList<ServiceWrapper> wrappers;
2009
        private List<Alert> alertList;
2010

2011
        public UndoServiceTask(ServiceWrapper tag) {
×
2012
            this.tag = tag;
×
2013
            this.view = RecurringServiceUtils.getLastOpenedServiceView(serviceGroups);
×
2014
        }
×
2015

2016
        @Override
2017
        protected Void doInBackground(Void... params) {
2018
            if (tag != null && tag.getDbKey() != null) {
×
2019
                Long dbKey = tag.getDbKey();
×
2020
                ImmunizationLibrary.getInstance().recurringServiceRecordRepository().deleteServiceRecord(dbKey);
×
2021

2022
                serviceRecordList = ImmunizationLibrary.getInstance().recurringServiceRecordRepository().findByEntityId(childDetails.entityId());
×
2023

2024
                wrappers = new ArrayList<>();
×
2025
                wrappers.add(tag);
×
2026

2027
                ServiceSchedule.updateOfflineAlerts(tag.getType(), childDetails.entityId(), Utils.dobToDateTime(childDetails));
×
2028

2029
                AlertService alertService = getOpenSRPContext().alertService();
×
2030
                alertList = alertService.findByEntityId(childDetails.entityId());
×
2031

2032
            }
2033
            return null;
×
2034
        }
2035

2036
        @Override
2037
        protected void onPreExecute() {
2038
            showProgressDialog(getString(R.string.updating_dialog_title), null);
×
2039
        }
×
2040

2041
        @Override
2042
        protected void onPostExecute(Void params) {
2043
            super.onPostExecute(params);
×
2044
            hideProgressDialog();
×
2045

2046
            tag.setUpdatedVaccineDate(null, false);
×
2047
            tag.setDbKey(null);
×
2048

2049
            RecurringServiceUtils.updateServiceGroupViews(view, wrappers, serviceRecordList, alertList, true);
×
2050
        }
×
2051
    }
2052

2053
    private class SaveVaccinesTask extends AsyncTask<VaccineWrapper, Void, List<VaccineWrapper>> {
×
2054

2055
        private View view;
2056
        private VaccineRepository vaccineRepository;
2057
        private AlertService alertService;
2058
        private List<String> affectedVaccines;
2059
        private List<Vaccine> vaccineList;
2060
        private List<Alert> alertList;
2061

2062
        public void setView(View view) {
2063
            getSupportFragmentManager();
×
2064
            this.view = view;
×
2065
        }
×
2066

2067
        public void setVaccineRepository(VaccineRepository vaccineRepository) {
2068
            this.vaccineRepository = vaccineRepository;
×
2069
            alertService = getOpenSRPContext().alertService();
×
2070
            affectedVaccines = new ArrayList<>();
×
2071
        }
×
2072

2073
        @Override
2074
        protected List<VaccineWrapper> doInBackground(VaccineWrapper... vaccineWrappers) {
2075

2076
            ArrayList<VaccineWrapper> list = new ArrayList<>();
×
2077
            if (vaccineRepository != null) {
×
2078
                for (VaccineWrapper tag : vaccineWrappers) {
×
2079
                    saveVaccine(vaccineRepository, tag);
×
2080
                    list.add(tag);
×
2081
                }
2082
            }
2083

2084
            String dobString = Utils.getValue(childDetails.getColumnmaps(), Constants.KEY.DOB, false);
×
2085
            DateTime dateTime = Utils.dobStringToDateTime(dobString);
×
2086
            if (dateTime != null) {
×
2087
                affectedVaccines = VaccineSchedule.updateOfflineAlertsAndReturnAffectedVaccineNames(childDetails.entityId(), dateTime, Constants.KEY.CHILD);
×
2088
            }
2089
            vaccineList = vaccineRepository.findByEntityId(childDetails.entityId());
×
2090
            alertList = alertService.findByEntityId(childDetails.entityId());
×
2091

2092
            //Schedule stuff if we support the next appointment event
2093

2094
            if (ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.NEXT_APPOINTMENT_EVENT_ENABLED)) {
×
2095

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

2099
                Vaccine previousVaccineGiven = null;
×
2100
                Date lastVaccineDate = null;
×
2101
                if (!vaccineList.isEmpty()) {
×
2102
                    previousVaccineGiven = vaccineList.get(vaccineList.size() - 1);
×
2103
                    lastVaccineDate = previousVaccineGiven.getDate();
×
2104
                }
2105

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

2109
                List<Observation> observationList = new ArrayList<>();
×
2110

2111
                if (previousVaccineGiven != null) {
×
2112
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.TREATMENT_PROVIDED, previousVaccineGiven.getName().toUpperCase(), Observation.TYPE.TEXT));
×
2113
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.IS_OUT_OF_CATCHMENT, String.valueOf(previousVaccineGiven.getOutOfCatchment() == 1), Observation.TYPE.TEXT));
×
2114
                }
2115
                if (nextVaccineAlert != null) {
×
2116
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.NEXT_APPOINTMENT_DATE, nextVaccineAlert.startDate(), Observation.TYPE.DATE));
×
2117
                    observationList.add(new Observation(Constants.NEXT_APPOINTMENT_OBSERVATION_FIELD.NEXT_SERVICE_EXPECTED, nextVaccineAlert.scheduleName(), Observation.TYPE.TEXT));
×
2118
                }
2119

2120
                processNextVaccineDate(childDetails.entityId(), observationList);
×
2121
            }
2122

2123
            return list;
×
2124
        }
2125

2126
        @Override
2127
        protected void onPreExecute() {
2128
            showProgressDialog();
×
2129
        }
×
2130

2131
        @Override
2132
        protected void onPostExecute(List<VaccineWrapper> list) {
2133
            hideProgressDialog();
×
2134
            updateVaccineGroupViews(view, list, vaccineList);
×
2135
            WeightWrapper weightWrapper = (WeightWrapper) recordGrowth.getTag(R.id.weight_wrapper);
×
2136
            if ((ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED) &&
×
2137
                    ChildLibrary.getInstance().getProperties()
×
2138
                            .getPropertyBoolean(ChildAppProperties.KEY.NOTIFICATIONS_WEIGHT_ENABLED)) &&
×
2139
                    (weightWrapper == null || weightWrapper.getWeight() == null)) {
×
2140
                showRecordWeightNotification();
×
2141
            }
2142

2143
            updateVaccineGroupsUsingAlerts(affectedVaccines, vaccineList, alertList);
×
2144
            showVaccineNotifications(vaccineList, alertList);
×
2145
        }
×
2146
    }
2147
}
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