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

OpenSRP / opensrp-client-child / #792

pending completion
#792

Pull #330

github-actions

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

5222 of 9051 relevant lines covered (57.7%)

0.58 hits per line

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

68.55
opensrp-child/src/main/java/org/smartregister/child/util/Utils.java
1
package org.smartregister.child.util;
2

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

5
import android.app.Activity;
6
import android.content.ContentValues;
7
import android.content.res.Resources;
8
import android.graphics.Color;
9
import android.graphics.Typeface;
10
import android.text.Html;
11
import android.text.InputType;
12
import android.text.TextUtils;
13
import android.view.View;
14
import android.view.ViewGroup;
15
import android.widget.EditText;
16
import android.widget.LinearLayout;
17
import android.widget.TableRow;
18
import android.widget.TextView;
19

20
import androidx.annotation.NonNull;
21
import androidx.core.widget.TextViewCompat;
22

23
import com.google.common.collect.Lists;
24

25
import org.apache.commons.lang3.ArrayUtils;
26
import org.apache.commons.lang3.StringUtils;
27
import org.apache.commons.lang3.math.NumberUtils;
28
import org.apache.commons.lang3.time.DateUtils;
29
import org.greenrobot.eventbus.EventBus;
30
import org.jetbrains.annotations.NotNull;
31
import org.jetbrains.annotations.Nullable;
32
import org.joda.time.DateTime;
33
import org.joda.time.LocalDate;
34
import org.joda.time.Weeks;
35
import org.json.JSONArray;
36
import org.json.JSONException;
37
import org.json.JSONObject;
38
import org.opensrp.api.constants.Gender;
39
import org.smartregister.AllConstants;
40
import org.smartregister.Context;
41
import org.smartregister.CoreLibrary;
42
import org.smartregister.child.ChildLibrary;
43
import org.smartregister.child.R;
44
import org.smartregister.child.domain.ChildMetadata;
45
import org.smartregister.child.domain.EditWrapper;
46
import org.smartregister.child.event.BaseEvent;
47
import org.smartregister.child.event.ClientDirtyFlagEvent;
48
import org.smartregister.clientandeventmodel.DateUtil;
49
import org.smartregister.clientandeventmodel.Event;
50
import org.smartregister.clientandeventmodel.FormEntityConstants;
51
import org.smartregister.clientandeventmodel.Obs;
52
import org.smartregister.commonregistry.AllCommonsRepository;
53
import org.smartregister.commonregistry.CommonPersonObject;
54
import org.smartregister.commonregistry.CommonPersonObjectClient;
55
import org.smartregister.commonregistry.CommonRepository;
56
import org.smartregister.domain.tag.FormTag;
57
import org.smartregister.growthmonitoring.domain.Height;
58
import org.smartregister.growthmonitoring.domain.HeightWrapper;
59
import org.smartregister.growthmonitoring.domain.Weight;
60
import org.smartregister.growthmonitoring.domain.WeightWrapper;
61
import org.smartregister.growthmonitoring.repository.HeightRepository;
62
import org.smartregister.growthmonitoring.repository.WeightRepository;
63
import org.smartregister.growthmonitoring.service.intent.HeightIntentService;
64
import org.smartregister.growthmonitoring.service.intent.WeightIntentService;
65
import org.smartregister.immunization.ImmunizationLibrary;
66
import org.smartregister.immunization.db.VaccineRepo;
67
import org.smartregister.immunization.domain.Vaccine;
68
import org.smartregister.immunization.repository.VaccineRepository;
69
import org.smartregister.immunization.service.intent.VaccineIntentService;
70
import org.smartregister.repository.AllSharedPreferences;
71
import org.smartregister.repository.BaseRepository;
72
import org.smartregister.repository.UniqueIdRepository;
73

74
import java.text.DateFormat;
75
import java.text.NumberFormat;
76
import java.text.ParseException;
77
import java.text.SimpleDateFormat;
78
import java.util.ArrayList;
79
import java.util.Calendar;
80
import java.util.Collection;
81
import java.util.Date;
82
import java.util.HashMap;
83
import java.util.List;
84
import java.util.Locale;
85
import java.util.Map;
86
import java.util.TimeZone;
87
import java.util.concurrent.TimeUnit;
88

89
import timber.log.Timber;
90

91
/**
92
 * Created by ndegwamartin on 25/02/2019.
93
 */
94
public class Utils extends org.smartregister.util.Utils {
×
95
    public static final SimpleDateFormat DB_DF = new SimpleDateFormat(Constants.SQLITE_DATE_TIME_FORMAT);
1✔
96

97
    public static int getProfileImageResourceIDentifier() {
98
        return R.mipmap.ic_child;
×
99
    }
100

101
    public static TableRow getDataRow(android.content.Context context, String label, String value, TableRow row) {
102
        TableRow tr = row;
1✔
103
        if (row == null) {
1✔
104
            tr = new TableRow(context);
1✔
105
            TableRow.LayoutParams trlp =
1✔
106
                    new TableRow.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
107
            tr.setLayoutParams(trlp);
1✔
108
            tr.setPadding(10, 5, 10, 5);
1✔
109
        }
110

111
        TextView l = new TextView(context);
1✔
112
        l.setText(label + ": ");
1✔
113
        l.setPadding(20, 2, 20, 2);
1✔
114
        l.setTextColor(Color.BLACK);
1✔
115
        l.setTextSize(14);
1✔
116
        l.setBackgroundColor(Color.WHITE);
1✔
117
        tr.addView(l);
1✔
118

119
        TextView v = new TextView(context);
1✔
120
        v.setText(value);
1✔
121
        v.setPadding(20, 2, 20, 2);
1✔
122
        v.setTextColor(Color.BLACK);
1✔
123
        v.setTextSize(14);
1✔
124
        v.setBackgroundColor(Color.WHITE);
1✔
125
        tr.addView(v);
1✔
126

127
        return tr;
1✔
128
    }
129

130
    public static TableRow getDataRow(android.content.Context context, String label, String value, String field,
131
                                      TableRow row) {
132
        TableRow tr = row;
1✔
133
        if (row == null) {
1✔
134
            tr = new TableRow(context);
1✔
135
            TableRow.LayoutParams trlp =
1✔
136
                    new TableRow.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
137
            tr.setLayoutParams(trlp);
1✔
138
            tr.setPadding(10, 5, 10, 5);
1✔
139
        }
140

141
        TextView l = new TextView(context);
1✔
142
        l.setText(label + ": ");
1✔
143
        l.setPadding(20, 2, 20, 2);
1✔
144
        l.setTextColor(Color.BLACK);
1✔
145
        l.setTextSize(14);
1✔
146
        l.setBackgroundColor(Color.WHITE);
1✔
147
        tr.addView(l);
1✔
148

149
        EditWrapper editWrapper = new EditWrapper();
1✔
150
        editWrapper.setCurrentValue(value);
1✔
151
        editWrapper.setField(field);
1✔
152

153
        EditText e = new EditText(context);
1✔
154
        e.setTag(editWrapper);
1✔
155
        e.setText(value);
1✔
156
        e.setPadding(20, 2, 20, 2);
1✔
157
        e.setTextColor(Color.BLACK);
1✔
158
        e.setTextSize(14);
1✔
159
        e.setBackgroundColor(Color.WHITE);
1✔
160
        e.setInputType(InputType.TYPE_NULL);
1✔
161
        tr.addView(e);
1✔
162

163
        return tr;
1✔
164
    }
165

166
    public static TableRow getDataRow(android.content.Context context) {
167
        TableRow tr = new TableRow(context);
1✔
168
        TableRow.LayoutParams trlp =
1✔
169
                new TableRow.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
170
        tr.setLayoutParams(trlp);
1✔
171
        tr.setPadding(0, 0, 0, 0);
1✔
172
        // tr.setBackgroundColor(Color.BLUE);
173
        return tr;
1✔
174
    }
175

176
    public static int addAsInts(boolean ignoreEmpty, String... vals) {
177
        int i = 0;
×
178
        for (String v : vals) {
×
179
            i += ignoreEmpty && StringUtils.isBlank(v) ? 0 : Integer.parseInt(v);
×
180
        }
181
        return i;
×
182
    }
183

184
    public static TableRow addToRow(android.content.Context context, String value, TableRow row) {
185
        return addToRow(context, value, row, false, 1);
×
186
    }
187

188
    public static TableRow addToRow(android.content.Context context, String value, TableRow row, int weight) {
189
        return addToRow(context, value, row, false, weight);
×
190
    }
191

192
    public static TableRow addToRow(android.content.Context context, String value, TableRow row, boolean compact) {
193
        return addToRow(context, value, row, compact, 1);
×
194
    }
195

196
    public static void putAll(Map<String, String> map, Map<String, String> extend) {
197
        Collection<String> values = extend.values();
1✔
198
        while (true) {
199
            if (!(values.remove(null))) break;
1✔
200
        }
201
        map.putAll(extend);
1✔
202
    }
1✔
203

204
    public static void addVaccine(VaccineRepository vaccineRepository, Vaccine vaccine) {
205
        try {
206
            if (vaccineRepository == null || vaccine == null) {
1✔
207
                return;
1✔
208
            }
209

210
            //Update team and team_id before adding vaccine
211
            AllSharedPreferences allSharedPreferences = getAllSharedPreferences();
1✔
212
            String providerId = allSharedPreferences.fetchRegisteredANM();
1✔
213
            vaccine.setTeam(allSharedPreferences.fetchDefaultTeam(providerId));
1✔
214
            vaccine.setTeamId(allSharedPreferences.fetchDefaultTeamId(providerId));
1✔
215

216
            vaccine.setName(vaccine.getName().trim());
1✔
217
            // Add the vaccine
218
            vaccineRepository.add(vaccine);
1✔
219

220
            String name = vaccine.getName();
1✔
221
            if (!StringUtils.isBlank(name) && name.contains("/")) {
1✔
222

223
                updateFTSForCombinedVaccineAlternatives(vaccineRepository, vaccine);
×
224
            }
225

226
            if (!BaseRepository.TYPE_Synced.equals(vaccine.getSyncStatus()))
1✔
227
                Utils.postEvent(new ClientDirtyFlagEvent(vaccine.getBaseEntityId(), VaccineIntentService.EVENT_TYPE));
1✔
228

229
        } catch (Exception e) {
1✔
230
            Timber.e(e);
1✔
231
        }
1✔
232

233
    }
1✔
234

235
    /**
236
     * Update vaccines in the same group where either can be given. For example measles 1 / mr 1
237
     *
238
     * @param vaccineRepository
239
     * @param vaccine
240
     */
241
    public static void updateFTSForCombinedVaccineAlternatives(VaccineRepository vaccineRepository, Vaccine vaccine) {
242

243
        List<String> ftsVaccineNames = getAlternativeCombinedVaccines(VaccineRepository.removeHyphen(vaccine.getName()), ImmunizationLibrary.COMBINED_VACCINES_MAP);
×
244

245
        if (ftsVaccineNames != null) {
×
246

247
            for (String ftsVaccineName : ftsVaccineNames) {
×
248
                ftsVaccineName = VaccineRepository.addHyphen(ftsVaccineName.toLowerCase());
×
249
                Vaccine ftsVaccine = new Vaccine();
×
250
                ftsVaccine.setBaseEntityId(vaccine.getBaseEntityId());
×
251
                ftsVaccine.setName(ftsVaccineName);
×
252
                vaccineRepository.updateFtsSearch(ftsVaccine);
×
253
            }
×
254

255
        }
256
    }
×
257

258
    /**
259
     * @param vaccineName_       Vaccine whos alternative vaccines names must be found
260
     * @param combinedVaccineMap Combined vaccine map
261
     * @return list of alternative vaccines to {@code vaccineName_}
262
     */
263

264
    public static List<String> getAlternativeCombinedVaccines(String vaccineName_, Map<String, String> combinedVaccineMap) {
265

266
        List<String> comboVaccineList = null;
1✔
267

268
        String vaccineName = VaccineRepository.removeHyphen(vaccineName_);
1✔
269
        String comboVaccinesValue = combinedVaccineMap.get(vaccineName_);
1✔
270
        if (comboVaccinesValue != null) {
1✔
271

272
            String[] comboVaccines = StringUtils.stripAll(comboVaccinesValue.split("/"));
1✔
273

274
            comboVaccineList = Lists.newArrayList(comboVaccines);
1✔
275

276
            comboVaccineList.remove(vaccineName);
1✔
277
        }
278
        return comboVaccineList;
1✔
279

280
    }
281

282
    public static Date dobStringToDate(String dobString) {
283
        DateTime dateTime = dobStringToDateTime(dobString);
1✔
284
        if (dateTime != null) {
1✔
285
            return dateTime.toDate();
1✔
286
        }
287
        return null;
1✔
288
    }
289

290
    public static DateTime dobStringToDateTime(String dobString) {
291
        try {
292
            if (StringUtils.isBlank(dobString)) {
1✔
293
                return null;
1✔
294
            }
295
            return new DateTime(dobString);
1✔
296

297
        } catch (Exception e) {
1✔
298
            return null;
1✔
299
        }
300
    }
301

302
    public static String getTodaysDate() {
303
        return convertDateFormat(LocalDate.now().toDate(), DB_DF);
1✔
304
    }
305

306
    public static String convertDateFormat(Date date, SimpleDateFormat formatter) {
307

308
        return formatter.format(date);
1✔
309
    }
310

311
    public static void recordWeight(WeightRepository weightRepository, WeightWrapper weightWrapper, String syncStatus) {
312

313
        Weight weight = null;
1✔
314
        if (weightWrapper.getDbKey() != null) {
1✔
315
            weight = weightRepository.find(weightWrapper.getDbKey());
×
316
        }
317

318
        if (weight == null) {
1✔
319

320
            Date eventDate = weightWrapper.getUpdatedWeightDate().toDate();
1✔
321
            weight = weightRepository.findUniqueByDate(weightRepository.getWritableDatabase(), weightWrapper.getId(), eventDate);
1✔
322
        }
323

324
        weight = weight != null ? weight : new Weight();
1✔
325
        weight.setBaseEntityId(weightWrapper.getId());
1✔
326
        weight.setKg(weightWrapper.getWeight());
1✔
327
        weight.setDate(weightWrapper.isToday() ? Calendar.getInstance().getTime() : weightWrapper.getUpdatedWeightDate().toDate());
1✔
328
        //Update team, team_id and provider before recording weight
329
        AllSharedPreferences allSharedPreferences = getAllSharedPreferences();
1✔
330
        String providerId = allSharedPreferences.fetchRegisteredANM();
1✔
331
        weight.setTeam(allSharedPreferences.fetchDefaultTeam(providerId));
1✔
332
        weight.setTeamId(allSharedPreferences.fetchDefaultTeamId(providerId));
1✔
333
        weight.setAnmId(providerId);
1✔
334
        weight.setLocationId(ChildJsonFormUtils.getProviderLocationId(ChildLibrary.getInstance().context().applicationContext()));
1✔
335
        weight.setChildLocationId(ChildJsonFormUtils.getChildLocationId(allSharedPreferences.fetchDefaultLocalityId(weight.getAnmId()), allSharedPreferences));
1✔
336

337
        weight.setSyncStatus(syncStatus);
1✔
338

339
        Gender gender = Gender.UNKNOWN;
1✔
340
        String genderString = weightWrapper.getGender();
1✔
341
        if (Constants.GENDER.FEMALE.equalsIgnoreCase(genderString)) {
1✔
342
            gender = Gender.FEMALE;
1✔
343
        } else if (Constants.GENDER.MALE.equalsIgnoreCase(genderString)) {
1✔
344
            gender = Gender.MALE;
1✔
345
        }
346

347
        Date dob = Utils.dobStringToDate(weightWrapper.getDob());
1✔
348

349
        if (dob != null && gender != Gender.UNKNOWN) {
1✔
350
            weightRepository.add(dob, gender, weight);
1✔
351
        } else {
352
            weightRepository.add(weight);
1✔
353
        }
354

355
        weightWrapper.setDbKey(weight.getId());
1✔
356

357
        if (!BaseRepository.TYPE_Synced.equals(syncStatus))
1✔
358
            Utils.postEvent(new ClientDirtyFlagEvent(weight.getBaseEntityId(), WeightIntentService.EVENT_TYPE));
1✔
359

360
    }
1✔
361

362
    public static void recordHeight(HeightRepository heightRepository, HeightWrapper heightWrapper, String syncStatus) {
363
        if (heightWrapper != null && heightWrapper.getHeight() != null && heightWrapper.getId() != null) {
1✔
364
            Height height = new Height();
1✔
365
            if (heightWrapper.getDbKey() != null) {
1✔
366
                height = heightRepository.find(heightWrapper.getDbKey());
×
367
            }
368
            height.setBaseEntityId(heightWrapper.getId());
1✔
369
            height.setCm(heightWrapper.getHeight());
1✔
370
            height.setDate(heightWrapper.isToday() ? Calendar.getInstance().getTime() : heightWrapper.getUpdatedHeightDate().toDate());
1✔
371
            //Update team, team_id and provider before recording height
372
            AllSharedPreferences allSharedPreferences = getAllSharedPreferences();
1✔
373
            String providerId = allSharedPreferences.fetchRegisteredANM();
1✔
374
            height.setTeam(allSharedPreferences.fetchDefaultTeam(providerId));
1✔
375
            height.setTeamId(allSharedPreferences.fetchDefaultTeamId(providerId));
1✔
376
            height.setAnmId(ChildLibrary.getInstance().context().allSharedPreferences().fetchRegisteredANM());
1✔
377
            height.setLocationId(ChildJsonFormUtils.getProviderLocationId(ChildLibrary.getInstance().context().applicationContext()));
1✔
378
            height.setChildLocationId(ChildJsonFormUtils.getChildLocationId(allSharedPreferences.fetchDefaultLocalityId(height.getAnmId()), allSharedPreferences));
1✔
379
            height.setSyncStatus(syncStatus);
1✔
380

381
            Gender gender = Gender.UNKNOWN;
1✔
382
            String genderString = heightWrapper.getGender();
1✔
383
            if (Constants.GENDER.FEMALE.equalsIgnoreCase(genderString)) {
1✔
384
                gender = Gender.FEMALE;
1✔
385
            } else if (Constants.GENDER.MALE.equalsIgnoreCase(genderString)) {
1✔
386
                gender = Gender.MALE;
1✔
387
            }
388

389
            Date dob = Utils.dobStringToDate(heightWrapper.getDob());
1✔
390

391
            if (dob != null && gender != Gender.UNKNOWN) {
1✔
392
                heightRepository.add(dob, gender, height);
1✔
393
            } else {
394
                heightRepository.add(height);
1✔
395
            }
396

397
            heightWrapper.setDbKey(height.getId());
1✔
398

399
            if (!BaseRepository.TYPE_Synced.equals(syncStatus))
1✔
400
                Utils.postEvent(new ClientDirtyFlagEvent(height.getBaseEntityId(), HeightIntentService.EVENT_TYPE));
1✔
401
        }
402
    }
1✔
403

404
    public static Context context() {
405
        return ChildLibrary.getInstance().context();
1✔
406
    }
407

408
    public static ChildMetadata metadata() {
409
        return ChildLibrary.getInstance().metadata();
1✔
410
    }
411

412
    public static String updateGrowthValue(String value) {
413
        String growthValue = value;
1✔
414
        if (NumberUtils.isNumber(value) && Double.parseDouble(value) > 0) {
1✔
415
            if (!value.contains(".")) {
1✔
416
                growthValue = value + ".0";
1✔
417
            }
418
            return growthValue;
1✔
419
        }
420

421
        throw new IllegalArgumentException(value + " is not a positive number");
1✔
422
    }
423

424
    public static Map<String, String> getCleanMap(Map<String, String> rawDetails) {
425
        Map<String, String> clean = new HashMap<>();
1✔
426

427
        try {
428
            for (Map.Entry<String, String> entry : rawDetails.entrySet()) {
1✔
429
                String val = entry.getValue();
1✔
430
                if (!TextUtils.isEmpty(val) && !"null".equalsIgnoreCase(val)) {
1✔
431
                    clean.put(entry.getKey(), entry.getValue());
1✔
432
                }
433
            }
1✔
434
        } catch (Exception e) {
1✔
435
            Timber.e(e);
1✔
436
        }
1✔
437

438
        return clean;
1✔
439

440
    }
441

442
    public static String formatNumber(String raw) {
443
        try {
444

445
            NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
1✔
446
            nf.setGroupingUsed(false);
1✔
447
            return nf.format(NumberFormat.getInstance(Locale.ENGLISH).parse(raw));
1✔
448

449
        } catch (ParseException e) {
1✔
450
            return raw;
1✔
451
        }
452
    }
453

454
    public static String getTranslatedIdentifier(String key) {
455

456
        String myKey;
457
        try {
458
            myKey = ChildLibrary.getInstance().context().applicationContext().getString(ChildLibrary.getInstance().context().applicationContext().getResources().getIdentifier(key.toLowerCase(), "string", ChildLibrary.getInstance().context().applicationContext().getPackageName()));
×
459

460
        } catch (Resources.NotFoundException resourceNotFoundException) {
×
461
            myKey = key;
×
462
        }
×
463
        return myKey;
×
464
    }
465

466
    public static String bold(String textToBold) {
467
        return "<b>" + textToBold + "</b>";
×
468
    }
469

470
    public static Integer getWeeksDue(DateTime dueDate) {
471

472
        return dueDate != null ? Math.abs(Weeks.weeksBetween(new DateTime(), dueDate).getWeeks()) : null;
1✔
473
    }
474

475
    @NonNull
476
    public static String getChildBirthDate(@Nullable JSONObject jsonObject) throws JSONException {
477
        String childBirthDate = "";
1✔
478

479
        if (jsonObject != null && jsonObject.has(FormEntityConstants.Person.birthdate.toString())) {
1✔
480
            childBirthDate = jsonObject.getString(FormEntityConstants.Person.birthdate.toString());
1✔
481
        }
482

483
        return childBirthDate.contains("T") ? childBirthDate.substring(0, childBirthDate.indexOf('T')) : childBirthDate;
1✔
484
    }
485

486
    public static void updateLastInteractionWith(String baseEntityId, String tableName) {
487
        ContentValues contentValues = new ContentValues();
×
488
        contentValues.put(Constants.KEY.LAST_INTERACTED_WITH, Calendar.getInstance().getTimeInMillis());
×
489
        updateLastInteractionWith(baseEntityId, tableName, contentValues);
×
490
    }
×
491

492
    public static void updateLastInteractionWith(String baseEntityId, String tableName, ContentValues contentValues) {
493
        AllCommonsRepository allCommonsRepository = ChildLibrary.getInstance().context().allCommonsRepositoryobjects(tableName);
×
494
        allCommonsRepository.update(tableName, contentValues, baseEntityId);
×
495
        allCommonsRepository.updateSearch(baseEntityId);
×
496
    }
×
497

498
    public static String reverseHyphenatedString(String date) {
499

500
        String[] dateArray = date.split("-");
1✔
501
        ArrayUtils.reverse(dateArray);
1✔
502

503
        return StringUtils.join(dateArray, "-");
1✔
504
    }
505

506
    public static void postEvent(BaseEvent baseEvent) {
507

508
        EventBus eventBus = ChildLibrary.getInstance().getEventBus();
1✔
509

510
        if (eventBus != null && baseEvent != null)
1✔
511
            eventBus.post(baseEvent);
×
512
    }
1✔
513

514
    public static Date getDate(String eventDateStr) {
515
        Date date = null;
×
516
        if (StringUtils.isNotBlank(eventDateStr)) {
×
517
            try {
518
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ", Locale.ENGLISH);
×
519
                date = dateFormat.parse(eventDateStr);
×
520
            } catch (ParseException e) {
×
521
                try {
522
                    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH);
×
523
                    date = dateFormat.parse(eventDateStr);
×
524
                } catch (ParseException pe) {
×
525
                    try {
526
                        date = DateUtil.parseDate(eventDateStr);
×
527
                    } catch (ParseException pee) {
×
528
                        Timber.e(pee);
×
529
                    }
×
530
                }
×
531
            }
×
532
        }
533
        return date;
×
534
    }
535

536
    public static String getNextOpenMrsId() {
537
        UniqueIdRepository uniqueIdRepo = ChildLibrary.getInstance().getUniqueIdRepository();
1✔
538
        return uniqueIdRepo.getNextUniqueId() != null ? uniqueIdRepo.getNextUniqueId().getOpenmrsId() : "";
1✔
539
    }
540

541
    public static String localizeStateKey(@NonNull android.content.Context context, @NonNull String stateKey) {
542

543
        String correctedStateKey = formatAtBirthKey(stateKey);
1✔
544

545
        if (correctedStateKey.matches("^\\d.*\\n*")) {
1✔
546
            correctedStateKey = "_" + correctedStateKey;
1✔
547
        }
548

549
        return translate(context, correctedStateKey);
1✔
550
    }
551

552
    @NotNull
553
    public static String formatAtBirthKey(@NonNull String stateKey) {
554
        String correctedStateKey = stateKey.trim();
1✔
555

556
        if (correctedStateKey.equalsIgnoreCase("birth")) {
1✔
557
            correctedStateKey = "at_" + stateKey;
×
558
        }
559
        return correctedStateKey;
1✔
560
    }
561

562
    @NotNull
563
    public static TextView createGroupNameTextView(android.content.Context context, String rowGroupName) {
564
        TextView groupNameTextView = new TextView(context);
1✔
565
        groupNameTextView.setTypeface(Typeface.DEFAULT_BOLD);
1✔
566
        TextViewCompat.setTextAppearance(groupNameTextView, android.R.style.TextAppearance_DeviceDefault_Medium);
1✔
567
        groupNameTextView.setText(Utils.localizeStateKey(context, rowGroupName));
1✔
568
        groupNameTextView.setAllCaps(true);
1✔
569

570
        LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
1✔
571

572
        p.setMargins(0, 30, 0, 0);
1✔
573
        groupNameTextView.setLayoutParams(p);
1✔
574
        return groupNameTextView;
1✔
575
    }
576

577
    public static String formatIdentifiers(String raw) {
578
        return prettyFormat(raw, 4, '-');
1✔
579

580
    }
581

582
    public static String prettyFormat(String original, int interval, char separator) {
583

584
        StringBuilder sb = new StringBuilder(original);
1✔
585

586
        int bloc;
587
        for (int i = 0; i < original.length() / interval; i++) {
1✔
588
            bloc = (i + 1) * interval;
1✔
589
            if (bloc != original.length()) {
1✔
590
                sb.insert(bloc + i, separator);
×
591
            }
592
        }
593

594
        return sb.toString();
1✔
595
    }
596

597
    public static CommonPersonObject getEcChildDetails(String baseEntityId) {
598
        CommonRepository cr = CoreLibrary.getInstance().context().commonrepository(Utils.metadata().getRegisterQueryProvider().getChildDetailsTable());
1✔
599
        if (cr != null) {
1✔
600
            return cr.findByBaseEntityId(baseEntityId);
1✔
601
        }
602
        return null;
×
603
    }
604

605
    public static boolean isVaccineDue(@NonNull List<Vaccine> vaccineList, @NonNull Date dob, @NonNull org.smartregister.immunization.domain.jsonmapping.Vaccine vaccine, boolean allowedExpiredVaccineEntry) {
606
        Date dueDate = VaccineCalculator.getVaccineDueDate(vaccine, dob, vaccineList);
1✔
607
        Date expiryDate = VaccineCalculator.getVaccineExpiryDate(dob, vaccine);
1✔
608
        return (dueDate != null && (expiryDate == null || allowedExpiredVaccineEntry || expiryDate.after(Calendar.getInstance().getTime())));
1✔
609
    }
610

611
    @NonNull
612
    public static Event createArchiveRecordEvent(@NonNull String baseEntityId) throws Exception {
613
        FormTag formTag = ChildJsonFormUtils.formTag(getAllSharedPreferences());
×
614
        Event archiveRecordEvent = ChildJsonFormUtils.createEvent(new JSONArray(), new JSONObject(), formTag, baseEntityId, Constants.EventType.ARCHIVE_CHILD_RECORD, "");
×
615
        ChildJsonFormUtils.tagSyncMetadata(archiveRecordEvent);
×
616
        JSONObject eventJson = new JSONObject(ChildJsonFormUtils.gson.toJson(archiveRecordEvent));
×
617
        ChildLibrary.getInstance().getEcSyncHelper().addEvent(archiveRecordEvent.getBaseEntityId(), eventJson);
×
618
        return archiveRecordEvent;
×
619
    }
620

621
    public static List<Event> createArchiveRecordEvents(List<String> baseEntityIds) throws Exception {
622
        List<Event> archiveRecordEvents = new ArrayList<>();
×
623
        for (String baseEntityId : baseEntityIds) {
×
624
            Event archiveRecordEvent = createArchiveRecordEvent(baseEntityId);
×
625
            archiveRecordEvents.add(archiveRecordEvent);
×
626
        }
×
627
        return archiveRecordEvents;
×
628
    }
629

630
    public static void initiateEventProcessing(@Nullable List<String> formSubmissionIds) throws Exception {
631
        if (formSubmissionIds != null && !formSubmissionIds.isEmpty()) {
×
632
            long lastSyncTimeStamp = getAllSharedPreferences().fetchLastUpdatedAtDate(0);
×
633
            Date lastSyncDate = new Date(lastSyncTimeStamp);
×
634
            ChildLibrary.getInstance().getClientProcessorForJava().processClient(ChildLibrary.getInstance().getEcSyncHelper().getEvents(formSubmissionIds));
×
635
            getAllSharedPreferences().saveLastUpdatedAtDate(lastSyncDate.getTime());
×
636
        }
637
    }
×
638

639
    public static void refreshDataCaptureStrategyBanner(Activity context, String selectedLocation) {
640

641
        View dataCaptureStrategyView = context.findViewById(R.id.advanced_data_capture_strategy_wrapper);
1✔
642
        if (dataCaptureStrategyView != null) {
1✔
643
            ((TextView) context.findViewById(R.id.advanced_data_capture_strategy)).setText(context.getString(R.string.service_point, selectedLocation));
1✔
644
            dataCaptureStrategyView.setVisibility(AllConstants.DATA_CAPTURE_STRATEGY.ADVANCED.equals(CoreLibrary.getInstance().context().allSharedPreferences().fetchCurrentDataStrategy()) ? View.VISIBLE : View.GONE);
1✔
645
        }
646
    }
1✔
647

648
    public static Gender getGenderEnum(Map<String, String> childDetails) {
649
        Gender gender = Gender.UNKNOWN;
1✔
650
        String genderString = Utils.getValue(childDetails, AllConstants.ChildRegistrationFields.GENDER, false);
1✔
651
        if (genderString != null && genderString.equalsIgnoreCase(Constants.GENDER.FEMALE)) {
1✔
652
            gender = Gender.FEMALE;
×
653
        } else if (genderString != null && genderString.equalsIgnoreCase(Constants.GENDER.MALE)) {
1✔
654
            gender = Gender.MALE;
1✔
655
        }
656
        return gender;
1✔
657
    }
658

659
    public static boolean isSameDay(long timeA, long timeB, @Nullable TimeZone dateTimeZone) {
660
        Calendar calendarA = Calendar.getInstance();
×
661
        calendarA.setTimeInMillis(timeA);
×
662
        Calendar calendarB = Calendar.getInstance();
×
663
        calendarB.setTimeInMillis(timeB);
×
664
        return DateUtils.isSameDay(calendarA, calendarB);
×
665
    }
666

667
    public static void processExtraVaccinesEventObs(Event baseEvent, String vaccineField) {
668
        List<Obs> eventObs = baseEvent.getObs();
×
669
        ArrayList<String> vaccineLabels = new ArrayList<>();
×
670
        List<Obs> newObs = new ArrayList<>();
×
671
        int vaccinesCounter = 0;
×
672
        for (Obs obs : eventObs) {
×
673
            if (vaccineField.equalsIgnoreCase(obs.getFieldCode())) {
×
674
                vaccineLabels.add((String) obs.getHumanReadableValues().get(0));
×
675
                vaccinesCounter++;
×
676
            } else {
677
                newObs.add(obs);
×
678
            }
679
        }
×
680

681
        Obs vaccineObs = new Obs()
×
682
                .withFieldCode(Constants.KEY.SELECTED_VACCINES)
×
683
                .withFormSubmissionField(Constants.KEY.SELECTED_VACCINES)
×
684
                .withFieldDataType(Constants.KEY.TEXT)
×
685
                .withFieldType(Constants.KEY.CONCEPT)
×
686
                .withsaveObsAsArray(false)
×
687
                .withValue(StringUtils.join(vaccineLabels, ","));
×
688

689
        Obs vaccinesCounterObs = new Obs()
×
690
                .withFieldCode(Constants.KEY.SELECTED_VACCINES_COUNTER)
×
691
                .withFormSubmissionField(Constants.KEY.SELECTED_VACCINES_COUNTER)
×
692
                .withFieldDataType(Constants.KEY.TEXT)
×
693
                .withFieldType(Constants.KEY.CONCEPT)
×
694
                .withValue(vaccinesCounter)
×
695
                .withsaveObsAsArray(false);
×
696

697
        newObs.add(vaccineObs);
×
698
        newObs.add(vaccinesCounterObs);
×
699
        baseEvent.withObs(newObs);
×
700
    }
×
701

702
    public static void htmlEnhancedText(TextView textView, String bodyData) {
703
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
×
704
            textView.setText(Html.fromHtml(bodyData, Html.FROM_HTML_MODE_LEGACY));
×
705
        } else {
706
            textView.setText(Html.fromHtml(bodyData));
×
707
        }
708
    }
×
709

710
    /*
711
     *
712
     * Return true only if all the Second year vaccines are given with-in
713
     * Second year of child's life. Will return false if any vaccine which
714
     * was due in second year, given after second year of child's life
715
     * @param scheduleList              Child's vaccine schedules
716
     * @param dob                       Child's Date of birth
717
     * @param minDays                   Minimum limit in days
718
     * @param maxDays                   Maximum limit in days
719
     */
720
    public static boolean isAllVaccinesDoneWithIn(List<Map<String, Object>> scheduleList, DateTime dob, int minDays, int maxDays) {
721
        if (scheduleList == null || dob == null)
1✔
722
            return false;
1✔
723
        boolean isDone = true;
1✔
724
        for (Map<String, Object> schedule : scheduleList) {
1✔
725
            // Only check vaccines within First year of child's age
726
            if (((VaccineRepo.Vaccine) schedule.get(Constants.KEY.VACCINE)).milestoneGapDays() >= minDays
1✔
727
                    && ((VaccineRepo.Vaccine) schedule.get(Constants.KEY.VACCINE)).milestoneGapDays() < maxDays) {
1✔
728
                if (!((String) schedule.get(Constants.KEY.STATUS)).equalsIgnoreCase(Constants.KEY.DONE)
1✔
729
                        // Do not consider BCG 2 if BCG is already given
730
                        && !((VaccineRepo.Vaccine) schedule.get(Constants.KEY.VACCINE)).name().equalsIgnoreCase(Constants.VACCINE.BCG2)) {
1✔
731
                    isDone = false;
1✔
732
                } else if (((String) schedule.get(Constants.KEY.STATUS)).equalsIgnoreCase(Constants.KEY.DONE)
1✔
733
                        && !vaccineProvidedWithin(schedule, dob, maxDays)) {
1✔
734
                    isDone = false;
×
735
                }
736
            }
737
        }
1✔
738
        return isDone;
1✔
739
    }
740

741

742
    private static boolean vaccineProvidedWithin(Map<String, Object> schedule, DateTime dob, int days) {
743
        boolean providedWithin = false;
1✔
744
        DateTime date = (DateTime) schedule.get(Constants.DATE);
1✔
745
        if (date != null
1✔
746
                && ((date.getMillis() - dob.getMillis()) < TimeUnit.MILLISECONDS.convert(days, TimeUnit.DAYS))) {
1✔
747
            providedWithin = true;
1✔
748
        }
749
        return providedWithin;
1✔
750
    }
751

752
    /**
753
     * This method updates the Client document with the Child Status Attribute-Values e.g. Lost To Follow up with true or false values depending on state.
754
     * It also updates the child details passed as param of type CommonPersonObjectClient with the new status attribute/values for rendering on the view
755
     *
756
     * @param openSRPcontext The OpenSRP context
757
     * @param childDetails   The data object of type CommonPersonObjectClient holding the child details
758
     */
759
    public static void activateChildStatus(Context openSRPcontext, CommonPersonObjectClient childDetails) {
760
        try {
761
            Map<String, String> details = Utils.getEcChildDetails(childDetails.entityId()).getColumnmaps();
1✔
762
            CommonPersonObject commonPersonObject = new CommonPersonObject(details.get(Constants.KEY.BASE_ENTITY_ID), details.get(Constants.KEY.RELATIONALID), details, Constants.ENTITY.CHILD);
1✔
763

764
            String isInactive = details.get(Constants.CHILD_STATUS.INACTIVE);
1✔
765
            String isLostToFollowup = details.get(Constants.CHILD_STATUS.LOST_TO_FOLLOW_UP);
1✔
766

767
            Map<String, Object> childStatusAttributes = new HashMap<>();
1✔
768
            childStatusAttributes.put(Constants.CHILD_STATUS.INACTIVE, isInactive != null && isInactive.equalsIgnoreCase(Boolean.TRUE.toString()));
1✔
769
            childStatusAttributes.put(Constants.CHILD_STATUS.LOST_TO_FOLLOW_UP, isLostToFollowup != null && isLostToFollowup.equalsIgnoreCase(Boolean.TRUE.toString()));
1✔
770

771
            commonPersonObject.setColumnmaps(ChildJsonFormUtils.updateClientAttribute(openSRPcontext, childDetails, childStatusAttributes));
1✔
772

773
        } catch (Exception e) {
×
774
            Timber.e(e);
×
775
        }
1✔
776
    }
1✔
777

778
    public static boolean isChildHasNFCCard(Map<String, String> detailsMap) {
779
        return StringUtils.isNotEmpty(detailsMap.get(Constants.KEY.NFC_CARD_IDENTIFIER))
×
780
                && !Constants.TRUE.equalsIgnoreCase(detailsMap.getOrDefault(Constants.KEY.NFC_CARD_BLACKLISTED, Constants.FALSE));
×
781
    }
782

783
    public static boolean hasCompassRelationshipId(Map<String, String> detailsMap) {
784
        return StringUtils.isNotBlank(detailsMap.get(DBConstants.KEY.MOTHER_COMPASS_RELATIONSHIP_ID));
×
785
    }
786
}
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