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

OpenSRP / opensrp-client-immunization / #898

pending completion
#898

push

github-actions

web-flow
Merge pull request #195 from opensrp/check-vaccine-duplicates

Add Duplicate Vaccines & Recurring Service Record Checks

5076 of 6673 relevant lines covered (76.07%)

0.76 hits per line

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

69.87
opensrp-immunization/src/main/java/org/smartregister/immunization/util/VaccinateActionUtils.java
1
package org.smartregister.immunization.util;
2

3
import static org.smartregister.AllConstants.ENTITY_ID_PARAM;
4
import static org.smartregister.AllConstants.FORM_NAME_PARAM;
5
import static org.smartregister.AllConstants.INSTANCE_ID_PARAM;
6
import static org.smartregister.AllConstants.SYNC_STATUS;
7
import static org.smartregister.AllConstants.VERSION_PARAM;
8
import static org.smartregister.domain.SyncStatus.PENDING;
9
import static org.smartregister.util.EasyMap.create;
10
import static org.smartregister.util.Utils.convertDateFormat;
11

12
import android.content.Context;
13
import android.graphics.Color;
14
import android.view.View;
15
import android.widget.Button;
16
import android.widget.TableLayout;
17
import android.widget.TableRow;
18
import android.widget.TextView;
19

20
import androidx.fragment.app.Fragment;
21
import androidx.fragment.app.FragmentActivity;
22
import androidx.fragment.app.FragmentTransaction;
23

24
import com.google.gson.Gson;
25

26
import org.apache.commons.lang3.StringUtils;
27
import org.joda.time.DateTime;
28
import org.json.JSONException;
29
import org.json.JSONObject;
30
import org.smartregister.clientandeventmodel.DateUtil;
31
import org.smartregister.commonregistry.AllCommonsRepository;
32
import org.smartregister.commonregistry.CommonFtsObject;
33
import org.smartregister.domain.Alert;
34
import org.smartregister.domain.AlertStatus;
35
import org.smartregister.domain.form.FormSubmission;
36
import org.smartregister.immunization.ImmunizationLibrary;
37
import org.smartregister.immunization.R;
38
import org.smartregister.immunization.db.VaccineRepo;
39
import org.smartregister.immunization.domain.ServiceRecord;
40
import org.smartregister.immunization.domain.ServiceType;
41
import org.smartregister.immunization.domain.VaccinateFormSubmissionWrapper;
42
import org.smartregister.immunization.domain.Vaccine;
43
import org.smartregister.immunization.domain.VaccineWrapper;
44
import org.smartregister.immunization.domain.jsonmapping.VaccineGroup;
45
import org.smartregister.immunization.fragment.VaccinationDialogFragment;
46
import org.smartregister.service.AlertService;
47
import org.smartregister.service.ZiggyService;
48
import org.smartregister.util.FormUtils;
49

50
import java.util.ArrayList;
51
import java.util.Arrays;
52
import java.util.Calendar;
53
import java.util.Collection;
54
import java.util.Date;
55
import java.util.List;
56
import java.util.Set;
57
import java.util.concurrent.TimeUnit;
58

59
import timber.log.Timber;
60

61
/**
62
 * Created by keyman on 17/11/2016.
63
 */
64
public class VaccinateActionUtils {
1✔
65

66
    public static String formData(Context context, String entityId, String formName, String metaData) {
67
        try {
68
            return FormUtils.getInstance(context).generateXMLInputForFormWithEntityId(entityId, formName, metaData);
1✔
69
        } catch (Exception e) {
1✔
70
            Timber.e(e);
1✔
71
            return null;
1✔
72
        }
73
    }
74

75
    public static void updateJson(JSONObject jsonObject, String field, String value) {
76
        try {
77
            if (jsonObject.has(field)) {
1✔
78
                JSONObject fieldJson = jsonObject.getJSONObject(field);
1✔
79
                fieldJson.put("content", value);
1✔
80
            }
81
        } catch (JSONException e) {
1✔
82
            Timber.e(e);
1✔
83
        }
1✔
84
    }
1✔
85

86
    public static JSONObject find(JSONObject jsonObject, String field) {
87
        try {
88
            if (jsonObject.has(field)) {
1✔
89
                return jsonObject.getJSONObject(field);
1✔
90

91
            }
92
        } catch (JSONException e) {
1✔
93
            Timber.e(e);
1✔
94
        }
1✔
95

96
        return null;
1✔
97
    }
98

99

100
    public static TableRow findRow(Set<TableLayout> tables, String tag) {
101
        for (TableLayout table : tables) {
1✔
102
            View view = table.findViewWithTag(tag);
1✔
103
            if (view != null && view instanceof TableRow) {
1✔
104
                return (TableRow) view;
1✔
105
            }
106
        }
1✔
107
        return null;
1✔
108
    }
109

110
    public static TableRow findRow(TableLayout table, String tag) {
111
        View view = table.findViewWithTag(tag);
1✔
112
        if (view != null && view instanceof TableRow) {
1✔
113
            return (TableRow) view;
1✔
114
        }
115
        return null;
1✔
116
    }
117

118
    public static void vaccinateToday(TableRow tableRow, VaccineWrapper tag) {
119
        TextView textView = tableRow.findViewById(R.id.date);
×
120
        textView.setText(R.string.done_today);
×
121

122
        Button button = tableRow.findViewById(R.id.undo);
×
123
        button.setVisibility(View.VISIBLE);
×
124

125
        String color = "#31B404";
×
126
        Button status = tableRow.findViewById(R.id.status);
×
127
        status.setBackgroundColor(Color.parseColor(color));
×
128

129
        tableRow.setOnClickListener(null);
×
130
    }
×
131

132
    public static void vaccinateEarlier(TableRow tableRow, VaccineWrapper tag) {
133
        String vaccineDate = convertDateFormat(tag.getUpdatedVaccineDateAsString(), true);
×
134

135
        TextView textView = tableRow.findViewById(R.id.date);
×
136
        textView.setText(vaccineDate);
×
137

138
        Button button = tableRow.findViewById(R.id.undo);
×
139
        button.setVisibility(View.VISIBLE);
×
140

141
        String color = "#31B404";
×
142
        Button status = tableRow.findViewById(R.id.status);
×
143
        status.setBackgroundColor(Color.parseColor(color));
×
144

145
        tableRow.setOnClickListener(null);
×
146
    }
×
147

148
    public static void undoVaccination(final Context context, TableRow tableRow, final VaccineWrapper tag) {
149
        Button button = tableRow.findViewById(R.id.undo);
×
150
        button.setVisibility(View.GONE);
×
151

152
        String color = tag.getColor();
×
153
        Button status = tableRow.findViewById(R.id.status);
×
154
        status.setBackgroundColor(Color.parseColor(color));
×
155

156
        TextView v = tableRow.findViewById(R.id.date);
×
157
        v.setText(tag.getFormattedVaccineDate());
×
158

159
        if ("due".equalsIgnoreCase(tag.getStatus())) {
×
160
            tableRow.setOnClickListener(new TableRow.OnClickListener() {
×
161
                @Override
162
                public void onClick(View view) {
163
                    FragmentTransaction ft = ((FragmentActivity) context).getSupportFragmentManager().beginTransaction();
×
164
                    Fragment prev =
×
165
                            ((FragmentActivity) context).getSupportFragmentManager()
×
166
                                    .findFragmentByTag(VaccinationDialogFragment.DIALOG_TAG);
×
167
                    if (prev != null) {
×
168
                        ft.remove(prev);
×
169
                    }
170
                    ft.addToBackStack(null);
×
171
                    ArrayList<VaccineWrapper> list = new ArrayList<VaccineWrapper>();
×
172
                    list.add(tag);
×
173
                    VaccinationDialogFragment vaccinationDialogFragment = VaccinationDialogFragment
×
174
                            .newInstance(null, null, list);
×
175
                    vaccinationDialogFragment.show(ft, VaccinationDialogFragment.DIALOG_TAG);
×
176

177
                }
×
178
            });
179
        }
180

181
    }
×
182

183
    public static void saveFormSubmission(Context appContext, String formSubmission, String id, String formName,
184
                                          JSONObject fieldOverrides) {
185

186
        Timber.d("fieldoverride %s", fieldOverrides.toString());
×
187

188
        // save the form
189
        try {
190
            FormUtils formUtils = FormUtils.getInstance(appContext);
×
191
            FormSubmission submission = formUtils
×
192
                    .generateFormSubmisionFromXMLString(id, formSubmission, formName, fieldOverrides);
×
193

194
            org.smartregister.Context context = ImmunizationLibrary.getInstance().context();
×
195
            ZiggyService ziggyService = context.ziggyService();
×
196
            ziggyService.saveForm(getParams(submission), submission.instance());
×
197

198
            // Update Fts Tables
199
            CommonFtsObject commonFtsObject = context.commonFtsObject();
×
200
            if (commonFtsObject != null) {
×
201
                String[] ftsTables = commonFtsObject.getTables();
×
202
                for (String ftsTable : ftsTables) {
×
203
                    AllCommonsRepository allCommonsRepository = context.allCommonsRepositoryobjects(ftsTable);
×
204
                    boolean updated = allCommonsRepository.updateSearch(submission.entityId());
×
205
                    if (updated) {
×
206
                        break;
×
207
                    }
208
                }
209
            }
210
        } catch (Exception e) {
×
211
            Timber.e(e);
×
212
        }
×
213
    }
×
214

215
    private static String getParams(FormSubmission submission) {
216
        return new Gson().toJson(
1✔
217
                create(INSTANCE_ID_PARAM, submission.instanceId())
1✔
218
                        .put(ENTITY_ID_PARAM, submission.entityId())
1✔
219
                        .put(FORM_NAME_PARAM, submission.formName())
1✔
220
                        .put(VERSION_PARAM, submission.version())
1✔
221
                        .put(SYNC_STATUS, PENDING.value())
1✔
222
                        .map());
1✔
223
    }
224

225
    public static JSONObject retrieveFieldOverides(String overrides) {
226
        try {
227
            //get the field overrides map
228
            if (overrides != null) {
1✔
229
                JSONObject json = new JSONObject(overrides);
1✔
230
                String overridesStr = json.getString("fieldOverrides");
1✔
231
                return new JSONObject(overridesStr);
1✔
232
            }
233
        } catch (Exception e) {
1✔
234
            Timber.e(e);
1✔
235
        }
1✔
236
        return new JSONObject();
1✔
237

238
    }
239

240
    public static String retrieveExistingAge(VaccinateFormSubmissionWrapper vaccinateFormSubmissionWrapper) {
241
        try {
242
            if (vaccinateFormSubmissionWrapper != null) {
×
243
                JSONObject fieldOverrides = vaccinateFormSubmissionWrapper.getOverrides();
×
244
                if (fieldOverrides.has("existing_age")) {
×
245
                    return fieldOverrides.getString("existing_age");
×
246
                }
247
            }
248
        } catch (JSONException e) {
×
249
            Timber.e(e);
×
250
        }
×
251
        return null;
×
252
    }
253

254
    public static boolean addDialogHookCustomFilter(VaccineWrapper tag) {
255
        boolean addHook = false;
1✔
256

257
        int age = 0;
1✔
258
        String existingAge = tag.getExistingAge();
1✔
259
        if (StringUtils.isNumeric(existingAge)) {
1✔
260
            age = Integer.valueOf(existingAge);
1✔
261
        }
262

263
        VaccineRepo.Vaccine vaccine = tag.getVaccine();
1✔
264
        switch (vaccine) {
1✔
265
            case penta1:
266
            case pcv1:
267
            case opv1:
268
                if (age > 35)
1✔
269
                    addHook = true;
1✔
270
                break;
271
            case penta2:
272
            case pcv2:
273
            case opv2:
274
                if (age > 63)
1✔
275
                    addHook = true;
1✔
276
                break;
277
            case penta3:
278
            case pcv3:
279
            case opv3:
280
            case ipv:
281
                if (age > 91)
1✔
282
                    addHook = true;
1✔
283
                break;
284
            case measles1:
285
                if (age > 250)
1✔
286
                    addHook = true;
1✔
287
                break;
288
            case measles2:
289
                if (age > 340)
1✔
290
                    addHook = true;
1✔
291
                break;
292
            default:
293
                addHook = true;
1✔
294
                break;
295
        }
296

297
        return addHook;
1✔
298

299
    }
300

301
    public static String[] allAlertNames(String category) {
302
        if (category == null) {
1✔
303
            return null;
1✔
304
        }
305

306
        List<VaccineRepo.Vaccine> vaccines = VaccineRepo.getVaccines(category);
1✔
307
        List<String> names = new ArrayList<>();
1✔
308

309
        for (VaccineRepo.Vaccine vaccine : vaccines) {
1✔
310
            names.add(vaccine.display());
1✔
311
            names.add(vaccine.name());
1✔
312
        }
1✔
313

314
        return names.toArray(new String[names.size()]);
1✔
315

316
    }
317

318
    public static String[] allAlertNames(Collection<List<ServiceType>> typeList) {
319
        if (typeList == null) {
1✔
320
            return null;
×
321
        }
322

323
        List<String> names = new ArrayList<>();
1✔
324

325
        for (List<ServiceType> serviceTypes : typeList) {
1✔
326
            if (serviceTypes != null) {
1✔
327
                String[] array = allAlertNames(serviceTypes);
1✔
328
                if (array != null) {
1✔
329
                    names.addAll(Arrays.asList(array));
1✔
330
                }
331
            }
332
        }
1✔
333

334
        return names.toArray(new String[names.size()]);
1✔
335
    }
336

337
    public static String[] allAlertNames(List<ServiceType> list) {
338
        if (list == null) {
1✔
339
            return null;
×
340
        }
341

342
        List<String> names = new ArrayList<>();
1✔
343

344
        for (ServiceType serviceType : list) {
1✔
345
            names.add(serviceType.getName().toLowerCase().replaceAll("\\s+", ""));
1✔
346
            names.add(serviceType.getName());
1✔
347
        }
1✔
348
        return names.toArray(new String[names.size()]);
1✔
349
    }
350

351
    public static String addHyphen(String s) {
352
        if (StringUtils.isNotBlank(s)) {
1✔
353
            return s.replace(" ", "_");
1✔
354
        }
355
        return s;
1✔
356
    }
357

358
    public static String removeHyphen(String s) {
359
        if (StringUtils.isNotBlank(s)) {
1✔
360
            return s.replace("_", " ");
1✔
361
        }
362
        return s;
1✔
363
    }
364

365
    public static void populateDefaultAlerts(AlertService alertService, List<Vaccine> vaccineList,
366
                                             List<Alert> alertList, String entityId,
367
                                             DateTime birthDateTime, VaccineRepo.Vaccine[] vList) {
368

369
        if (vList == null || vList.length == 0) {
1✔
370
            return;
1✔
371
        }
372

373
        List<Alert> defaultAlerts = new ArrayList<Alert>();
1✔
374
        for (VaccineRepo.Vaccine v : vList) {
1✔
375
            if ((!VaccinateActionUtils.hasVaccine(vaccineList, v)) && (!VaccinateActionUtils.hasAlert(alertList, v))) {
1✔
376
                defaultAlerts.add(VaccinateActionUtils.createDefaultAlert(v, entityId, birthDateTime));
1✔
377
            }
378
        }
379

380
        for (Alert alert : defaultAlerts) {
1✔
381
            alertService.create(alert);
1✔
382
            alertService.updateFtsSearch(alert, true);
1✔
383
        }
1✔
384
    }
1✔
385

386
    public static boolean hasVaccine(List<Vaccine> vaccineList, VaccineRepo.Vaccine v) {
387
        if (vaccineList == null || vaccineList.isEmpty() || v == null) {
1✔
388
            return false;
1✔
389
        }
390

391
        for (Vaccine vaccine : vaccineList) {
1✔
392
            if (vaccine.getName().equalsIgnoreCase(v.display().toLowerCase())) {
1✔
393
                return true;
1✔
394
            }
395
        }
1✔
396
        return false;
1✔
397
    }
398

399
    public static boolean hasAlert(List<Alert> alerts, VaccineRepo.Vaccine vaccine) {
400
        if (alerts == null || alerts.isEmpty() || vaccine == null) {
1✔
401
            return false;
1✔
402
        }
403

404
        for (Alert alert : alerts) {
1✔
405
            if (alert.scheduleName().replaceAll(" ", "").equalsIgnoreCase(vaccine.name())
1✔
406
                    || alert.visitCode().replaceAll(" ", "").equalsIgnoreCase(vaccine.name())) {
1✔
407
                return true;
1✔
408
            }
409
        }
1✔
410
        return false;
1✔
411
    }
412

413
    public static Alert createDefaultAlert(VaccineRepo.Vaccine vaccine, String entityId, DateTime birthDateTime) {
414

415

416
        AlertStatus alertStatus = AlertStatus.upcoming;
1✔
417
        Calendar today = Calendar.getInstance();
1✔
418
        today.set(Calendar.HOUR_OF_DAY, 0);
1✔
419
        today.set(Calendar.MINUTE, 0);
1✔
420
        today.set(Calendar.SECOND, 0);
1✔
421
        today.set(Calendar.MILLISECOND, 0);
1✔
422
        Date birthDate = birthDateTime.toDate();
1✔
423
        if (birthDateTime != null && birthDateTime.plusDays(vaccine.expiryDays()).isBefore(DateTime.now())) {
1✔
424
            alertStatus = AlertStatus.expired;
1✔
425
        } else if (birthDate.getTime() > (today.getTimeInMillis() + TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS))) {
1✔
426
            // Vaccination due more than one day from today
427
            alertStatus = AlertStatus.upcoming;
1✔
428
        } else if (birthDate.getTime() < (today.getTimeInMillis() - TimeUnit.MILLISECONDS.convert(10, TimeUnit.DAYS))) {
1✔
429
            // Vaccination overdue
430
            alertStatus = AlertStatus.urgent;
1✔
431
        } else {
432
            alertStatus = AlertStatus.normal;
1✔
433
        }
434

435
        return new Alert(entityId, vaccine.display(), vaccine.name(), alertStatus, DateUtil.yyyyMMdd.format(birthDate),
1✔
436
                null);
437

438
    }
439

440
    public static Alert getAlert(List<Alert> alerts, VaccineRepo.Vaccine vaccine) {
441
        if (alerts == null || alerts.isEmpty() || vaccine == null) {
1✔
442
            return null;
1✔
443
        }
444

445
        for (Alert alert : alerts) {
1✔
446
            if (alert.scheduleName().replaceAll(" ", "").equalsIgnoreCase(vaccine.name())
1✔
447
                    || alert.visitCode().replaceAll(" ", "").equalsIgnoreCase(vaccine.name())) {
1✔
448
                return alert;
1✔
449
            }
450
        }
1✔
451
        return null;
1✔
452
    }
453

454
    public static Vaccine getVaccine(List<Vaccine> vaccineList, VaccineRepo.Vaccine v) {
455
        if (vaccineList == null || vaccineList.isEmpty() || v == null) {
1✔
456
            return null;
1✔
457
        }
458

459
        for (Vaccine vaccine : vaccineList) {
1✔
460
            if (vaccine.getName().equalsIgnoreCase(v.display().toLowerCase())) {
1✔
461
                return vaccine;
1✔
462
            }
463
        }
1✔
464
        return null;
1✔
465
    }
466

467
    /**
468
     * Picks the BCG 2 special vaccine from the loaded list of special_vaccines and adds it to the birth group
469
     *
470
     * @param context
471
     * @param vaccineGroupObject
472
     * @param vaccineList
473
     * @return
474
     */
475
    public static boolean addBcg2SpecialVaccine(Context context, VaccineGroup vaccineGroupObject, List<Vaccine> vaccineList) {
476
        //Add BCG2 special vaccine to birth vaccine group
477
        if (VaccinateActionUtils.hasVaccine(vaccineList, VaccineRepo.Vaccine.bcg2)
1✔
478
                && vaccineGroupObject.days_after_birth_due != null
479
                && vaccineGroupObject.vaccines != null
480
                && "Birth".equalsIgnoreCase(vaccineGroupObject.name)
1✔
481
                && "0".equalsIgnoreCase(vaccineGroupObject.days_after_birth_due.toString())) {
1✔
482

483
            List<org.smartregister.immunization.domain.jsonmapping.Vaccine> specialVaccines = VaccinatorUtils
1✔
484
                    .getSpecialVaccines(context);
1✔
485

486
            if (specialVaccines != null && !specialVaccines.isEmpty()) {
1✔
487
                for (org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine : specialVaccines) {
1✔
488
                    if (vaccine.name != null
1✔
489
                            && vaccine.type != null
490
                            && vaccine.name.equalsIgnoreCase(VaccineRepo.Vaccine.bcg2.display())
1✔
491
                            && vaccine.type.equalsIgnoreCase(VaccineRepo.Vaccine.bcg.display())) {
1✔
492
                        vaccineGroupObject.vaccines.add(vaccine);
1✔
493
                        return true;
1✔
494
                    }
495
                }
×
496
            }
497
        }
498

499
        return false;
1✔
500
    }
501

502
    public static boolean moreThanThreeMonths(Date createdAt) {
503
        return createdAt != null && org.smartregister.util.DateUtil.checkIfDateThreeMonthsOlder(createdAt);
1✔
504
    }
505

506
    public static boolean lessThanThreeMonths(Vaccine vaccine) {
507
        ////////////////////////check 3 months///////////////////////////////
508
        return vaccine == null || vaccine.getCreatedAt() == null || !org.smartregister.util.DateUtil
1✔
509
                .checkIfDateThreeMonthsOlder(vaccine.getCreatedAt());
1✔
510
        ///////////////////////////////////////////////////////////////////////
511
    }
512

513

514
    public static boolean lessThanThreeMonths(ServiceRecord serviceRecord) {
515
        ////////////////////////check 3 months///////////////////////////////
516
        return serviceRecord == null || serviceRecord.getCreatedAt() == null || !org.smartregister.util.DateUtil
1✔
517
                .checkIfDateThreeMonthsOlder(serviceRecord.getCreatedAt());
1✔
518
        ///////////////////////////////////////////////////////////////////////
519
    }
520

521
}
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

© 2025 Coveralls, Inc