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

OpenSRP / opensrp-client-child / #793

pending completion
#793

Pull #330

github-actions

web-flow
Merge 63b2e51ba 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

33.85
opensrp-child/src/main/java/org/smartregister/child/fragment/BaseAdvancedSearchFragment.java
1
package org.smartregister.child.fragment;
2

3
import android.app.ProgressDialog;
4
import android.content.BroadcastReceiver;
5
import android.content.Context;
6
import android.content.Intent;
7
import android.content.IntentFilter;
8
import android.database.Cursor;
9
import android.net.ConnectivityManager;
10
import android.os.Bundle;
11
import android.text.Editable;
12
import android.text.Html;
13
import android.text.TextUtils;
14
import android.text.TextWatcher;
15
import android.view.LayoutInflater;
16
import android.view.View;
17
import android.view.ViewGroup;
18
import android.widget.Button;
19
import android.widget.EditText;
20
import android.widget.ImageButton;
21
import android.widget.TextView;
22

23
import androidx.appcompat.app.AlertDialog;
24
import androidx.loader.content.CursorLoader;
25
import androidx.loader.content.Loader;
26

27
import com.vijay.jsonwizard.customviews.CheckBox;
28
import com.vijay.jsonwizard.customviews.RadioButton;
29
import com.vijay.jsonwizard.utils.FormUtils;
30

31
import org.apache.commons.lang3.StringUtils;
32
import org.jetbrains.annotations.NotNull;
33
import org.smartregister.child.ChildLibrary;
34
import org.smartregister.child.R;
35
import org.smartregister.child.activity.BaseChildImmunizationActivity;
36
import org.smartregister.child.activity.BaseChildRegisterActivity;
37
import org.smartregister.child.contract.ChildAdvancedSearchContract;
38
import org.smartregister.child.contract.ChildRegisterFragmentContract;
39
import org.smartregister.child.cursor.AdvancedMatrixCursor;
40
import org.smartregister.child.domain.MoveToCatchmentEvent;
41
import org.smartregister.child.domain.RegisterClickables;
42
import org.smartregister.child.domain.RepositoryHolder;
43
import org.smartregister.child.presenter.BaseChildAdvancedSearchPresenter;
44
import org.smartregister.child.provider.AdvancedSearchClientsProvider;
45
import org.smartregister.child.util.AppExecutors;
46
import org.smartregister.child.util.ChildAppProperties;
47
import org.smartregister.child.util.ChildJsonFormUtils;
48
import org.smartregister.child.util.Constants;
49
import org.smartregister.child.util.MoveToMyCatchmentUtils;
50
import org.smartregister.child.util.Utils;
51
import org.smartregister.child.widgets.AdvanceSearchDatePickerDialog;
52
import org.smartregister.commonregistry.CommonPersonObjectClient;
53
import org.smartregister.cursoradapter.RecyclerViewPaginatedAdapter;
54
import org.smartregister.cursoradapter.SmartRegisterQueryBuilder;
55
import org.smartregister.domain.FetchStatus;
56
import org.smartregister.event.Listener;
57
import org.smartregister.growthmonitoring.GrowthMonitoringLibrary;
58
import org.smartregister.immunization.ImmunizationLibrary;
59
import org.smartregister.receiver.SyncStatusBroadcastReceiver;
60
import org.smartregister.view.activity.BaseRegisterActivity;
61
import org.smartregister.view.activity.SecuredNativeSmartRegisterActivity;
62

63
import java.text.ParseException;
64
import java.text.SimpleDateFormat;
65
import java.util.Calendar;
66
import java.util.HashMap;
67
import java.util.List;
68
import java.util.Locale;
69
import java.util.Map;
70
import java.util.Set;
71

72
import timber.log.Timber;
73

74
public abstract class BaseAdvancedSearchFragment extends BaseChildRegisterFragment
×
75
        implements ChildAdvancedSearchContract.View, ChildRegisterFragmentContract.View, View.OnClickListener {
76
    public static final String START_DATE = "start_date";
77
    public static final String END_DATE = "end_date";
78
    private final Listener<MoveToCatchmentEvent> moveToMyCatchmentListener = moveToCatchmentEvent -> {
×
79
        if (moveToCatchmentEvent != null) {
×
80
            if (ChildJsonFormUtils.processMoveToCatchment(context(), moveToCatchmentEvent)) {
×
81
                clientAdapter.notifyDataSetChanged();
×
82
                ((BaseRegisterActivity) requireActivity()).refreshList(FetchStatus.fetched);
×
83
                ((BaseRegisterActivity) requireActivity()).switchToBaseFragment();
×
84

85
                Utils.showToast(requireActivity(), requireActivity().getString(R.string.move_to_catchment_success_message));
×
86
            } else {
87
                Utils.showShortToast(requireActivity(), requireActivity().getString(R.string.an_error_occured));
×
88
            }
89
        } else {
90
            Utils.showShortToast(requireActivity(), requireActivity().getString(R.string.unable_to_move_to_my_catchment));
×
91
        }
92
    };
×
93
    protected AdvancedSearchTextWatcher advancedSearchTextwatcher = new AdvancedSearchTextWatcher();
×
94
    protected HashMap<String, String> searchFormData = new HashMap<>();
×
95
    protected CheckBox active;
96
    protected CheckBox inactive;
97
    protected CheckBox lostToFollowUp;
98
    protected EditText startDate;
99
    protected EditText endDate;
100
    protected Button qrCodeButton;
101
    protected Map<String, View> advancedFormSearchableFields = new HashMap<>();
×
102
    private View listViewLayout;
103
    private View advancedSearchForm;
104
    private ImageButton backButton;
105
    private Button searchButton;
106
    private Button advancedSearchToolbarSearchButton;
107
    private RadioButton outsideInside;
108
    private RadioButton myCatchment;
109
    private TextView searchCriteria;
110
    private TextView matchingResults;
111
    private boolean listMode = false;
×
112
    private boolean isLocal = false;
×
113
    private BroadcastReceiver connectionChangeReciever;
114
    private boolean registeredConnectionChangeReceiver = false;
×
115
    private ProgressDialog progressDialog;
116
    private AdvanceSearchDatePickerDialog startDateDatePicker;
117
    private AdvanceSearchDatePickerDialog endDateDatePicker;
118
    private final SimpleDateFormat dateFormatter = new SimpleDateFormat(FormUtils.NATIIVE_FORM_DATE_FORMAT_PATTERN,
×
119
            Locale.getDefault().toString().startsWith("ar") ? Locale.ENGLISH : Locale.getDefault());
×
120

121
    @Override
122
    protected void initializePresenter() {
123
        presenter = getPresenter();
×
124
        initProgressDialog();
×
125

126
    }
×
127

128
    private void initProgressDialog() {
129
        progressDialog = new ProgressDialog(requireActivity());
×
130
        progressDialog.setCancelable(false);
×
131
    }
×
132

133
    protected abstract BaseChildAdvancedSearchPresenter getPresenter();
134

135
    @Override
136
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
137
        View view = inflater.inflate(R.layout.fragment_advanced_search, container, false);
1✔
138
        rootView = view;//handle to the root
1✔
139
        setupViews(view);
1✔
140
        onResumption();
1✔
141
        return view;
1✔
142
    }
143

144
    @Override
145
    public void setUserVisibleHint(boolean isVisibleToUser) {
146
        super.setUserVisibleHint(isVisibleToUser);
1✔
147
        if (isVisibleToUser) {
1✔
148
            switchViews(false);
1✔
149
            updateSearchLimits();
1✔
150
            resetForm();
1✔
151
        }
152
    }
1✔
153

154
    @Override
155
    public void onPause() {
156
        super.onPause();
×
157

158
        if (connectionChangeReciever != null && registeredConnectionChangeReceiver) {
×
159
            requireActivity().unregisterReceiver(connectionChangeReciever);
×
160
            registeredConnectionChangeReceiver = false;
×
161
        }
162
    }
×
163

164
    @Override
165
    public boolean onBackPressed() {
166
        goBack();
×
167
        return true;
×
168
    }
169

170
    @Override
171
    protected void goBack() {
172
        if (listMode) {
×
173
            switchViews(false);
×
174
        } else {
175
            ((BaseRegisterActivity) requireActivity()).switchToBaseFragment();
×
176
        }
177
    }
×
178

179
    @Override
180
    @SuppressWarnings("unchecked")
181
    protected void onViewClicked(View view) {
182
        if (view.getId() == R.id.record_growth && view.getTag() != null) {
×
183
            if (view.getTag() instanceof String) {
×
184
                recordService((String) view.getTag());
×
185
            } else if (view.getTag() instanceof CommonPersonObjectClient) {
×
186
                recordGrowth(view);
×
187
            }
188
        } else if (view.getId() == R.id.search) {
×
189
            search();
×
190
        } else if (view.getId() == R.id.advanced_form_search_btn) {
×
191
            search();
×
192
        } else if (view.getId() == R.id.back_button) {
×
193
            switchViews(false);
×
194
        } else if ((view.getId() == R.id.patient_column || view.getId() == R.id.child_profile_info_layout)
×
195
                && view.getTag() != null) {
×
196
            recordGrowth(view);
×
197
        } else if (view.getId() == R.id.move_to_catchment && view.getTag(R.id.move_to_catchment_ids) != null && view.getTag(R.id.move_to_catchment_ids) instanceof List) {
×
198
            List<String> ids = (List<String>) view.getTag(R.id.move_to_catchment_ids);
×
199
            moveToMyCatchmentArea(ids);
×
200
        }
201
    }
×
202

203
    private void recordGrowth(View view) {
204
        RegisterClickables registerClickables = new RegisterClickables();
×
205
        if (view.getTag(org.smartregister.child.R.id.record_action) != null) {
×
206
            registerClickables.setRecordWeight(Constants.RECORD_ACTION.GROWTH.equals(view.getTag(org.smartregister.child.R.id.record_action)));
×
207
            registerClickables.setRecordAll(Constants.RECORD_ACTION.VACCINATION.equals(view.getTag(org.smartregister.child.R.id.record_action)));
×
208
            registerClickables.setNextAppointmentDate(view.getTag(R.id.next_appointment_date) != null ? String.valueOf(view.getTag(R.id.next_appointment_date)) : "");
×
209
        }
210
        BaseChildImmunizationActivity.launchActivity(requireActivity(), (CommonPersonObjectClient) view.getTag(), registerClickables);
×
211
    }
×
212

213
    protected void recordService(String openSrpId) {
214
        try {
215
            ChildJsonFormUtils.startForm(requireActivity(), ChildJsonFormUtils.REQUEST_CODE_GET_JSON, getOutOfCatchmentServiceFormName(), openSrpId,
×
216
                    ChildJsonFormUtils.getProviderLocationId(requireContext()));
×
217
        } catch (Exception e) {
×
218
            Utils.showShortToast(requireActivity(), getString(R.string.error_recording_out_of_catchment_service));
×
219
            Timber.e(e, "Error recording Out of Catchment Service");
×
220
        }
×
221
    }
×
222

223
    protected String getOutOfCatchmentServiceFormName() {
224
        return Constants.JsonForm.OUT_OF_CATCHMENT_SERVICE;
×
225
    }
226

227
    private void moveToMyCatchmentArea(final List<String> ids) {
228
        if (ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.NOVEL.OUT_OF_CATCHMENT)) {
×
229

230
            showMoveToCatchmentChoiceDialog(ids);
×
231

232
        } else {
233

234
            showMoveToCatchmentDialog(ids, true);
×
235
        }
236
    }
×
237

238
    private void showMoveToCatchmentChoiceDialog(final List<String> ids) {
239

240
        AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
×
241
        builder.setTitle(requireActivity().getString(R.string.choose_how));
×
242

243
        String[] choices = {requireActivity().getString(R.string.permanently), requireActivity().getString(R.string.temporarily)};
×
244
        builder.setItems(choices, (dialog, which) -> showMoveToCatchmentDialog(ids, which == 0));
×
245
        AlertDialog dialog = builder.create();
×
246
        dialog.show();
×
247

248
    }
×
249

250
    private void showMoveToCatchmentDialog(final List<String> ids, final boolean isPermanent) {
251
        AlertDialog dialog = new AlertDialog.Builder(requireActivity(), R.style.PathAlertDialog)
×
252
                .setMessage(R.string.move_to_catchment_confirm_dialog_message)
×
253
                .setTitle(ChildLibrary.getInstance().getProperties().isTrue(ChildAppProperties.KEY.NOVEL.OUT_OF_CATCHMENT) ? requireActivity().getString(R.string.move_to_catchment_confirm_dialog_title_, isPermanent ? requireActivity().getString(R.string.permanently) : requireActivity().getString(R.string.temporarily)) : requireActivity().getString(R.string.move_to_catchment_confirm_dialog_title))
×
254
                .setCancelable(false)
×
255
                .setPositiveButton(R.string.no_button_label, null)
×
256
                .setNegativeButton(R.string.yes_button_label,
×
257
                        (dialog1, whichButton) -> {
258
                            progressDialog.setTitle(R.string.move_to_catchment_dialog_title);
×
259
                            progressDialog.setMessage(getString(R.string.move_to_catchment_dialog_message));
×
260
                            MoveToMyCatchmentUtils.moveToMyCatchment(ids, moveToMyCatchmentListener, progressDialog, isPermanent);
×
261
                        }).create();
×
262

263
        dialog.show();
×
264
    }
×
265

266
    @Override
267
    public void setupViews(View view) {
268
        super.setupViews(view);
×
269

270
        listViewLayout = view.findViewById(R.id.advanced_search_list);
×
271
        listViewLayout.setVisibility(View.GONE);
×
272

273
        advancedSearchForm = view.findViewById(R.id.advanced_search_form);
×
274
        backButton = view.findViewById(R.id.back_button);
×
275
        backButton.setOnClickListener(v -> onBackPressed());
×
276

277
        searchCriteria = view.findViewById(R.id.search_criteria);
×
278
        matchingResults = view.findViewById(R.id.matching_results);
×
279
        advancedSearchToolbarSearchButton = view.findViewById(R.id.search);
×
280
        searchButton = view.findViewById(R.id.advanced_form_search_btn);
×
281
        outsideInside = view.findViewById(R.id.out_and_inside);
×
282
        myCatchment = view.findViewById(R.id.my_catchment);
×
283

284
        populateFormViews(view);
×
285

286
        populateSearchableFields(view);
×
287

288
        resetForm();
×
289

290
    }
×
291

292
    public abstract void populateSearchableFields(View view);
293

294
    @Override
295
    public void initializeAdapter(Set<org.smartregister.configurableviews.model.View> visibleColumns) {
296

297
        RepositoryHolder repoHolder = new RepositoryHolder();
×
298

299
        repoHolder.setWeightRepository(GrowthMonitoringLibrary.getInstance().weightRepository());
×
300
        repoHolder.setHeightRepository(GrowthMonitoringLibrary.getInstance().heightRepository());
×
301
        repoHolder.setVaccineRepository(ImmunizationLibrary.getInstance().vaccineRepository());
×
302
        repoHolder.setCommonRepository(commonRepository());
×
303

304
        AdvancedSearchClientsProvider advancedSearchProvider = new AdvancedSearchClientsProvider(requireActivity(), repoHolder, visibleColumns, registerActionHandler, paginationViewHandler, ChildLibrary.getInstance().context().alertService());
×
305

306
        clientAdapter = new RecyclerViewPaginatedAdapter(null, advancedSearchProvider, context().commonrepository(this.tablename));
×
307
        clientsView.setAdapter(clientAdapter);
×
308
    }
×
309

310
    protected void populateFormViews(View view) {
311

312
        setUpSearchButtons();
1✔
313

314
        setUpMyCatchmentControls(view, outsideInside, myCatchment, R.id.out_and_inside_layout);
1✔
315

316
        setUpMyCatchmentControls(view, myCatchment, outsideInside, R.id.my_catchment_layout);
1✔
317

318
        startDate = view.findViewById(R.id.start_date);
1✔
319
        startDate.setTag(R.id.type, START_DATE);
1✔
320
        startDate.setOnClickListener(this);
1✔
321
        startDate.addTextChangedListener(new TextWatcher() {
1✔
322
            @Override
323
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
324
                //Overridden
325
            }
×
326

327
            @Override
328
            public void onTextChanged(CharSequence s, int start, int before, int count) {
329
                //Overridden
330
            }
×
331

332
            @Override
333
            public void afterTextChanged(Editable editable) {
334
                try {
335
                    if (StringUtils.isNoneBlank(editable))
×
336
                        endDateDatePicker.getDatePickerDialog().setMinDate(dateFormatter.parse(editable.toString()).getTime());
×
337
                } catch (ParseException e) {
×
338
                    Timber.e(e, "Error setting end date minimum to start date");
×
339
                }
×
340
                startDate.setError(null);
×
341
            }
×
342
        });
343
        startDateDatePicker = new AdvanceSearchDatePickerDialog(startDate);
1✔
344
        startDateDatePicker.setDateFormatter(dateFormatter);
1✔
345

346
        endDate = view.findViewById(R.id.end_date);
1✔
347
        endDate.setTag(R.id.type, END_DATE);
1✔
348
        endDate.setOnClickListener(this);
1✔
349
        endDate.setEnabled(false);
1✔
350
        endDateDatePicker = new AdvanceSearchDatePickerDialog(endDate);
1✔
351
        endDateDatePicker.setDateFormatter(dateFormatter);
1✔
352

353
        setUpQRCodeButton(view);
1✔
354

355
        setUpScanCardButton(view);
1✔
356

357
        setUpMyCatchmentControls(view, myCatchment, outsideInside, R.id.my_catchment_layout);
1✔
358

359
        active = view.findViewById(R.id.active);
1✔
360
        active.setOnCheckedChangeListener((compoundButton, isChecked) -> {
1✔
361
            if (!isChecked && !inactive.isChecked() && !lostToFollowUp.isChecked()) {
×
362
                active.setChecked(true);
×
363
            }
364
        });
×
365
        inactive = view.findViewById(R.id.inactive);
1✔
366
        inactive.setOnCheckedChangeListener((compoundButton, isChecked) -> {
1✔
367
            if (!isChecked && !active.isChecked() && !lostToFollowUp.isChecked()) {
×
368
                inactive.setChecked(true);
×
369
            }
370
        });
×
371
        lostToFollowUp = view.findViewById(R.id.lost_to_follow_up);
1✔
372
        lostToFollowUp.setOnCheckedChangeListener((compoundButton, isChecked) -> {
1✔
373
            if (!isChecked && !active.isChecked() && !inactive.isChecked()) {
×
374
                lostToFollowUp.setChecked(true);
×
375
            }
376
        });
×
377

378
        final View activeLayout = view.findViewById(R.id.active_layout);
1✔
379
        activeLayout.setOnClickListener(v -> active.toggle());
1✔
380

381
        final View inactiveLayout = view.findViewById(R.id.inactive_layout);
1✔
382
        inactiveLayout.setOnClickListener(v -> inactive.toggle());
1✔
383

384
        final View lostToFollowUpLayout = view.findViewById(R.id.lost_to_follow_up_layout);
1✔
385
        lostToFollowUpLayout.setOnClickListener(v -> lostToFollowUp.toggle());
1✔
386
    }
1✔
387

388
    private void setUpMyCatchmentControls(View view, final RadioButton myCatchment,
389
                                          final RadioButton outsideInside, int p) {
390
        myCatchment.setOnCheckedChangeListener((buttonView, isChecked) -> {
1✔
391
            // Trigger for myCatchment only, when there is no internet connectivity
392
            if (!Utils.isConnectedToNetwork(requireActivity()) && myCatchment.getId() == R.id.my_catchment) {
×
393
                outsideInside.setChecked(false);
×
394
                myCatchment.setChecked(true);
×
395
            } else {
396
                outsideInside.setChecked(!isChecked);
×
397
            }
398
        });
×
399

400
        View myCatchmentLayout = view.findViewById(p);
1✔
401
        myCatchmentLayout.setOnClickListener(v -> myCatchment.toggle());
1✔
402
    }
1✔
403

404
    private void setUpSearchButtons() {
405
        advancedSearchToolbarSearchButton.setEnabled(false);
1✔
406
        advancedSearchToolbarSearchButton.setTextColor(getResources().getColor(R.color.contact_complete_grey_border));
1✔
407
        advancedSearchToolbarSearchButton.setOnClickListener(registerActionHandler);
1✔
408

409
        searchButton.setEnabled(false);
1✔
410
        searchButton.setTextColor(getResources().getColor(R.color.contact_complete_grey_border));
1✔
411
        searchButton.setOnClickListener(registerActionHandler);
1✔
412
    }
1✔
413

414
    private void setUpQRCodeButton(View view) {
415
        qrCodeButton = view.findViewById(R.id.qrCodeButton);
1✔
416
        if (!ChildLibrary.getInstance().getProperties().hasProperty(ChildAppProperties.KEY.FEATURE_SCAN_QR_ENABLED) || ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.FEATURE_SCAN_QR_ENABLED)) {
1✔
417
            qrCodeButton.setOnClickListener(view1 -> {
1✔
418
                if (requireActivity() == null) {
×
419
                    return;
×
420
                }
421
                BaseRegisterActivity baseRegisterActivity = (BaseRegisterActivity) requireActivity();
×
422
                baseRegisterActivity.startQrCodeScanner();
×
423

424
                ((BaseChildRegisterActivity) requireActivity()).setAdvancedSearch(true);
×
425
                ((BaseChildRegisterActivity) requireActivity()).setAdvancedSearchFormData(createSelectedFieldMap());
×
426
            });
×
427
        } else {
428
            qrCodeButton.setVisibility(View.GONE);
×
429
        }
430
    }
1✔
431

432
    private void setUpScanCardButton(View view) {
433
        Button scanCardButton = view.findViewById(R.id.scanCardButton);
1✔
434

435
        if (ChildLibrary.getInstance().getProperties().getPropertyBoolean(ChildAppProperties.KEY.FEATURE_NFC_CARD_ENABLED)) {
1✔
436
            scanCardButton.setVisibility(View.VISIBLE);//should be visible
1✔
437

438
            ((View) view.findViewById(R.id.card_id).getParent()).setVisibility(View.VISIBLE);
1✔
439
        }
440
    }
1✔
441

442
    public abstract void assignedValuesBeforeBarcode();
443

444
    protected abstract HashMap<String, String> createSelectedFieldMap();
445

446
    private void checkTextFields() {
447
        if (anySearchableFieldHasValue()) {
1✔
448
            advancedSearchToolbarSearchButton.setEnabled(true);
1✔
449
            advancedSearchToolbarSearchButton.setTextColor(getResources().getColor(R.color.white));
1✔
450

451
            searchButton.setEnabled(true);
1✔
452
            searchButton.setTextColor(getResources().getColor(R.color.white));
1✔
453
        } else {
454
            advancedSearchToolbarSearchButton.setEnabled(false);
1✔
455
            advancedSearchToolbarSearchButton.setTextColor(getResources().getColor(R.color.contact_complete_grey_border));
1✔
456

457
            searchButton.setEnabled(false);
1✔
458
            searchButton.setTextColor(getResources().getColor(R.color.contact_complete_grey_border));
1✔
459
        }
460
    }
1✔
461

462
    private boolean anySearchableFieldHasValue() {
463
        for (Map.Entry<String, View> entry : advancedFormSearchableFields.entrySet()) {
1✔
464
            if (entry.getValue() instanceof TextView && !TextUtils.isEmpty(((TextView) entry.getValue()).getText())) {
1✔
465
                return true;
1✔
466
            }
467
        }
×
468
        return false;
1✔
469
    }
470

471

472
    @Override
473
    public void switchViews(boolean showList) {
474
        if (showList) {
1✔
475
            Utils.hideKeyboard(requireActivity());
1✔
476

477
            advancedSearchForm.setVisibility(View.GONE);
1✔
478
            listViewLayout.setVisibility(View.VISIBLE);
1✔
479
            clientsView.setVisibility(View.VISIBLE);
1✔
480
            backButton.setVisibility(View.VISIBLE);
1✔
481
            searchButton.setVisibility(View.GONE);
1✔
482
            advancedSearchToolbarSearchButton.setVisibility(View.GONE);
1✔
483

484
            if (titleLabelView != null) {
1✔
485
                titleLabelView.setText(getString(R.string.search_results));
1✔
486
            }
487

488
            // hide result count , should be dynamic
489
            if (matchingResults != null) {
1✔
490
                matchingResults.setVisibility(View.GONE);
1✔
491
            }
492

493
            showProgressView();
1✔
494
            listMode = true;
1✔
495
        } else {
496
            clearSearchCriteria();
1✔
497
            advancedSearchForm.setVisibility(View.VISIBLE);
1✔
498
            listViewLayout.setVisibility(View.GONE);
1✔
499
            clientsView.setVisibility(View.INVISIBLE);
1✔
500
            searchButton.setVisibility(View.VISIBLE);
1✔
501
            advancedSearchToolbarSearchButton.setVisibility(View.VISIBLE);
1✔
502

503
            if (titleLabelView != null) {
1✔
504
                titleLabelView.setText(getString(R.string.advanced_search));
1✔
505
            }
506

507
            listMode = false;
1✔
508
        }
509
    }
1✔
510

511
    private void updateSearchLimits() {
512
        if (Utils.isConnectedToNetwork(requireActivity())) {
1✔
513
            outsideInside.setChecked(true);
1✔
514
            myCatchment.setChecked(false);
1✔
515
        } else {
516
            outsideInside.setChecked(false);
1✔
517
            myCatchment.setChecked(true);
1✔
518
        }
519

520
        if (connectionChangeReciever == null) {
1✔
521
            connectionChangeReciever = new BroadcastReceiver() {
1✔
522
                @Override
523
                public void onReceive(Context context, Intent intent) {
524
                    if (!Utils.isConnectedToNetwork(requireActivity())) {
×
525
                        outsideInside.setChecked(false);
×
526
                        myCatchment.setChecked(true);
×
527
                    }
528
                }
×
529
            };
530

531
            IntentFilter intentFilter = new IntentFilter();
1✔
532
            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
1✔
533
            requireActivity().registerReceiver(connectionChangeReciever, intentFilter);
1✔
534
            registeredConnectionChangeReceiver = true;
1✔
535
        }
536

537
    }
1✔
538

539
    private void resetForm() {
540
        clearSearchCriteria();
1✔
541
        clearMatchingResults();
1✔
542
        clearFormFields();
1✔
543
    }
1✔
544

545

546
    protected void clearFormFields() {
547
        active.setChecked(true);
1✔
548
        inactive.setChecked(false);
1✔
549
        lostToFollowUp.setChecked(false);
1✔
550
        startDate.setText("");
1✔
551
        endDate.setText("");
1✔
552
    }
1✔
553

554
    private void clearSearchCriteria() {
555
        if (searchCriteria != null) {
1✔
556
            searchCriteria.setVisibility(View.GONE);
1✔
557
            searchCriteria.setText("");
1✔
558
        }
559
    }
1✔
560

561
    private void clearMatchingResults() {
562
        if (matchingResults != null) {
1✔
563
            matchingResults.setVisibility(View.GONE);
1✔
564
            matchingResults.setText("");
1✔
565
        }
566
    }
1✔
567

568
    @Override
569
    public void updateMatchingResults(int count) {
570
        if (matchingResults != null) {
×
571
            matchingResults.setText(getString(R.string.matching_results, String.valueOf(count)));
×
572
            matchingResults.setVisibility(View.VISIBLE);
×
573
        }
574
    }
×
575

576
    @Override
577
    public void updateSearchCriteria(String searchCriteriaString) {
578
        if (searchCriteria != null) {
×
579
            searchCriteria.setText(Html.fromHtml(searchCriteriaString));
×
580
            searchCriteria.setVisibility(View.VISIBLE);
×
581
        }
582
    }
×
583

584
    @Override
585
    public void setupSearchView(View view) {
586
        // TODO implement this
587
    }
×
588

589
    @Override
590
    protected SecuredNativeSmartRegisterActivity.DefaultOptionsProvider getDefaultOptionsProvider() {
591
        return null;
×
592
    }
593

594
    @Override
595
    protected String getMainCondition() {
596
        return ((BaseChildAdvancedSearchPresenter) presenter).getCurrentCondition();
×
597
    }
598

599
    public void search() {
600
        if (myCatchment.isChecked()) {
×
601
            isLocal = true;
×
602
        } else if (outsideInside.isChecked()) {
×
603
            isLocal = false;
×
604
        }
605

606
        Map<String, String> editMap = getSearchMap(!isLocal);
×
607

608
        //Do not search when only one of the birth dates are provided
609
        if (editMap.containsKey(START_DATE) && !editMap.containsKey(END_DATE)) {
×
610
            endDate.setError(getString(R.string.end_date_required));
×
611
            return;
×
612
        }
613
        if (editMap.containsKey(END_DATE) && !editMap.containsKey(START_DATE)) {
×
614
            startDate.setError(getString(R.string.start_date_required));
×
615
            return;
×
616
        }
617

618
        ((ChildAdvancedSearchContract.Presenter) presenter).search(editMap, isLocal);
×
619
    }
×
620

621
    protected abstract Map<String, String> getSearchMap(boolean outOfArea);
622

623
    @Override
624
    public void recalculatePagination(AdvancedMatrixCursor matrixCursor) {
625
        super.recalculatePagination(matrixCursor);
×
626
        updateMatchingResults(clientAdapter.getTotalcount());
×
627
    }
×
628

629
    @Override
630
    public void showNotFoundPopup(String opensrpID) {
631
        //Todo implement this
632
    }
×
633

634
    @Override
635
    public void setAdvancedSearchFormData(HashMap<String, String> advancedSearchFormData) {
636
        this.searchFormData = advancedSearchFormData;
×
637
    }
×
638

639
    @Override
640
    public void countExecute() {
641
        try {
642
            AppExecutors appExecutors = new AppExecutors();
×
643
            appExecutors.diskIO().execute(new Runnable() {
×
644
                @Override
645
                public void run() {
646
                    String sql = ((BaseChildAdvancedSearchPresenter) presenter).getCountQuery();
×
647
                    Timber.i(sql);
×
648
                    int totalCount = commonRepository().countSearchIds(sql);
×
649
                    appExecutors.mainThread().execute(new Runnable() {
×
650
                        @Override
651
                        public void run() {
652
                            clientAdapter.setTotalcount(totalCount);
×
653
                            Timber.i("Total Register Count %d", clientAdapter.getTotalcount());
×
654
                            updateMatchingResults(totalCount);
×
655

656
                            clientAdapter.setCurrentlimit(getPageLimit());
×
657
                            clientAdapter.setCurrentoffset(0);
×
658
                        }
×
659
                    });
660
                }
×
661
            });
662

663

664
        } catch (Exception e) {
×
665
            Timber.e(e);
×
666
        }
×
667

668
    }
×
669

670
    @Override
671
    public @NotNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
672
        if (id == LOADER_ID) {
×
673
            return new AdvanceSearchCursorLoader(this);
×
674
        }
675
        return new CursorLoader(requireContext());
×
676
    }
677

678

679
    @Override
680
    public String filterAndSortQuery() {
681
        SmartRegisterQueryBuilder sqb = new SmartRegisterQueryBuilder(mainSelect);
×
682

683
        String query = "";
×
684
        try {
685
            sqb.addCondition(filters);
×
686
            query = sqb.orderbyCondition(Sortqueries);
×
687
            query = sqb.Endquery(
×
688
                    sqb.addlimitandOffset(query, clientAdapter.getCurrentlimit(), clientAdapter.getCurrentoffset()));
×
689
        } catch (Exception e) {
×
690
            Timber.e(e);
×
691
        }
×
692

693
        return query;
×
694
    }
695

696
    @Override
697
    public Cursor getRawCustomQueryForAdapter(String query) {
698
        return commonRepository().rawCustomQueryForAdapter(query);
×
699
    }
700

701
    @Override
702
    public void onResume() {
703
        super.onResume();
×
704
        assignedValuesBeforeBarcode();
×
705
        //Do not show for sync status on advance search screen
706
        SyncStatusBroadcastReceiver.getInstance().removeSyncStatusListener(this);
×
707
    }
×
708

709
    private class AdvancedSearchTextWatcher implements TextWatcher {
×
710

711
        @Override
712
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
713
            //Todo later
714
        }
×
715

716
        @Override
717
        public void onTextChanged(CharSequence s, int start, int before, int count) {
718
            checkTextFields();
×
719
        }
×
720

721
        @Override
722
        public void afterTextChanged(Editable s) {
723
            checkTextFields();
×
724
        }
×
725
    }
726

727
    static class AdvanceSearchCursorLoader extends CursorLoader {
728

729
        private final BaseAdvancedSearchFragment advancedSearchFragment;
730

731
        public AdvanceSearchCursorLoader(BaseAdvancedSearchFragment advancedSearchFragment) {
732
            super(advancedSearchFragment.requireActivity());
×
733
            this.advancedSearchFragment = advancedSearchFragment;
×
734
        }
×
735

736
        @Override
737
        public Cursor loadInBackground() {
738
            AdvancedMatrixCursor matrixCursor = ((BaseChildAdvancedSearchPresenter) advancedSearchFragment.presenter).getMatrixCursor();
×
739
            advancedSearchFragment.requireActivity();
×
740
            if (advancedSearchFragment.isLocal || matrixCursor == null) {
×
741
                String query = advancedSearchFragment.filterAndSortQuery();
×
742
                Cursor cursor = advancedSearchFragment.commonRepository().rawCustomQueryForAdapter(query);
×
743
                advancedSearchFragment.requireActivity().runOnUiThread(advancedSearchFragment::hideProgressView);
×
744
                return cursor;
×
745
            } else {
746
                return matrixCursor;
×
747
            }
748
        }
749
    }
750

751
    @Override
752
    public void onClick(View view) {
753
        if (view instanceof EditText) {
×
754
            Calendar currentDate = Calendar.getInstance();
×
755
            final EditText editText = (EditText) view;
×
756
            String previousDateString = editText.getText().toString();
×
757
            if (StringUtils.isNoneBlank(previousDateString)) {
×
758
                try {
759
                    currentDate.setTime(dateFormatter.parse(previousDateString));
×
760
                } catch (ParseException e) {
×
761
                    Timber.e(e, "Error parsing Advance Search Date: %s", e.getMessage());
×
762
                }
×
763
            }
764

765
            if (editText.getTag(R.id.type).equals(START_DATE)) {
×
766
                startDateDatePicker.setCurrentDate(currentDate);
×
767
                startDateDatePicker.showDialog();
×
768
                endDate.setEnabled(true);
×
769
                startDate.setError(null);
×
770
            } else if (editText.getTag(R.id.type).equals(END_DATE)) {
×
771
                endDate.setError(null);
×
772
                endDateDatePicker.setCurrentDate(currentDate);
×
773
                endDateDatePicker.showDialog();
×
774
            }
775
        }
776
    }
×
777

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