From 84576f82166a786ec9dfc2ec4910668ab203fdc6 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Fri, 8 Nov 2024 10:58:29 +0530 Subject: [PATCH 1/7] Setup payment info feature Setup payment info feature --- .../layout/fragment_connect_payment_setup.xml | 158 +++++++++++++ app/res/navigation/nav_graph_connect.xml | 8 + app/res/values/strings.xml | 3 + .../connect/network/ApiConnectId.java | 11 + .../connect/ConnectJobsListsFragment.java | 7 + .../connect/ConnectPaymentSetupFragment.java | 208 ++++++++++++++++++ 6 files changed, 395 insertions(+) create mode 100644 app/res/layout/fragment_connect_payment_setup.xml create mode 100644 app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java diff --git a/app/res/layout/fragment_connect_payment_setup.xml b/app/res/layout/fragment_connect_payment_setup.xml new file mode 100644 index 0000000000..67e7741500 --- /dev/null +++ b/app/res/layout/fragment_connect_payment_setup.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/navigation/nav_graph_connect.xml b/app/res/navigation/nav_graph_connect.xml index fa43c71a4a..7d29f83bde 100644 --- a/app/res/navigation/nav_graph_connect.xml +++ b/app/res/navigation/nav_graph_connect.xml @@ -29,6 +29,9 @@ + + diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml index 9947841d10..c248ce1556 100644 --- a/app/res/values/strings.xml +++ b/app/res/values/strings.xml @@ -42,6 +42,8 @@ https://%s/api/payment/%s/confirm https://connectid.dimagi.com/users/recover/initiate_deactivation https://connectid.dimagi.com/users/recover/confirm_deactivation + https://connectid.dimagi.com/users/profile/payment_phone_number + https://connectid.dimagi.com/users/profile/confirm_payment_otp @@ -868,5 +870,6 @@ ₹ %s Daily Limit reached. No Payment for submitting forms Over Limit + Payment Info diff --git a/app/src/org/commcare/connect/network/ApiConnectId.java b/app/src/org/commcare/connect/network/ApiConnectId.java index f330c39316..d1e202738f 100644 --- a/app/src/org/commcare/connect/network/ApiConnectId.java +++ b/app/src/org/commcare/connect/network/ApiConnectId.java @@ -424,4 +424,15 @@ public static boolean confirmUserDeactivation(Context context, String phone, Str return ConnectNetworkHelper.post(context, context.getString(urlId), API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } + + public static boolean paymentInfo(Context context, String phone, IApiCallback callback) { + int urlId = R.string.ConnectPaymentPhoneNumberURL; + AuthInfo authInfo = new AuthInfo.NoAuth(); + + HashMap params = new HashMap<>(); + params.put("phone_number", phone); + + return ConnectNetworkHelper.post(context, context.getString(urlId), + API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); + } } diff --git a/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java b/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java index 9e55709982..b54fd73aa2 100644 --- a/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java @@ -96,6 +96,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, ConnectManager.launchApp(getActivity(), isLearning, appId); }; + view.findViewById(R.id.connect_jobs_last_update).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Navigation.findNavController(view).navigate(ConnectJobsListsFragmentDirections.actionConnectJobsListFragmentToConnectPaymentSetupFragment()); + } + }); + refreshUi(); refreshData(); diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java new file mode 100644 index 0000000000..82d4b7805a --- /dev/null +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java @@ -0,0 +1,208 @@ +package org.commcare.fragments.connect; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.google.android.gms.auth.api.identity.Identity; +import com.google.android.gms.common.api.ApiException; + +import org.commcare.connect.network.ApiConnectId; +import org.commcare.connect.network.IApiCallback; +import org.commcare.dalvik.R; +import org.commcare.dalvik.databinding.FragmentConnectPaymentSetupBinding; +import org.commcare.utils.PhoneNumberHelper; +import org.javarosa.core.io.StreamsUtil; +import org.javarosa.core.services.Logger; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; + +public class ConnectPaymentSetupFragment extends Fragment { + + private FragmentConnectPaymentSetupBinding binding; + protected boolean skipPhoneNumberCheck = false; + private boolean showhPhoneDialog = true; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentConnectPaymentSetupBinding.inflate(inflater, container, false); + getActivity().setTitle(getString(R.string.connect_payment_info)); + clickListeners(); + + View.OnFocusChangeListener listener = (v, hasFocus) -> { + if (hasFocus && showhPhoneDialog) { + PhoneNumberHelper.requestPhoneNumberHint(getActivity()); + showhPhoneDialog = false; + } + }; + + PhoneNumberHelper.phoneNumberHintLauncher = registerForActivityResult( + new ActivityResultContracts.StartIntentSenderForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + Intent data = result.getData(); + String phoneNumber; + try { + phoneNumber = Identity.getSignInClient(requireActivity()).getPhoneNumberFromIntent(data); + displayNumber(phoneNumber); + } catch (ApiException e) { + Toast.makeText(getContext(), R.string.error_occured, Toast.LENGTH_SHORT).show(); + throw new RuntimeException(e); + } + } + } + ); + + binding.connectPrimaryPhoneInput.setOnFocusChangeListener(listener); + binding.countryCode.setOnFocusChangeListener(listener); + + binding.connectPrimaryPhoneInput.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + updateButtonEnabled(); + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + binding.countryCode.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (!s.toString().contains("+")) { + binding.countryCode.setText("+" + binding.countryCode.getText()); + } + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + updateButtonEnabled(); + + return binding.getRoot(); + } + + private void clickListeners() { + binding.continueButton.setOnClickListener(view -> { + submitPaymentDetail(); + }); + } + + private void submitPaymentDetail() { + String phone = PhoneNumberHelper.buildPhoneNumber(binding.countryCode.getText().toString(), + binding.connectPrimaryPhoneInput.getText().toString()); + boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + try { + String responseAsString = new String( + StreamsUtil.inputStreamToByteArray(responseData)); + JSONObject json = new JSONObject(responseAsString); + + } catch (IOException | JSONException e) { + Logger.exception("Parsing return from confirm_secondary_otp", e); + } + + } + + @Override + public void processFailure(int responseCode, IOException e) { + binding.errorTextView.setVisibility(View.VISIBLE); + binding.errorTextView.setText(String.format(Locale.getDefault(), "Registration error: %d", + responseCode)); + } + + @Override + public void processNetworkFailure() { + Toast.makeText(requireActivity(), R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); + + } + + @Override + public void processOldApiError() { + Toast.makeText(requireActivity(), R.string.recovery_network_outdated, Toast.LENGTH_SHORT).show(); + } + }); + + if (isBusy) { + Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); + } + } + + public void updateButtonEnabled() { + String phone = PhoneNumberHelper.buildPhoneNumber(binding.countryCode.getText().toString(), + binding.connectPrimaryPhoneInput.getText().toString()); + + boolean valid = PhoneNumberHelper.isValidPhoneNumber(getContext(), phone); + + boolean isEnabled = valid && + binding.nameTextValue.getText().toString().length() > 0; + binding.continueButton.setEnabled(isEnabled); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + String phone = PhoneNumberHelper.handlePhoneNumberPickerResult(requestCode, resultCode, data, getActivity()); + skipPhoneNumberCheck = false; + displayNumber(phone); + } + + void displayNumber(String fullNumber) { + int code = PhoneNumberHelper.getCountryCode(getContext()); + if (fullNumber != null && fullNumber.length() > 0) { + code = PhoneNumberHelper.getCountryCode(getContext(), fullNumber); + } + + String codeText = ""; + if (code > 0) { + codeText = String.format(Locale.getDefault(), "%d", code); + if (!codeText.startsWith("+")) { + codeText = "+" + codeText; + } + } + + if (fullNumber != null && fullNumber.startsWith(codeText)) { + fullNumber = fullNumber.substring(codeText.length()); + } + skipPhoneNumberCheck = false; + binding.connectPrimaryPhoneInput.setText(fullNumber); + skipPhoneNumberCheck = true; + binding.countryCode.setText(codeText); + skipPhoneNumberCheck = false; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} From a12722320cbcbcc378916cc0113b5360219bf50c Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Mon, 11 Nov 2024 12:07:35 +0530 Subject: [PATCH 2/7] Set OTP verification screen Set OTP verification screen and APIs --- .../screen_connect_payment_phone_verify.xml | 139 +++++++ app/res/navigation/nav_graph_connect.xml | 22 +- .../commcare/connect/ConnectConstants.java | 1 + .../connect/network/ApiConnectId.java | 13 + .../connect/ConnectPaymentSetupFragment.java | 83 ++-- ...PaymentSetupPhoneVerificationFragment.java | 362 ++++++++++++++++++ 6 files changed, 575 insertions(+), 45 deletions(-) create mode 100644 app/res/layout/screen_connect_payment_phone_verify.xml create mode 100644 app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java diff --git a/app/res/layout/screen_connect_payment_phone_verify.xml b/app/res/layout/screen_connect_payment_phone_verify.xml new file mode 100644 index 0000000000..bb204df753 --- /dev/null +++ b/app/res/layout/screen_connect_payment_phone_verify.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/navigation/nav_graph_connect.xml b/app/res/navigation/nav_graph_connect.xml index 7d29f83bde..be38c3fa97 100644 --- a/app/res/navigation/nav_graph_connect.xml +++ b/app/res/navigation/nav_graph_connect.xml @@ -157,6 +157,24 @@ android:id="@+id/connectPaymentSetupFragment" android:name="org.commcare.fragments.connect.ConnectPaymentSetupFragment" android:label="fragment_connect_payment_setup" - tools:layout="@layout/fragment_connect_payment_setup" /> - + tools:layout="@layout/fragment_connect_payment_setup"> + + + + + + diff --git a/app/src/org/commcare/connect/ConnectConstants.java b/app/src/org/commcare/connect/ConnectConstants.java index 325e1e9005..c38ff2b315 100644 --- a/app/src/org/commcare/connect/ConnectConstants.java +++ b/app/src/org/commcare/connect/ConnectConstants.java @@ -72,4 +72,5 @@ public class ConnectConstants { public final static int CONNECT_USER_DEACTIVATE_CONFIRMATION = ConnectConstants.ConnectIdTaskIdOffset + 40; public final static int CONNECT_VERIFY_USER_DEACTIVATE = ConnectConstants.ConnectIdTaskIdOffset + 41; public final static int CONNECT_USER_DEACTIVATE_SUCCESS = ConnectConstants.ConnectIdTaskIdOffset + 42; + public final static int CONNECT_PAYMENT_SETUP = ConnectConstants.ConnectIdTaskIdOffset + 43; } diff --git a/app/src/org/commcare/connect/network/ApiConnectId.java b/app/src/org/commcare/connect/network/ApiConnectId.java index d1e202738f..c2e2588dfd 100644 --- a/app/src/org/commcare/connect/network/ApiConnectId.java +++ b/app/src/org/commcare/connect/network/ApiConnectId.java @@ -435,4 +435,17 @@ public static boolean paymentInfo(Context context, String phone, IApiCallback ca return ConnectNetworkHelper.post(context, context.getString(urlId), API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } + + public static boolean confirmPaymentInfo(Context context,String phone,String secret, String token, IApiCallback callback) { + int urlId = R.string.ConnectConfirmPaymentOtpURL; + AuthInfo authInfo = new AuthInfo.NoAuth(); + + HashMap params = new HashMap<>(); + params.put("phone_number", phone); + params.put("secret_key", secret); + params.put("token", token); + + return ConnectNetworkHelper.post(context, context.getString(urlId), + API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); + } } diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java index 82d4b7805a..a12a474ce2 100644 --- a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java @@ -13,22 +13,15 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; import com.google.android.gms.auth.api.identity.Identity; import com.google.android.gms.common.api.ApiException; -import org.commcare.connect.network.ApiConnectId; -import org.commcare.connect.network.IApiCallback; import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.FragmentConnectPaymentSetupBinding; import org.commcare.utils.PhoneNumberHelper; -import org.javarosa.core.io.StreamsUtil; -import org.javarosa.core.services.Logger; -import org.json.JSONException; -import org.json.JSONObject; -import java.io.IOException; -import java.io.InputStream; import java.util.Locale; public class ConnectPaymentSetupFragment extends Fragment { @@ -119,42 +112,46 @@ private void clickListeners() { private void submitPaymentDetail() { String phone = PhoneNumberHelper.buildPhoneNumber(binding.countryCode.getText().toString(), binding.connectPrimaryPhoneInput.getText().toString()); - boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, new IApiCallback() { - @Override - public void processSuccess(int responseCode, InputStream responseData) { - try { - String responseAsString = new String( - StreamsUtil.inputStreamToByteArray(responseData)); - JSONObject json = new JSONObject(responseAsString); - - } catch (IOException | JSONException e) { - Logger.exception("Parsing return from confirm_secondary_otp", e); - } - - } - - @Override - public void processFailure(int responseCode, IOException e) { - binding.errorTextView.setVisibility(View.VISIBLE); - binding.errorTextView.setText(String.format(Locale.getDefault(), "Registration error: %d", - responseCode)); - } - - @Override - public void processNetworkFailure() { - Toast.makeText(requireActivity(), R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); - - } - - @Override - public void processOldApiError() { - Toast.makeText(requireActivity(), R.string.recovery_network_outdated, Toast.LENGTH_SHORT).show(); - } - }); - if (isBusy) { - Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); - } + Navigation.findNavController(binding.continueButton).navigate( + ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone)); + +// boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, new IApiCallback() { +// @Override +// public void processSuccess(int responseCode, InputStream responseData) { +// try { +// String responseAsString = new String( +// StreamsUtil.inputStreamToByteArray(responseData)); +// JSONObject json = new JSONObject(responseAsString); +// +// } catch (IOException | JSONException e) { +// Logger.exception("Parsing return from confirm_secondary_otp", e); +// } +// +// } +// +// @Override +// public void processFailure(int responseCode, IOException e) { +// binding.errorTextView.setVisibility(View.VISIBLE); +// binding.errorTextView.setText(String.format(Locale.getDefault(), "Registration error: %d", +// responseCode)); +// } +// +// @Override +// public void processNetworkFailure() { +// Toast.makeText(requireActivity(), R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); +// +// } +// +// @Override +// public void processOldApiError() { +// Toast.makeText(requireActivity(), R.string.recovery_network_outdated, Toast.LENGTH_SHORT).show(); +// } +// }); +// +// if (isBusy) { +// Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); +// } } public void updateButtonEnabled() { diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java new file mode 100644 index 0000000000..59904be73a --- /dev/null +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java @@ -0,0 +1,362 @@ +package org.commcare.fragments.connect; + +import static android.app.Activity.RESULT_OK; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; + +import com.google.android.gms.auth.api.phone.SmsRetriever; +import com.google.android.gms.auth.api.phone.SmsRetrieverClient; + +import org.commcare.connect.SMSBroadcastReceiver; +import org.commcare.connect.SMSListener; +import org.commcare.dalvik.R; +import org.commcare.dalvik.databinding.ScreenConnectPaymentPhoneVerifyBinding; +import org.commcare.utils.KeyboardHelper; +import org.joda.time.DateTime; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ConnectPaymentSetupPhoneVerificationFragment#newInstance} factory method to + * create an instance of requireActivity() fragment. + */ +public class ConnectPaymentSetupPhoneVerificationFragment extends Fragment { + public static final int MethodUserDeactivate = 5; + public static final int REQ_USER_CONSENT = 200; + private String primaryPhone; + private String username; + private String password; + private SMSBroadcastReceiver smsBroadcastReceiver; + private DateTime smsTime = null; + + private ScreenConnectPaymentPhoneVerifyBinding binding; + + private final Handler taskHandler = new Handler(); + + private final Runnable runnable = new Runnable() { + @Override + public void run() { + int secondsToReset = -1; + if (smsTime != null) { + double elapsedMinutes = ((new DateTime()).getMillis() - smsTime.getMillis()) / 60000.0; + int resendLimitMinutes = 2; + double minutesRemaining = resendLimitMinutes - elapsedMinutes; + if (minutesRemaining > 0) { + secondsToReset = (int) Math.ceil(minutesRemaining * 60); + } + } + + boolean allowResend = secondsToReset < 0; + + setResendEnabled(allowResend); + + String text = allowResend ? + getString(R.string.connect_verify_phone_resend) : + getString(R.string.connect_verify_phone_resend_wait, secondsToReset); + + binding.connectPhoneVerifyResend.setText(text); + taskHandler.postDelayed(this, 100); + } + }; + + + public ConnectPaymentSetupPhoneVerificationFragment() { + // Required empty public constructor + } + + public static ConnectPaymentSetupPhoneVerificationFragment newInstance() { + ConnectPaymentSetupPhoneVerificationFragment fragment = new ConnectPaymentSetupPhoneVerificationFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for requireActivity() fragment + binding = ScreenConnectPaymentPhoneVerifyBinding.inflate(inflater, container, false); + View view = binding.getRoot(); + binding.connectPhoneVerifyButton.setEnabled(false); + getActivity().setTitle(getString(R.string.connect_verify_phone_title)); + buttonEnabled(""); + SmsRetrieverClient client = SmsRetriever.getClient(getActivity());// starting the SmsRetriever API + client.startSmsUserConsent(null); + + + if (getArguments() != null) { +// method = Integer.parseInt(Objects.requireNonNull(ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getMethod())); + primaryPhone = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPhone(); +// allowChange = (ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getAllowChange()); +// username = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getUsername(); +// password = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPassword(); +// recoveryPhone = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getSecondaryPhone(); +// callingClass = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getCallingClass(); +// deactivateButton = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getDeactivateButton(); + } + + updateMessage(); + +// requestSmsCode(); + + startHandler(); + +// binding.connectPhoneVerifyResend.setOnClickListener(arg0 -> requestSmsCode()); + binding.connectPhoneVerifyButton.setOnClickListener(arg0 -> verifySmsCode()); + binding.connectPhoneVerifyCode.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + buttonEnabled(s.toString()); + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + return view; + } + + private void buttonEnabled(String code) { + binding.connectPhoneVerifyButton.setEnabled(!code.isEmpty() && code.length() > 5); + } + + @Override + public void onStart() { + super.onStart(); + registerBrodcastReciever(); + + } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == REQ_USER_CONSENT && (resultCode == RESULT_OK) && data != null) { + String message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE); + getOtpFromMessage(message); + + } + } + + private void getOtpFromMessage(String message) { + Pattern otpPattern = Pattern.compile("(|^)\\d{6}"); + Matcher matcher = otpPattern.matcher(message); + if (matcher.find()) { + binding.connectPhoneVerifyCode.setText(matcher.group(0)); + } + } + + @Override + public void onResume() { + super.onResume(); + requestInputFocus(); + } + + @Override + public void onStop() { + super.onStop(); + } + + @Override + public void onPause() { + super.onPause(); + try { + stopHandler(); + requireActivity().unregisterReceiver(smsBroadcastReceiver); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + + } + + public void registerBrodcastReciever() { + smsBroadcastReceiver = new SMSBroadcastReceiver(); + + smsBroadcastReceiver.smsListener = new SMSListener() { + @Override + public void onSuccess(Intent intent) { + startActivityForResult(intent, REQ_USER_CONSENT); + } + + }; + + IntentFilter intentFilter = new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION); + requireActivity().registerReceiver(smsBroadcastReceiver, intentFilter); + } + + public void setErrorMessage(String message) { + if (message == null) { + binding.connectPhoneVerifyError.setVisibility(View.GONE); + } else { + binding.connectPhoneVerifyError.setVisibility(View.VISIBLE); + binding.connectPhoneVerifyError.setText(message); + } + } + + public void requestInputFocus() { + KeyboardHelper.showKeyboardOnInput(requireActivity(), binding.connectPhoneVerifyCode); + } + + public void setResendEnabled(boolean enabled) { + binding.connectPhoneVerifyResend.setEnabled(enabled); + binding.connectPhoneVerifyResend.setTextColor(enabled ? Color.BLUE : Color.GRAY); + } + + + public void updateMessage() { + String phone = primaryPhone; + phone = phone.substring(phone.length() - 4); + String text = getString(R.string.connect_verify_phone_label, phone); + binding.connectPhoneVerifyLabel.setText(text); + } + + void startHandler() { + taskHandler.postDelayed(runnable, 100); + } + + void stopHandler() { + taskHandler.removeCallbacks(runnable); + } + + /*public void requestSmsCode() { + smsTime = new DateTime(); + setErrorMessage(null); + + IApiCallback callback = new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + try { + String responseAsString = new String(StreamsUtil.inputStreamToByteArray(responseData)); + if (responseAsString.length() > 0) { + JSONObject json = new JSONObject(responseAsString); + String key = ConnectConstants.CONNECT_KEY_SECRET; + if (json.has(key)) { + password = json.getString(key); + } + + key = ConnectConstants.CONNECT_KEY_SECONDARY_PHONE; + if (json.has(key)) { + recoveryPhone = json.getString(key); + updateMessage(); + } + } + } catch (IOException | JSONException e) { + Logger.exception("Parsing return from OTP request", e); + } + } + + @Override + public void processFailure(int responseCode, IOException e) { + String message = ""; + if (responseCode > 0) { + message = String.format(Locale.getDefault(), "(%d)", responseCode); + } else if (e != null) { + message = e.toString(); + } + setErrorMessage("Error requesting SMS code" + message); + + //Null out the last-requested time so user can request again immediately + smsTime = null; + } + + @Override + public void processNetworkFailure() { + setErrorMessage(getString(R.string.recovery_network_unavailable)); + //Null out the last-requested time so user can request again immediately + smsTime = null; + } + + @Override + public void processOldApiError() { + setErrorMessage(getString(R.string.recovery_network_outdated)); + } + }; + + boolean isBusy; + isBusy = !ApiConnectId.requestRegistrationOtpPrimary(requireActivity(), username, password, callback); + if (isBusy) { + Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); + } + }*/ + + public void verifySmsCode() { + setErrorMessage(null); + + String token = binding.connectPhoneVerifyCode.getText().toString(); + String phone = username; + final Context context = getContext(); + + Navigation.findNavController(binding.connectPhoneVerifyButton).navigate( + ConnectPaymentSetupPhoneVerificationFragmentDirections.actionConnectPaymentSetupPhoneVerificationFragmentToConnectJobsListFragment()); + + /* IApiCallback callback = new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + try { + String secondaryPhone = null; + String responseAsString = new String( + StreamsUtil.inputStreamToByteArray(responseData)); + if (responseAsString.length() > 0) { + JSONObject json = new JSONObject(responseAsString); + String key = ConnectConstants.CONNECT_KEY_SECONDARY_PHONE; + secondaryPhone = json.has(key) ? json.getString(key) : null; + } + + } catch (Exception e) { + Logger.exception("Parsing return from OTP verification", e); + } + } + + @Override + public void processFailure(int responseCode, IOException e) { + String message = ""; + if (responseCode > 0) { + message = String.format(Locale.getDefault(), "(%d)", responseCode); + } else if (e != null) { + message = e.toString(); + } + setErrorMessage("Error verifying SMS code"); + } + + @Override + public void processNetworkFailure() { + setErrorMessage(getString(R.string.recovery_network_unavailable)); + } + + @Override + public void processOldApiError() { + setErrorMessage(getString(R.string.recovery_network_outdated)); + } + }; + + boolean isBusy; + isBusy = !ApiConnectId.confirmPaymentInfo(requireActivity(), username, password, token, callback); + if (isBusy) { + Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); + }*/ + } +} \ No newline at end of file From fb22bb45ee8723b4478cf66aee897abf91327be9 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Fri, 22 Nov 2024 10:51:01 +0530 Subject: [PATCH 3/7] Add name on post params Add name on post params --- .../connect/network/ApiConnectId.java | 3 +- .../connect/ConnectPaymentSetupFragment.java | 83 ++++++++++--------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/app/src/org/commcare/connect/network/ApiConnectId.java b/app/src/org/commcare/connect/network/ApiConnectId.java index c2e2588dfd..0c79f76f42 100644 --- a/app/src/org/commcare/connect/network/ApiConnectId.java +++ b/app/src/org/commcare/connect/network/ApiConnectId.java @@ -425,12 +425,13 @@ public static boolean confirmUserDeactivation(Context context, String phone, Str API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } - public static boolean paymentInfo(Context context, String phone, IApiCallback callback) { + public static boolean paymentInfo(Context context, String phone,String name, IApiCallback callback) { int urlId = R.string.ConnectPaymentPhoneNumberURL; AuthInfo authInfo = new AuthInfo.NoAuth(); HashMap params = new HashMap<>(); params.put("phone_number", phone); + params.put("owner_name ", name); return ConnectNetworkHelper.post(context, context.getString(urlId), API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java index a12a474ce2..633fd1176b 100644 --- a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java @@ -18,10 +18,18 @@ import com.google.android.gms.auth.api.identity.Identity; import com.google.android.gms.common.api.ApiException; +import org.commcare.connect.network.ApiConnectId; +import org.commcare.connect.network.IApiCallback; import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.FragmentConnectPaymentSetupBinding; import org.commcare.utils.PhoneNumberHelper; +import org.javarosa.core.io.StreamsUtil; +import org.javarosa.core.services.Logger; +import org.json.JSONException; +import org.json.JSONObject; +import java.io.IOException; +import java.io.InputStream; import java.util.Locale; public class ConnectPaymentSetupFragment extends Fragment { @@ -113,45 +121,42 @@ private void submitPaymentDetail() { String phone = PhoneNumberHelper.buildPhoneNumber(binding.countryCode.getText().toString(), binding.connectPrimaryPhoneInput.getText().toString()); - Navigation.findNavController(binding.continueButton).navigate( - ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone)); - -// boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, new IApiCallback() { -// @Override -// public void processSuccess(int responseCode, InputStream responseData) { -// try { -// String responseAsString = new String( -// StreamsUtil.inputStreamToByteArray(responseData)); -// JSONObject json = new JSONObject(responseAsString); -// -// } catch (IOException | JSONException e) { -// Logger.exception("Parsing return from confirm_secondary_otp", e); -// } -// -// } -// -// @Override -// public void processFailure(int responseCode, IOException e) { -// binding.errorTextView.setVisibility(View.VISIBLE); -// binding.errorTextView.setText(String.format(Locale.getDefault(), "Registration error: %d", -// responseCode)); -// } -// -// @Override -// public void processNetworkFailure() { -// Toast.makeText(requireActivity(), R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); -// -// } -// -// @Override -// public void processOldApiError() { -// Toast.makeText(requireActivity(), R.string.recovery_network_outdated, Toast.LENGTH_SHORT).show(); -// } -// }); -// -// if (isBusy) { -// Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); -// } + boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, binding.nameTextValue.toString(), new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + try { + String responseAsString = new String( + StreamsUtil.inputStreamToByteArray(responseData)); + JSONObject json = new JSONObject(responseAsString); + Navigation.findNavController(binding.continueButton).navigate( + ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone)); + } catch (IOException | JSONException e) { + Logger.exception("Parsing return from confirm_secondary_otp", e); + } + } + + @Override + public void processFailure(int responseCode, IOException e) { + binding.errorTextView.setVisibility(View.VISIBLE); + binding.errorTextView.setText(String.format(Locale.getDefault(), "Registration error: %d", + responseCode)); + } + + @Override + public void processNetworkFailure() { + Toast.makeText(requireActivity(), R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); + + } + + @Override + public void processOldApiError() { + Toast.makeText(requireActivity(), R.string.recovery_network_outdated, Toast.LENGTH_SHORT).show(); + } + }); + + if (isBusy) { + Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); + } } public void updateButtonEnabled() { From 3cba3ea1c6313c117dc153da82e5047916359734 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Tue, 26 Nov 2024 10:46:47 +0530 Subject: [PATCH 4/7] Solved OTP verification API issues Solved OTP verification API issues --- app/res/navigation/nav_graph_connect.xml | 8 ++ .../connect/network/ApiConnectId.java | 29 +++-- .../connect/ConnectPaymentSetupFragment.java | 16 +-- ...PaymentSetupPhoneVerificationFragment.java | 110 +++--------------- 4 files changed, 47 insertions(+), 116 deletions(-) diff --git a/app/res/navigation/nav_graph_connect.xml b/app/res/navigation/nav_graph_connect.xml index be38c3fa97..f5a8546e95 100644 --- a/app/res/navigation/nav_graph_connect.xml +++ b/app/res/navigation/nav_graph_connect.xml @@ -171,6 +171,14 @@ android:name="phone" app:argType="string" app:nullable="true" /> + + params = new HashMap<>(); String token = FirebaseMessagingUtil.getFCMToken(); - if(token != null) { + if (token != null) { params.put("fcm_token", token); boolean useFormEncoding = true; return ConnectNetworkHelper.postSync(context, url, API_VERSION_CONNECT_ID, retrieveConnectIdTokenSync(context), params, useFormEncoding, true); @@ -147,7 +147,7 @@ public static AuthInfo.TokenAuth retrieveConnectIdTokenSync(Context context) { Date expiration = new Date(); key = ConnectConstants.CONNECT_KEY_EXPIRES; int seconds = json.has(key) ? json.getInt(key) : 0; - expiration.setTime(expiration.getTime() + ((long)seconds * 1000)); + expiration.setTime(expiration.getTime() + ((long) seconds * 1000)); user.updateConnectToken(token, expiration); ConnectDatabaseHelper.storeUser(context, user); @@ -288,11 +288,11 @@ public static boolean updateUserProfile(Context context, String username, int urlId = R.string.ConnectUpdateProfileURL; HashMap params = new HashMap<>(); - if(secondaryPhone != null) { + if (secondaryPhone != null) { params.put("secondary_phone", secondaryPhone); } - if(displayName != null) { + if (displayName != null) { params.put("name", displayName); } @@ -337,7 +337,7 @@ public static boolean requestRecoveryOtpSecondary(Context context, String phone, } public static boolean requestVerificationOtpSecondary(Context context, String username, String password, - IApiCallback callback) { + IApiCallback callback) { int urlId = R.string.ConnectVerifySecondaryURL; AuthInfo authInfo = new AuthInfo.ProvidedAuth(username, password, false); @@ -388,7 +388,7 @@ public static boolean confirmRecoveryOtpSecondary(Context context, String phone, } public static boolean confirmVerificationOtpSecondary(Context context, String username, String password, - String token, IApiCallback callback) { + String token, IApiCallback callback) { int urlId = R.string.ConnectVerifyConfirmSecondaryOTPURL; AuthInfo authInfo = new AuthInfo.ProvidedAuth(username, password, false); @@ -399,7 +399,7 @@ public static boolean confirmVerificationOtpSecondary(Context context, String us API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } - public static boolean requestInitiateAccountDeactivation(Context context, String phone,String secretKey, IApiCallback callback) { + public static boolean requestInitiateAccountDeactivation(Context context, String phone, String secretKey, IApiCallback callback) { int urlId = R.string.ConnectInitiateUserAccountDeactivationURL; AuthInfo authInfo = new AuthInfo.NoAuth(); @@ -425,25 +425,24 @@ public static boolean confirmUserDeactivation(Context context, String phone, Str API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } - public static boolean paymentInfo(Context context, String phone,String name, IApiCallback callback) { + public static boolean paymentInfo(Context context, String phone, String username, String password, String name, IApiCallback callback) { int urlId = R.string.ConnectPaymentPhoneNumberURL; - AuthInfo authInfo = new AuthInfo.NoAuth(); + AuthInfo authInfo = new AuthInfo.ProvidedAuth(username, password, false); HashMap params = new HashMap<>(); params.put("phone_number", phone); - params.put("owner_name ", name); + params.put("owner_name", name); return ConnectNetworkHelper.post(context, context.getString(urlId), API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } - public static boolean confirmPaymentInfo(Context context,String phone,String secret, String token, IApiCallback callback) { + public static boolean confirmPaymentInfo(Context context, String phone, String username, String password, String token, IApiCallback callback) { int urlId = R.string.ConnectConfirmPaymentOtpURL; - AuthInfo authInfo = new AuthInfo.NoAuth(); + AuthInfo authInfo = new AuthInfo.ProvidedAuth(username, password, false); HashMap params = new HashMap<>(); params.put("phone_number", phone); - params.put("secret_key", secret); params.put("token", token); return ConnectNetworkHelper.post(context, context.getString(urlId), diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java index 633fd1176b..c6e4d10ce4 100644 --- a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java @@ -18,15 +18,14 @@ import com.google.android.gms.auth.api.identity.Identity; import com.google.android.gms.common.api.ApiException; +import org.commcare.android.database.connect.models.ConnectUserRecord; +import org.commcare.connect.ConnectDatabaseHelper; import org.commcare.connect.network.ApiConnectId; import org.commcare.connect.network.IApiCallback; import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.FragmentConnectPaymentSetupBinding; import org.commcare.utils.PhoneNumberHelper; -import org.javarosa.core.io.StreamsUtil; import org.javarosa.core.services.Logger; -import org.json.JSONException; -import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; @@ -120,17 +119,14 @@ private void clickListeners() { private void submitPaymentDetail() { String phone = PhoneNumberHelper.buildPhoneNumber(binding.countryCode.getText().toString(), binding.connectPrimaryPhoneInput.getText().toString()); - - boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, binding.nameTextValue.toString(), new IApiCallback() { + ConnectUserRecord user = ConnectDatabaseHelper.getUser(getActivity()); + boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), phone, user.getUserId(), user.getPassword(), binding.nameTextValue.getText().toString(), new IApiCallback() { @Override public void processSuccess(int responseCode, InputStream responseData) { try { - String responseAsString = new String( - StreamsUtil.inputStreamToByteArray(responseData)); - JSONObject json = new JSONObject(responseAsString); Navigation.findNavController(binding.continueButton).navigate( - ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone)); - } catch (IOException | JSONException e) { + ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone,user.getUserId(),user.getPassword())); + } catch (Exception e) { Logger.exception("Parsing return from confirm_secondary_otp", e); } } diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java index 59904be73a..9a2a518cd6 100644 --- a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java @@ -2,7 +2,6 @@ import static android.app.Activity.RESULT_OK; -import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; @@ -13,6 +12,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -21,13 +21,21 @@ import com.google.android.gms.auth.api.phone.SmsRetriever; import com.google.android.gms.auth.api.phone.SmsRetrieverClient; +import org.commcare.android.database.connect.models.ConnectUserRecord; +import org.commcare.connect.ConnectDatabaseHelper; import org.commcare.connect.SMSBroadcastReceiver; import org.commcare.connect.SMSListener; +import org.commcare.connect.network.ApiConnectId; +import org.commcare.connect.network.IApiCallback; import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.ScreenConnectPaymentPhoneVerifyBinding; import org.commcare.utils.KeyboardHelper; +import org.javarosa.core.services.Logger; import org.joda.time.DateTime; +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -104,20 +112,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, if (getArguments() != null) { -// method = Integer.parseInt(Objects.requireNonNull(ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getMethod())); primaryPhone = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPhone(); -// allowChange = (ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getAllowChange()); -// username = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getUsername(); -// password = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPassword(); -// recoveryPhone = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getSecondaryPhone(); -// callingClass = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getCallingClass(); -// deactivateButton = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getDeactivateButton(); + username = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getUsername(); + password = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPassword(); } updateMessage(); -// requestSmsCode(); - startHandler(); // binding.connectPhoneVerifyResend.setOnClickListener(arg0 -> requestSmsCode()); @@ -149,7 +150,6 @@ private void buttonEnabled(String code) { public void onStart() { super.onStart(); registerBrodcastReciever(); - } @Override @@ -158,7 +158,6 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d if (requestCode == REQ_USER_CONSENT && (resultCode == RESULT_OK) && data != null) { String message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE); getOtpFromMessage(message); - } } @@ -185,7 +184,6 @@ public void onStop() { public void onPause() { super.onPause(); try { - stopHandler(); requireActivity().unregisterReceiver(smsBroadcastReceiver); } catch (IllegalArgumentException e) { e.printStackTrace(); @@ -235,6 +233,7 @@ public void updateMessage() { } void startHandler() { + smsTime = new DateTime(); taskHandler.postDelayed(runnable, 100); } @@ -242,90 +241,19 @@ void stopHandler() { taskHandler.removeCallbacks(runnable); } - /*public void requestSmsCode() { - smsTime = new DateTime(); - setErrorMessage(null); - - IApiCallback callback = new IApiCallback() { - @Override - public void processSuccess(int responseCode, InputStream responseData) { - try { - String responseAsString = new String(StreamsUtil.inputStreamToByteArray(responseData)); - if (responseAsString.length() > 0) { - JSONObject json = new JSONObject(responseAsString); - String key = ConnectConstants.CONNECT_KEY_SECRET; - if (json.has(key)) { - password = json.getString(key); - } - - key = ConnectConstants.CONNECT_KEY_SECONDARY_PHONE; - if (json.has(key)) { - recoveryPhone = json.getString(key); - updateMessage(); - } - } - } catch (IOException | JSONException e) { - Logger.exception("Parsing return from OTP request", e); - } - } - - @Override - public void processFailure(int responseCode, IOException e) { - String message = ""; - if (responseCode > 0) { - message = String.format(Locale.getDefault(), "(%d)", responseCode); - } else if (e != null) { - message = e.toString(); - } - setErrorMessage("Error requesting SMS code" + message); - - //Null out the last-requested time so user can request again immediately - smsTime = null; - } - - @Override - public void processNetworkFailure() { - setErrorMessage(getString(R.string.recovery_network_unavailable)); - //Null out the last-requested time so user can request again immediately - smsTime = null; - } - - @Override - public void processOldApiError() { - setErrorMessage(getString(R.string.recovery_network_outdated)); - } - }; - - boolean isBusy; - isBusy = !ApiConnectId.requestRegistrationOtpPrimary(requireActivity(), username, password, callback); - if (isBusy) { - Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); - } - }*/ - public void verifySmsCode() { setErrorMessage(null); String token = binding.connectPhoneVerifyCode.getText().toString(); - String phone = username; - final Context context = getContext(); - - Navigation.findNavController(binding.connectPhoneVerifyButton).navigate( - ConnectPaymentSetupPhoneVerificationFragmentDirections.actionConnectPaymentSetupPhoneVerificationFragmentToConnectJobsListFragment()); + ConnectUserRecord user = ConnectDatabaseHelper.getUser(getActivity()); - /* IApiCallback callback = new IApiCallback() { + IApiCallback callback = new IApiCallback() { @Override public void processSuccess(int responseCode, InputStream responseData) { try { - String secondaryPhone = null; - String responseAsString = new String( - StreamsUtil.inputStreamToByteArray(responseData)); - if (responseAsString.length() > 0) { - JSONObject json = new JSONObject(responseAsString); - String key = ConnectConstants.CONNECT_KEY_SECONDARY_PHONE; - secondaryPhone = json.has(key) ? json.getString(key) : null; - } - + stopHandler(); + Navigation.findNavController(binding.connectPhoneVerifyButton).navigate( + ConnectPaymentSetupPhoneVerificationFragmentDirections.actionConnectPaymentSetupPhoneVerificationFragmentToConnectJobsListFragment()); } catch (Exception e) { Logger.exception("Parsing return from OTP verification", e); } @@ -354,9 +282,9 @@ public void processOldApiError() { }; boolean isBusy; - isBusy = !ApiConnectId.confirmPaymentInfo(requireActivity(), username, password, token, callback); + isBusy = !ApiConnectId.confirmPaymentInfo(requireActivity(), primaryPhone, username, password, token, callback); if (isBusy) { Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); - }*/ + } } } \ No newline at end of file From 3d8e8d636ba275cc3201973c78f9c3a6431a9e49 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Tue, 26 Nov 2024 14:36:05 +0530 Subject: [PATCH 5/7] Set resend button on OTP verification screen Set resend button on OTP verification screen --- .../screen_connect_payment_phone_verify.xml | 20 +++++++ app/res/navigation/nav_graph_connect.xml | 4 ++ app/res/values/strings.xml | 1 + .../connect/ConnectPaymentSetupFragment.java | 2 +- ...PaymentSetupPhoneVerificationFragment.java | 52 ++++++++++++++++--- 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/app/res/layout/screen_connect_payment_phone_verify.xml b/app/res/layout/screen_connect_payment_phone_verify.xml index bb204df753..7f97cd73bd 100644 --- a/app/res/layout/screen_connect_payment_phone_verify.xml +++ b/app/res/layout/screen_connect_payment_phone_verify.xml @@ -119,6 +119,26 @@ android:layout_marginBottom="16dp" android:orientation="horizontal"> + + + Daily Limit reached. No Payment for submitting forms Over Limit Payment Info + Resend OTP diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java index c6e4d10ce4..4d11078320 100644 --- a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupFragment.java @@ -125,7 +125,7 @@ private void submitPaymentDetail() { public void processSuccess(int responseCode, InputStream responseData) { try { Navigation.findNavController(binding.continueButton).navigate( - ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone,user.getUserId(),user.getPassword())); + ConnectPaymentSetupFragmentDirections.actionConnectPaymentSetupFragmentToConnectPaymentSetupPhoneVerificationFragment(phone,binding.nameTextValue.getText().toString(),user.getUserId(),user.getPassword())); } catch (Exception e) { Logger.exception("Parsing return from confirm_secondary_otp", e); } diff --git a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java index 9a2a518cd6..665d94e169 100644 --- a/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectPaymentSetupPhoneVerificationFragment.java @@ -4,7 +4,6 @@ import android.content.Intent; import android.content.IntentFilter; -import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.text.Editable; @@ -48,6 +47,7 @@ public class ConnectPaymentSetupPhoneVerificationFragment extends Fragment { public static final int MethodUserDeactivate = 5; public static final int REQ_USER_CONSENT = 200; private String primaryPhone; + private String paymentProfileName; private String username; private String password; private SMSBroadcastReceiver smsBroadcastReceiver; @@ -113,6 +113,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, if (getArguments() != null) { primaryPhone = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPhone(); + paymentProfileName = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPaymentProfileName(); username = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getUsername(); password = ConnectPaymentSetupPhoneVerificationFragmentArgs.fromBundle(getArguments()).getPassword(); } @@ -121,7 +122,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, startHandler(); -// binding.connectPhoneVerifyResend.setOnClickListener(arg0 -> requestSmsCode()); + binding.connectResendOtpButton.setOnClickListener(arg0 -> requestSmsCode()); binding.connectPhoneVerifyButton.setOnClickListener(arg0 -> verifySmsCode()); binding.connectPhoneVerifyCode.addTextChangedListener(new TextWatcher() { @Override @@ -142,6 +143,44 @@ public void afterTextChanged(Editable s) { return view; } + private void requestSmsCode() { + setErrorMessage(null); + boolean isBusy = !ApiConnectId.paymentInfo(requireActivity(), primaryPhone, username, password, paymentProfileName, new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + updateMessage(); + startHandler(); + } + + @Override + public void processFailure(int responseCode, IOException e) { + smsTime = null; + String message = ""; + if (responseCode > 0) { + message = String.format(Locale.getDefault(), "(%d)", responseCode); + } else if (e != null) { + message = e.toString(); + } + setErrorMessage("Error sending SMS"); + } + + @Override + public void processNetworkFailure() { + smsTime = null; + setErrorMessage(getString(R.string.recovery_network_unavailable)); + } + + @Override + public void processOldApiError() { + setErrorMessage(getString(R.string.recovery_network_outdated)); + } + }); + + if (isBusy) { + Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); + } + } + private void buttonEnabled(String code) { binding.connectPhoneVerifyButton.setEnabled(!code.isEmpty() && code.length() > 5); } @@ -149,7 +188,7 @@ private void buttonEnabled(String code) { @Override public void onStart() { super.onStart(); - registerBrodcastReciever(); + registerBroadcastReceiver(); } @Override @@ -184,6 +223,7 @@ public void onStop() { public void onPause() { super.onPause(); try { + stopHandler(); requireActivity().unregisterReceiver(smsBroadcastReceiver); } catch (IllegalArgumentException e) { e.printStackTrace(); @@ -191,7 +231,7 @@ public void onPause() { } - public void registerBrodcastReciever() { + public void registerBroadcastReceiver() { smsBroadcastReceiver = new SMSBroadcastReceiver(); smsBroadcastReceiver.smsListener = new SMSListener() { @@ -220,8 +260,8 @@ public void requestInputFocus() { } public void setResendEnabled(boolean enabled) { - binding.connectPhoneVerifyResend.setEnabled(enabled); - binding.connectPhoneVerifyResend.setTextColor(enabled ? Color.BLUE : Color.GRAY); + binding.connectResendOtpButton.setEnabled(enabled); + binding.connectResendOtpButton.setVisibility(enabled ? View.VISIBLE : View.GONE); } From 269f0f1fe0bb916de78d9e8751cca26d1c8a13b0 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Sat, 30 Nov 2024 10:26:30 +0530 Subject: [PATCH 6/7] Set payment info in local DB Set payment info in local DB --- .../connect/models/ConnectUserRecord.java | 15 +++++++++++-- .../commcare/connect/ConnectConstants.java | 3 +++ .../connectId/ConnectIDSignupFragment.java | 2 +- ...ConnectIdPasswordVerificationFragment.java | 2 +- .../ConnectIdPhoneVerificationFragmnet.java | 6 ++--- .../connectId/ConnectIdPinFragment.java | 22 ++++++++++++++----- 6 files changed, 38 insertions(+), 12 deletions(-) diff --git a/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java b/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java index 95d95ee66f..d71e26e111 100644 --- a/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java +++ b/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java @@ -63,6 +63,12 @@ public class ConnectUserRecord extends Persisted { @MetaField(META_VERIFY_SECONDARY_PHONE_DATE) private Date verifySecondaryPhoneByDate; + @Persisting(13) + private String paymentName; + + @Persisting(14) + private String paymentPhone; + public ConnectUserRecord() { registrationPhase = ConnectConstants.CONNECT_NO_ACTIVITY; lastPasswordDate = new Date(); @@ -72,13 +78,15 @@ public ConnectUserRecord() { } public ConnectUserRecord(String primaryPhone, String userId, String password, String name, - String alternatePhone) { + String alternatePhone,String paymentName,String paymentPhone) { this(); this.primaryPhone = primaryPhone; this.alternatePhone = alternatePhone; this.userId = userId; this.password = password; this.name = name; + this.paymentName = paymentName; + this.paymentPhone = paymentPhone; connectTokenExpiration = new Date(); } @@ -89,7 +97,10 @@ public static ConnectUserRecord getUserFromIntent(Intent intent) { intent.getStringExtra(ConnectConstants.USERNAME), intent.getStringExtra(ConnectConstants.PASSWORD), intent.getStringExtra(ConnectConstants.NAME), - intent.getStringExtra(ConnectConstants.ALT_PHONE)); + intent.getStringExtra(ConnectConstants.ALT_PHONE), + intent.getStringExtra(ConnectConstants.PAYMENT_NAME), + intent.getStringExtra(ConnectConstants.PAYMENT_PHONE) + ); } public void putUserInIntent(Intent intent) { diff --git a/app/src/org/commcare/connect/ConnectConstants.java b/app/src/org/commcare/connect/ConnectConstants.java index c38ff2b315..1b11c42a07 100644 --- a/app/src/org/commcare/connect/ConnectConstants.java +++ b/app/src/org/commcare/connect/ConnectConstants.java @@ -15,6 +15,8 @@ public class ConnectConstants { public static final String NAME = "NAME"; public static final String PHONE = "PHONE"; public static final String ALT_PHONE = "ALT_PHONE"; + public static final String PAYMENT_NAME = "PAYMENT_NAME"; + public static final String PAYMENT_PHONE = "PAYMENT_PHONE"; public static final String BEGIN_REGISTRATION = "BEGIN_REGISTRATION"; public static final String VERIFY_PHONE = "VERIFY_PHONE"; public static final String METHOD_REGISTER_PRIMARY = "REGISTER_PRIMARY"; @@ -24,6 +26,7 @@ public class ConnectConstants { public static final String CONNECT_KEY_TOKEN = "access_token"; public static final String CONNECT_KEY_EXPIRES = "expires_in"; public static final String CONNECT_KEY_USERNAME = "username"; + public static final String CONNECT_PAYMENT_INFO = "payment_info"; public static final String CONNECT_KEY_NAME = "name"; public static final String CONNECT_KEY_SECRET = "secret"; public static final String CONNECT_KEY_SECONDARY_PHONE = "secondary_phone"; diff --git a/app/src/org/commcare/fragments/connectId/ConnectIDSignupFragment.java b/app/src/org/commcare/fragments/connectId/ConnectIDSignupFragment.java index b10904b4c4..fb19e29d24 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIDSignupFragment.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIDSignupFragment.java @@ -341,7 +341,7 @@ public void createAccount() { binding.errorTextView.setVisibility(View.GONE); String phoneNo = binding.countryCode.getText().toString() + binding.connectPrimaryPhoneInput.getText().toString(); ConnectUserRecord tempUser = new ConnectUserRecord(phoneNo, generateUserId(), ConnectManager.generatePassword(), - binding.nameTextValue.getText().toString(), ""); + binding.nameTextValue.getText().toString(), "","",""); final Context context = getActivity(); boolean isBusy = !ApiConnectId.registerUser(requireActivity(), tempUser.getUserId(), tempUser.getPassword(), diff --git a/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java b/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java index 3c736eab8f..a5e87aea99 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java @@ -193,7 +193,7 @@ public void processSuccess(int responseCode, InputStream responseData) { } ConnectUserRecord user = new ConnectUserRecord(phone, username, - password, name, ""); + password, name, "","",""); key = ConnectConstants.CONNECT_KEY_VALIDATE_SECONDARY_PHONE_BY; user.setSecondaryPhoneVerified(!json.has(key) || json.isNull(key)); diff --git a/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java b/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java index 7e6a6ba5e0..522b89cf71 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java @@ -435,7 +435,7 @@ public void processSuccess(int responseCode, InputStream responseData) { ConnectDatabaseHelper.handleReceivedDbPassphrase(context, json.getString(key)); } - resetPassword(context, phone, password, username, displayName); + resetPassword(context, phone, password, username, displayName,"",""); } } } catch (Exception e) { @@ -490,14 +490,14 @@ public void processOldApiError() { } } - private void resetPassword(Context context, String phone, String secret, String username, String name) { + private void resetPassword(Context context, String phone, String secret, String username, String name,String paymentName,String paymentPhone) { //Auto-generate and send a new password String password = ConnectManager.generatePassword(); ApiConnectId.resetPassword(context, phone, secret, password, new IApiCallback() { @Override public void processSuccess(int responseCode, InputStream responseData) { ConnectUserRecord user = new ConnectUserRecord(phone, username, - password, name, recoveryPhone); + password, name, recoveryPhone,paymentName,paymentPhone); user.setSecondaryPhoneVerified(true); ConnectDatabaseHelper.storeUser(context, user); diff --git a/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java b/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java index e7343cca61..69837ef51e 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java @@ -7,6 +7,7 @@ import android.text.Editable; import android.text.InputFilter; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -206,6 +207,7 @@ public void handleButtonPress() { boolean isBusy = false; final Context context = getActivity(); + Log.e("DEBUG_TESTING12", "handleButtonPress: " + secret); if (isChanging) { //Change PIN isBusy = !ApiConnectId.changePin(getActivity(), user.getUserId(), user.getPassword(), pin, @@ -224,6 +226,7 @@ public void processFailure(int responseCode, IOException e) { } @Override + public void processNetworkFailure() { ConnectNetworkHelper.showNetworkError(getActivity()); } @@ -245,9 +248,10 @@ public void processSuccess(int responseCode, InputStream responseData) { String responseAsString = new String( StreamsUtil.inputStreamToByteArray(responseData)); ConnectManager.setFailureAttempt(0); + Log.e("DEBUG_TESTING12", "responseAsString: " + responseAsString); if (responseAsString.length() > 0) { JSONObject json = new JSONObject(responseAsString); - + Log.e("DEBUG_TESTING12", "json: " + json.toString()); String key = ConnectConstants.CONNECT_KEY_USERNAME; if (json.has(key)) { username = json.getString(key); @@ -263,8 +267,16 @@ public void processSuccess(int responseCode, InputStream responseData) { ConnectDatabaseHelper.handleReceivedDbPassphrase(context, json.getString(key)); } + key = ConnectConstants.CONNECT_PAYMENT_INFO; + String paymentName = "",paymentPhone = ""; +// if(json.has(key)){ +// JSONObject paymentJson = json.getJSONObject(key); +// paymentName = paymentJson.getString(""); +// paymentPhone = paymentJson.getString(""); +// } + ConnectUserRecord user = new ConnectUserRecord(phone, username, - "", name, ""); + "", name, "",paymentName,paymentPhone); user.setPin(pin); user.setLastPinDate(new Date()); @@ -382,7 +394,7 @@ public void finish(boolean success, boolean forgot, String pin) { } } else { directions = ConnectIdPinFragmentDirections.actionConnectidPinToConnectidPhoneVerify(ConnectConstants.CONNECT_RECOVERY_VERIFY_PRIMARY_PHONE, String.format(Locale.getDefault(), "%d", - ConnectIdPhoneVerificationFragmnet.MethodRecoveryPrimary), ConnectIdActivity.recoverPhone, ConnectIdActivity.recoverPhone, "", null,false); + ConnectIdPhoneVerificationFragmnet.MethodRecoveryPrimary), ConnectIdActivity.recoverPhone, ConnectIdActivity.recoverPhone, "", null, false); } } case ConnectConstants.CONNECT_REGISTRATION_CONFIGURE_PIN -> { @@ -397,7 +409,7 @@ public void finish(boolean success, boolean forgot, String pin) { } } else { directions = ConnectIdPinFragmentDirections.actionConnectidPinToConnectidPhoneVerify(ConnectConstants.CONNECT_REGISTRATION_VERIFY_PRIMARY_PHONE, String.format(Locale.getDefault(), "%d", - ConnectManager.MethodRegistrationPrimary), user.getPrimaryPhone(), user.getUserId(), user.getPassword(), user.getAlternatePhone(),false).setAllowChange(true); + ConnectManager.MethodRegistrationPrimary), user.getPrimaryPhone(), user.getUserId(), user.getPassword(), user.getAlternatePhone(), false).setAllowChange(true); } } case ConnectConstants.CONNECT_REGISTRATION_CONFIRM_PIN -> { @@ -447,7 +459,7 @@ public void finish(boolean success, boolean forgot, String pin) { } else { directions = ConnectIdPinFragmentDirections.actionConnectidPinToConnectidPhoneVerify(ConnectConstants.CONNECT_RECOVERY_VERIFY_ALT_PHONE, String.format(Locale.getDefault(), "%d", - ConnectIdPhoneVerificationFragmnet.MethodRecoveryAlternate), null, ConnectIdActivity.recoverPhone, ConnectIdActivity.recoverSecret, ConnectIdActivity.recoveryAltPhone,false).setAllowChange(false); + ConnectIdPhoneVerificationFragmnet.MethodRecoveryAlternate), null, ConnectIdActivity.recoverPhone, ConnectIdActivity.recoverSecret, ConnectIdActivity.recoveryAltPhone, false).setAllowChange(false); } } case ConnectConstants.CONNECT_REGISTRATION_CHANGE_PIN -> { From b3de0d88c074bde8a75aafdf818cb0ee7af1710a Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Mon, 9 Dec 2024 19:24:03 +0530 Subject: [PATCH 7/7] Added payment info in local DB Added payment info in local DB --- .../connect/models/ConnectJobRecord.java | 14 ++++ .../connect/models/ConnectUserRecord.java | 16 ++++ .../commcare/connect/ConnectConstants.java | 2 +- .../connect/ConnectJobsListsFragment.java | 78 ++++++++++--------- ...ConnectIdPasswordVerificationFragment.java | 11 ++- .../ConnectIdPhoneVerificationFragmnet.java | 11 ++- .../connectId/ConnectIdPinFragment.java | 15 ++-- 7 files changed, 99 insertions(+), 48 deletions(-) diff --git a/app/src/org/commcare/android/database/connect/models/ConnectJobRecord.java b/app/src/org/commcare/android/database/connect/models/ConnectJobRecord.java index 92fa3bbd5a..970eef7d0f 100644 --- a/app/src/org/commcare/android/database/connect/models/ConnectJobRecord.java +++ b/app/src/org/commcare/android/database/connect/models/ConnectJobRecord.java @@ -66,6 +66,7 @@ public class ConnectJobRecord extends Persisted implements Serializable { public static final String META_MAX_VISITS = "max_visits"; public static final String META_USER_SUSPENDED = "is_user_suspended"; + public static final String META_PAYMENT_INFO_REQUIRED = "payment_info_required"; @Persisting(1) @MetaField(META_JOB_ID) @@ -146,6 +147,10 @@ public class ConnectJobRecord extends Persisted implements Serializable { private ConnectAppRecord deliveryAppInfo; private List paymentUnits; + @Persisting(24) + @MetaField(META_PAYMENT_INFO_REQUIRED) + private Boolean isPaymentInfoRequired; + private boolean claimed; public ConnectJobRecord() { @@ -287,6 +292,15 @@ public int getLearningPercentComplete() { public ConnectAppRecord getDeliveryAppInfo() { return deliveryAppInfo; } public void setDeliveryAppInfo(ConnectAppRecord appInfo) { this.deliveryAppInfo = appInfo; } public List getDeliveries() { return deliveries; } + + public Boolean getPaymentInfoRequired() { + return isPaymentInfoRequired; + } + + public void setPaymentInfoRequired(Boolean paymentInfoRequired) { + isPaymentInfoRequired = paymentInfoRequired; + } + public void setDeliveries(List deliveries) { this.deliveries = deliveries; if(deliveries.size() > 0) { diff --git a/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java b/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java index d71e26e111..f78730d0bb 100644 --- a/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java +++ b/app/src/org/commcare/android/database/connect/models/ConnectUserRecord.java @@ -171,6 +171,22 @@ public Date getSecondaryPhoneVerifyByDate() { } public void setSecondaryPhoneVerifyByDate(Date date) { verifySecondaryPhoneByDate = date; } + public String getPaymentName() { + return paymentName; + } + + public void setPaymentName(String paymentName) { + this.paymentName = paymentName; + } + + public String getPaymentPhone() { + return paymentPhone; + } + + public void setPaymentPhone(String paymentPhone) { + this.paymentPhone = paymentPhone; + } + public boolean shouldForcePin() { return shouldForceRecoveryLogin() && pin != null && pin.length() > 0; } diff --git a/app/src/org/commcare/connect/ConnectConstants.java b/app/src/org/commcare/connect/ConnectConstants.java index 1b11c42a07..bd23cbcf6a 100644 --- a/app/src/org/commcare/connect/ConnectConstants.java +++ b/app/src/org/commcare/connect/ConnectConstants.java @@ -26,7 +26,7 @@ public class ConnectConstants { public static final String CONNECT_KEY_TOKEN = "access_token"; public static final String CONNECT_KEY_EXPIRES = "expires_in"; public static final String CONNECT_KEY_USERNAME = "username"; - public static final String CONNECT_PAYMENT_INFO = "payment_info"; + public static final String CONNECT_PAYMENT_INFO = "payment_profile"; public static final String CONNECT_KEY_NAME = "name"; public static final String CONNECT_KEY_SECRET = "secret"; public static final String CONNECT_KEY_SECONDARY_PHONE = "secondary_phone"; diff --git a/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java b/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java index b54fd73aa2..9564fe8bc1 100644 --- a/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java +++ b/app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java @@ -21,16 +21,15 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.fragment.app.Fragment; -import androidx.navigation.NavDirections; import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.commcare.activities.CommCareActivity; import org.commcare.adapters.JobListConnectHomeAppsAdapter; -import org.commcare.android.database.connect.models.ConnectAppRecord; import org.commcare.android.database.connect.models.ConnectJobRecord; import org.commcare.android.database.connect.models.ConnectLinkedAppRecord; +import org.commcare.android.database.connect.models.ConnectUserRecord; import org.commcare.connect.ConnectDatabaseHelper; import org.commcare.connect.ConnectManager; import org.commcare.connect.IConnectAppLauncher; @@ -96,12 +95,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, ConnectManager.launchApp(getActivity(), isLearning, appId); }; - view.findViewById(R.id.connect_jobs_last_update).setOnClickListener(new View.OnClickListener() { + /* view.findViewById(R.id.connect_jobs_last_update).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Navigation.findNavController(view).navigate(ConnectJobsListsFragmentDirections.actionConnectJobsListFragmentToConnectPaymentSetupFragment()); } - }); + });*/ refreshUi(); refreshData(); @@ -198,10 +197,15 @@ private void initRecyclerView() { noJobsText.setVisibility(jobList.size() > 0 ? View.GONE : View.VISIBLE); JobListConnectHomeAppsAdapter adapter = new JobListConnectHomeAppsAdapter(getContext(), jobList, (job, isLearning, appId, jobType) -> { - if (jobType.equals(JOB_NEW_OPPORTUNITY)) { - launchJobInfo(job); + ConnectUserRecord user = ConnectManager.getUser(getActivity()); + if (user.getPaymentName().isEmpty() && user.getPaymentPhone().isEmpty() && job.getPaymentInfoRequired()) { + Navigation.findNavController(view).navigate(ConnectJobsListsFragmentDirections.actionConnectJobsListFragmentToConnectPaymentSetupFragment()); } else { - launchAppForJob(job, isLearning); + if (jobType.equals(JOB_NEW_OPPORTUNITY)) { + launchJobInfo(job); + } else { + launchAppForJob(job, isLearning); + } } }); @@ -235,37 +239,37 @@ private void setJobListData(List jobs) { ArrayList otherJobs = new ArrayList<>(); for (ConnectJobRecord job : jobs) { - int jobStatus = job.getStatus(); - boolean isLearnAppInstalled = isAppInstalled(job.getLearnAppInfo().getAppId()); - boolean isDeliverAppInstalled = isAppInstalled(job.getDeliveryAppInfo().getAppId()); - - switch (jobStatus) { - case STATUS_AVAILABLE_NEW, STATUS_AVAILABLE: - if(!job.isFinished()) { - availableNewJobs.add(createJobModel( - job, JOB_NEW_OPPORTUNITY, NEW_APP, true, true, false, false - )); - } - break; - - case STATUS_LEARNING: - otherJobs.add(createJobModel( - job, JOB_LEARNING, LEARN_APP, isLearnAppInstalled, false, true, false - )); - break; - - case STATUS_DELIVERING: - otherJobs.add(createJobModel( - job, JOB_LEARNING, LEARN_APP, isLearnAppInstalled, false, true, false - )); - otherJobs.add(createJobModel( - job, JOB_DELIVERY, DELIVERY_APP, isDeliverAppInstalled, false, false, true + int jobStatus = job.getStatus(); + boolean isLearnAppInstalled = isAppInstalled(job.getLearnAppInfo().getAppId()); + boolean isDeliverAppInstalled = isAppInstalled(job.getDeliveryAppInfo().getAppId()); + + switch (jobStatus) { + case STATUS_AVAILABLE_NEW, STATUS_AVAILABLE: + if (!job.isFinished()) { + availableNewJobs.add(createJobModel( + job, JOB_NEW_OPPORTUNITY, NEW_APP, true, true, false, false )); - break; - - default: - break; - } + } + break; + + case STATUS_LEARNING: + otherJobs.add(createJobModel( + job, JOB_LEARNING, LEARN_APP, isLearnAppInstalled, false, true, false + )); + break; + + case STATUS_DELIVERING: + otherJobs.add(createJobModel( + job, JOB_LEARNING, LEARN_APP, isLearnAppInstalled, false, true, false + )); + otherJobs.add(createJobModel( + job, JOB_DELIVERY, DELIVERY_APP, isDeliverAppInstalled, false, false, true + )); + break; + + default: + break; + } } diff --git a/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java b/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java index a5e87aea99..99af1f069e 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java @@ -4,6 +4,7 @@ import android.content.Context; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -192,8 +193,16 @@ public void processSuccess(int responseCode, InputStream responseData) { ConnectDatabaseHelper.handleReceivedDbPassphrase(context, json.getString(key)); } + key = ConnectConstants.CONNECT_PAYMENT_INFO; + String paymentName = "",paymentPhone = ""; + if(json.has(key)){ + JSONObject paymentJson = json.getJSONObject(key); + paymentName = paymentJson.getString("owner_name"); + paymentPhone = paymentJson.getString("phone_number"); + } + ConnectUserRecord user = new ConnectUserRecord(phone, username, - password, name, "","",""); + password, name, "",paymentName,paymentPhone); key = ConnectConstants.CONNECT_KEY_VALIDATE_SECONDARY_PHONE_BY; user.setSecondaryPhoneVerified(!json.has(key) || json.isNull(key)); diff --git a/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java b/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java index 522b89cf71..af4099460f 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIdPhoneVerificationFragmnet.java @@ -13,6 +13,7 @@ import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -435,7 +436,15 @@ public void processSuccess(int responseCode, InputStream responseData) { ConnectDatabaseHelper.handleReceivedDbPassphrase(context, json.getString(key)); } - resetPassword(context, phone, password, username, displayName,"",""); + key = ConnectConstants.CONNECT_PAYMENT_INFO; + String paymentName = "",paymentPhone = ""; + if(json.has(key)){ + JSONObject paymentJson = json.getJSONObject(key); + paymentName = paymentJson.getString("owner_name"); + paymentPhone = paymentJson.getString("phone_number"); + } + + resetPassword(context, phone, password, username, displayName,paymentName,paymentPhone); } } } catch (Exception e) { diff --git a/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java b/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java index 69837ef51e..a2c0613c8a 100644 --- a/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java +++ b/app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java @@ -207,7 +207,6 @@ public void handleButtonPress() { boolean isBusy = false; final Context context = getActivity(); - Log.e("DEBUG_TESTING12", "handleButtonPress: " + secret); if (isChanging) { //Change PIN isBusy = !ApiConnectId.changePin(getActivity(), user.getUserId(), user.getPassword(), pin, @@ -248,10 +247,8 @@ public void processSuccess(int responseCode, InputStream responseData) { String responseAsString = new String( StreamsUtil.inputStreamToByteArray(responseData)); ConnectManager.setFailureAttempt(0); - Log.e("DEBUG_TESTING12", "responseAsString: " + responseAsString); if (responseAsString.length() > 0) { JSONObject json = new JSONObject(responseAsString); - Log.e("DEBUG_TESTING12", "json: " + json.toString()); String key = ConnectConstants.CONNECT_KEY_USERNAME; if (json.has(key)) { username = json.getString(key); @@ -269,15 +266,16 @@ public void processSuccess(int responseCode, InputStream responseData) { key = ConnectConstants.CONNECT_PAYMENT_INFO; String paymentName = "",paymentPhone = ""; -// if(json.has(key)){ -// JSONObject paymentJson = json.getJSONObject(key); -// paymentName = paymentJson.getString(""); -// paymentPhone = paymentJson.getString(""); -// } + if(json.has(key)){ + JSONObject paymentJson = json.getJSONObject(key); + paymentName = paymentJson.getString("owner_name"); + paymentPhone = paymentJson.getString("phone_number"); + } ConnectUserRecord user = new ConnectUserRecord(phone, username, "", name, "",paymentName,paymentPhone); user.setPin(pin); + user.setLastPinDate(new Date()); key = ConnectConstants.CONNECT_KEY_VALIDATE_SECONDARY_PHONE_BY; @@ -339,6 +337,7 @@ public void processSuccess(int responseCode, InputStream responseData) { finish(true, false, user.getPin()); } + @Override public void processFailure(int responseCode, IOException e) { Toast.makeText(context, getString(R.string.connect_recovery_failure),