Skip to content

Commit 8e647c6

Browse files
committed
fix ISE when synchronizing claims
1 parent 48b6f26 commit 8e647c6

4 files changed

Lines changed: 162 additions & 40 deletions

File tree

claimManagement/src/main/java/org/openimis/imisclaims/ClaimActivity.java

Lines changed: 147 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
import android.database.Cursor;
1111
import android.inputmethodservice.Keyboard;
1212
import android.os.Bundle;
13+
import android.text.Editable;
1314
import android.text.InputType;
15+
import android.text.TextWatcher;
1416
import android.view.Menu;
1517
import android.view.MenuInflater;
1618
import android.view.MenuItem;
@@ -93,7 +95,32 @@ public static Intent newIntent(@NonNull Context context, @NonNull String claimUU
9395
RadioButton rbEmergency, rbReferral, rbOther, rbPositive, rbNegative;
9496
ImageButton btnScan;
9597
LinearLayout llFagepFields;
96-
TextInputLayout ettClaimPrefix, ettGuaranteeNo;
98+
TextInputLayout ettClaimPrefix, ettGuaranteeNo, ettClaimCode;
99+
private volatile ValidationResult latestValidationResult;
100+
101+
private static class LocalClaimCodeValidationResult {
102+
private final boolean valid;
103+
private final String errorMessage;
104+
105+
private LocalClaimCodeValidationResult(boolean valid, String errorMessage) {
106+
this.valid = valid;
107+
this.errorMessage = errorMessage;
108+
}
109+
}
110+
111+
private static class ValidationResult {
112+
private final boolean valid;
113+
private final View errorView;
114+
private final String errorMessage;
115+
private final LocalClaimCodeValidationResult localClaimCodeValidationResult;
116+
117+
private ValidationResult(boolean valid, View errorView, String errorMessage, LocalClaimCodeValidationResult localClaimCodeValidationResult) {
118+
this.valid = valid;
119+
this.errorView = errorView;
120+
this.errorMessage = errorMessage;
121+
this.localClaimCodeValidationResult = localClaimCodeValidationResult;
122+
}
123+
}
97124

98125
@Override
99126
protected void onCreate(Bundle savedInstanceState) {
@@ -140,6 +167,10 @@ protected void onCreate(Bundle savedInstanceState) {
140167
etVisitType = findViewById(R.id.etVisitType);
141168
ettClaimPrefix = findViewById(R.id.ettClaimPrefix);
142169
ettGuaranteeNo = findViewById(R.id.ettGuaranteeNo);
170+
View claimCodeParent = (View) etClaimCode.getParent();
171+
if (claimCodeParent instanceof TextInputLayout) {
172+
ettClaimCode = (TextInputLayout) claimCodeParent;
173+
}
143174

144175
String[] visitTypes = getResources().getStringArray(R.array.visitType);
145176
ArrayAdapter<String> visitTypeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, visitTypes);
@@ -170,6 +201,25 @@ public void onItemClick(AdapterView<?> adapterView, View view, int position, lon
170201
rgVisitType.setVisibility(View.GONE);
171202
ettGuaranteeNo.setVisibility(View.GONE);
172203

204+
TextWatcher claimCodeUniquenessWatcher = new TextWatcher() {
205+
@Override
206+
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
207+
// no-op
208+
}
209+
210+
@Override
211+
public void onTextChanged(CharSequence s, int start, int before, int count) {
212+
// no-op
213+
}
214+
215+
@Override
216+
public void afterTextChanged(Editable s) {
217+
validateLocalClaimCodeUniqueness();
218+
}
219+
};
220+
etClaimCode.addTextChangedListener(claimCodeUniquenessWatcher);
221+
etClaimPrefix.addTextChangedListener(claimCodeUniquenessWatcher);
222+
173223
tvItemTotal.setText("0");
174224
tvServiceTotal.setText("0");
175225

@@ -267,7 +317,14 @@ public void onItemClick(AdapterView<?> adapterView, View view, int position, lon
267317
btnPost.setOnClickListener(v -> {
268318
progressDialog = ProgressDialog.show(this, "", getResources().getString(R.string.Processing));
269319
runOnNewThread(
270-
() -> isValidData() && saveClaim(),
320+
() -> {
321+
ValidationResult validationResult = validateDataForSubmission();
322+
latestValidationResult = validationResult;
323+
if (!validationResult.valid) {
324+
return false;
325+
}
326+
return saveClaim();
327+
},
271328
() -> runOnUiThread(() -> {
272329
ClearForm();
273330
progressDialog.dismiss();
@@ -278,7 +335,12 @@ public void onItemClick(AdapterView<?> adapterView, View view, int position, lon
278335
}
279336
}));
280337
}),
281-
() -> progressDialog.dismiss(),
338+
() -> runOnUiThread(() -> {
339+
if (latestValidationResult != null) {
340+
renderValidationResult(latestValidationResult);
341+
}
342+
progressDialog.dismiss();
343+
}),
282344
500
283345
);
284346
});
@@ -756,26 +818,23 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
756818
}
757819
}
758820

759-
private boolean isValidData() {
821+
private ValidationResult validateDataForSubmission() {
822+
LocalClaimCodeValidationResult localClaimCodeValidationResult = checkLocalClaimCodeUniqueness();
760823

761824
if (etHealthFacility.getText().length() == 0) {
762-
showValidationDialog(etHealthFacility, getResources().getString(R.string.MissingHealthFacility));
763-
return false;
825+
return invalidValidationResult(etHealthFacility, getResources().getString(R.string.MissingHealthFacility), localClaimCodeValidationResult);
764826
}
765827

766828
if (sqlHandler.getAdjustability("ClaimAdministrator").equals("M") && etClaimAdmin.getText().length() == 0) {
767-
showValidationDialog(etClaimAdmin, getResources().getString(R.string.MissingClaimAdmin));
768-
return false;
829+
return invalidValidationResult(etClaimAdmin, getResources().getString(R.string.MissingClaimAdmin), localClaimCodeValidationResult);
769830
}
770831

771832
if (etClaimCode.getText().length() == 0) {
772-
showValidationDialog(etClaimCode, getResources().getString(R.string.MissingClaimCode));
773-
return false;
833+
return invalidValidationResult(etClaimCode, getResources().getString(R.string.MissingClaimCode), localClaimCodeValidationResult);
774834
}
775835

776836
if (etInsureeNumber.getText().length() == 0) {
777-
showValidationDialog(etInsureeNumber, getResources().getString(R.string.MissingCHFID));
778-
return false;
837+
return invalidValidationResult(etInsureeNumber, getResources().getString(R.string.MissingCHFID), localClaimCodeValidationResult);
779838
}
780839

781840
/*if (!etProgram.getText().toString().equals("VIH")) {
@@ -787,18 +846,15 @@ private boolean isValidData() {
787846
}*/
788847

789848
if (!isValidInsureeNumber()) {
790-
showValidationDialog(etInsureeNumber, getResources().getString(R.string.InvalidCHFID));
791-
return false;
849+
return invalidValidationResult(etInsureeNumber, getResources().getString(R.string.InvalidCHFID), localClaimCodeValidationResult);
792850
}
793851

794852
if (etStartDate.getText().length() == 0) {
795-
showValidationDialog(etStartDate, getResources().getString(R.string.MissingStartDate));
796-
return false;
853+
return invalidValidationResult(etStartDate, getResources().getString(R.string.MissingStartDate), localClaimCodeValidationResult);
797854
}
798855

799856
if (etEndDate.getText().length() == 0) {
800-
showValidationDialog(etEndDate, getResources().getString(R.string.MissingEndDate));
801-
return false;
857+
return invalidValidationResult(etEndDate, getResources().getString(R.string.MissingEndDate), localClaimCodeValidationResult);
802858
}
803859

804860
try {
@@ -810,36 +866,34 @@ private boolean isValidData() {
810866
Date End_date = DateUtils.dateFromString(EndDate);
811867

812868
if (End_date.after(Current_date)) {
813-
showValidationDialog(etEndDate, getResources().getString(R.string.AfterCurrentDate));
814-
return false;
869+
return invalidValidationResult(etEndDate, getResources().getString(R.string.AfterCurrentDate), localClaimCodeValidationResult);
815870
}
816871

817872
if (Start_date.after(End_date)) {
818-
showValidationDialog(etEndDate, getResources().getString(R.string.BiggerDate));
819-
return false;
873+
return invalidValidationResult(etEndDate, getResources().getString(R.string.BiggerDate), localClaimCodeValidationResult);
820874
}
821875
} catch (Exception e) {
822876
Log.e(LOG_TAG, "Error while parsing dates", e);
823877
}
824878

825879
if (etDiagnosis.getText().length() == 0) {
826-
showValidationDialog(etDiagnosis, getResources().getString(R.string.MissingDisease));
827-
return false;
880+
return invalidValidationResult(etDiagnosis, getResources().getString(R.string.MissingDisease), localClaimCodeValidationResult);
828881
}
829882

830883
if (etProgram.getText().length() == 0) {
831-
showValidationDialog(etProgram, getResources().getString(R.string.MissingProgram));
832-
return false;
884+
return invalidValidationResult(etProgram, getResources().getString(R.string.MissingProgram), localClaimCodeValidationResult);
833885
}
834886

835887
if(etClaimPrefix.getText().length() == 0){
836-
showValidationDialog(etClaimPrefix, getResources().getString(R.string.MissingChequeNumber));
837-
return false;
888+
return invalidValidationResult(etClaimPrefix, getResources().getString(R.string.MissingChequeNumber), localClaimCodeValidationResult);
838889
}
839890

840891
if(etClaimCode.getText().length() > 7){
841-
showValidationDialog(etClaimPrefix, getResources().getString(R.string.InvalidClaimCode));
842-
return false;
892+
return invalidValidationResult(etClaimPrefix, getResources().getString(R.string.InvalidClaimCode), localClaimCodeValidationResult);
893+
}
894+
895+
if (!localClaimCodeValidationResult.valid) {
896+
return invalidValidationResult(etClaimCode, localClaimCodeValidationResult.errorMessage, localClaimCodeValidationResult);
843897
}
844898

845899
// if (rgVisitType.getCheckedRadioButtonId() == -1) {
@@ -848,26 +902,22 @@ private boolean isValidData() {
848902
// }
849903

850904
if(etVisitType.getText().toString().isEmpty()){
851-
showValidationDialog(rgVisitType, getResources().getString(R.string.MissingVisitType));
852-
return false;
905+
return invalidValidationResult(rgVisitType, getResources().getString(R.string.MissingVisitType), localClaimCodeValidationResult);
853906
}
854907

855908
if (Float.parseFloat(tvItemTotal.getText().toString()) + Float.parseFloat(tvServiceTotal.getText().toString()) == 0) {
856-
showValidationDialog(tvItemTotal, getResources().getString(R.string.MissingClaim));
857-
return false;
909+
return invalidValidationResult(tvItemTotal, getResources().getString(R.string.MissingClaim), localClaimCodeValidationResult);
858910
}
859911

860912
if(prefixProgramCode.equals("PAL")){
861913
if(etTestNumber.getText().length() == 0){
862-
showValidationDialog(etClaimPrefix, getResources().getString(R.string.MissingTestNumber));
863-
return false;
914+
return invalidValidationResult(etClaimPrefix, getResources().getString(R.string.MissingTestNumber), localClaimCodeValidationResult);
864915
}
865916
if(rgTdr.getCheckedRadioButtonId() == -1){
866-
showValidationDialog(etClaimPrefix, getResources().getString(R.string.MissingTdr));
867-
return false;
917+
return invalidValidationResult(etClaimPrefix, getResources().getString(R.string.MissingTdr), localClaimCodeValidationResult);
868918
}
869919
}
870-
return true;
920+
return new ValidationResult(true, null, null, localClaimCodeValidationResult);
871921
}
872922

873923
private boolean isValidInsureeNumber() {
@@ -970,4 +1020,62 @@ private boolean saveClaim() {
9701020
return true;
9711021
}
9721022

1023+
private LocalClaimCodeValidationResult checkLocalClaimCodeUniqueness() {
1024+
if (getIntent().hasExtra(EXTRA_CLAIM_UUID)) {
1025+
return new LocalClaimCodeValidationResult(true, null);
1026+
}
1027+
String finalCode = etClaimPrefix.getText().toString() + etClaimCode.getText().toString();
1028+
if (finalCode.trim().isEmpty()) {
1029+
return new LocalClaimCodeValidationResult(true, null);
1030+
}
1031+
1032+
boolean exists = sqlHandler.existsClaimCode(finalCode);
1033+
if (exists) {
1034+
String errorMessage = getResources().getString(R.string.ClaimNumberExist);
1035+
return new LocalClaimCodeValidationResult(false, errorMessage);
1036+
}
1037+
return new LocalClaimCodeValidationResult(true, null);
1038+
}
1039+
1040+
private void renderLocalClaimCodeError(@NonNull LocalClaimCodeValidationResult result) {
1041+
if (ettClaimCode != null) {
1042+
if (result.valid) {
1043+
ettClaimCode.setError(null);
1044+
ettClaimCode.setErrorEnabled(false);
1045+
} else {
1046+
ettClaimCode.setErrorEnabled(true);
1047+
ettClaimCode.setError(result.errorMessage);
1048+
}
1049+
return;
1050+
}
1051+
if (result.valid) {
1052+
etClaimCode.setError(null);
1053+
} else {
1054+
etClaimCode.setError(result.errorMessage);
1055+
}
1056+
}
1057+
1058+
private boolean validateLocalClaimCodeUniqueness() {
1059+
LocalClaimCodeValidationResult result = checkLocalClaimCodeUniqueness();
1060+
renderLocalClaimCodeError(result);
1061+
return result.valid;
1062+
}
1063+
1064+
private ValidationResult invalidValidationResult(@NonNull View errorView, @NonNull String errorMessage, @NonNull LocalClaimCodeValidationResult localClaimCodeValidationResult) {
1065+
return new ValidationResult(false, errorView, errorMessage, localClaimCodeValidationResult);
1066+
}
1067+
1068+
private void renderValidationResult(@NonNull ValidationResult result) {
1069+
renderLocalClaimCodeError(result.localClaimCodeValidationResult);
1070+
if (result.valid) {
1071+
return;
1072+
}
1073+
showDialog(result.errorMessage, (dialog, which) -> {
1074+
if (result.errorView instanceof EditText) {
1075+
EditText editText = (EditText) result.errorView;
1076+
editText.requestFocus();
1077+
}
1078+
});
1079+
}
1080+
9731081
}

claimManagement/src/main/java/org/openimis/imisclaims/ImisActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ protected void runOnNewThread(@NonNull Supplier<Boolean> task, @NonNull Runnable
344344
}
345345
}
346346

347+
// Callbacks are executed on this worker thread.
348+
// Any UI updates inside callbacks must be wrapped in runOnUiThread(...).
347349
if (result) {
348350
onTaskSucceed.run();
349351
} else {

claimManagement/src/main/java/org/openimis/imisclaims/SQLHandler.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,18 @@ public String getClaimUUIDForCode(@NonNull String claimCode) {
11941194
return null;
11951195
}
11961196

1197+
public boolean existsClaimCode(@NonNull String claimCode) {
1198+
try (Cursor cursor = db.rawQuery(
1199+
"SELECT 1 FROM tblClaimDetails WHERE LOWER(ClaimCode) = LOWER(?) LIMIT 1",
1200+
new String[]{claimCode}
1201+
)) {
1202+
return cursor != null && cursor.moveToFirst();
1203+
} catch (Exception e) {
1204+
Log.e(LOG_TAG, "Error while checking claim code uniqueness", e);
1205+
return false;
1206+
}
1207+
}
1208+
11971209
@NonNull
11981210
public JSONObject getClaimCounts() {
11991211
JSONArray claimCounts = getQueryResultAsJsonArray(

claimManagement/src/main/java/org/openimis/imisclaims/usecase/CreateClaim.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ public Integer execute(
3737
) throws Exception {
3838
return checkMutation.execute(
3939
createClaimGraphQLRequest.create(claim,hfId ,adminId, insureeId, programId, diagnosisId, programCode),
40-
"Error while creating policy for beneficiary '" + claim.getClaimNumber() + "'");
40+
"Error while creating claim No '" + claim.getClaimNumber() + "'");
4141
}
4242
}

0 commit comments

Comments
 (0)