package bf.io.openshop.ux.fragments; import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.TextInputLayout; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.LinearLayout; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyError; import org.json.JSONException; import org.json.JSONObject; import bf.io.openshop.CONST; import bf.io.openshop.MyApplication; import bf.io.openshop.R; import bf.io.openshop.SettingsMy; import bf.io.openshop.api.EndPoints; import bf.io.openshop.api.GsonRequest; import bf.io.openshop.api.JsonRequest; import bf.io.openshop.entities.User; import bf.io.openshop.listeners.OnSingleClickListener; import bf.io.openshop.utils.JsonUtils; import bf.io.openshop.utils.MsgUtils; import bf.io.openshop.utils.Utils; import bf.io.openshop.ux.MainActivity; import bf.io.openshop.ux.dialogs.LoginExpiredDialogFragment; import timber.log.Timber; /** * Fragment provides options to editing user information and password change. */ public class AccountEditFragment extends Fragment { private ProgressDialog progressDialog; /** * Indicate which fort is active. */ private boolean isPasswordForm = false; // Account editing form private LinearLayout accountForm; private TextInputLayout nameInputWrapper; private TextInputLayout streetInputWrapper; private TextInputLayout houseNumberInputWrapper; private TextInputLayout cityInputWrapper; private TextInputLayout zipInputWrapper; private TextInputLayout phoneInputWrapper; private TextInputLayout emailInputWrapper; // Password change form private LinearLayout passwordForm; private TextInputLayout currentPasswordWrapper; private TextInputLayout newPasswordWrapper; private TextInputLayout newPasswordAgainWrapper; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Timber.d("%s - OnCreateView", this.getClass().getSimpleName()); MainActivity.setActionBarTitle(getString(R.string.Account)); View view = inflater.inflate(R.layout.fragment_account_edit, container, false); progressDialog = Utils.generateProgressDialog(getActivity(), false); // Account details form accountForm = (LinearLayout) view.findViewById(R.id.account_edit_form); nameInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_name_wrapper); streetInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_street_wrapper); houseNumberInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_house_number_wrapper); cityInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_city_wrapper); zipInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_zip_wrapper); phoneInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_phone_wrapper); emailInputWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_email_wrapper); // Password form passwordForm = (LinearLayout) view.findViewById(R.id.account_edit_password_form); currentPasswordWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_password_current_wrapper); newPasswordWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_password_new_wrapper); newPasswordAgainWrapper = (TextInputLayout) view.findViewById(R.id.account_edit_password_new_again_wrapper); final Button btnChangePassword = (Button) view.findViewById(R.id.account_edit_change_form_btn); btnChangePassword.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isPasswordForm) { isPasswordForm = false; passwordForm.setVisibility(View.GONE); accountForm.setVisibility(View.VISIBLE); btnChangePassword.setText(getString(R.string.Change_password)); } else { isPasswordForm = true; passwordForm.setVisibility(View.VISIBLE); accountForm.setVisibility(View.GONE); btnChangePassword.setText(R.string.Cancel); } } }); // Fill user informations User activeUser = SettingsMy.getActiveUser(); if (activeUser != null) { refreshScreen(activeUser); Timber.d("user: %s", activeUser.toString()); } else { Timber.e(new RuntimeException(), "No active user. Shouldn't happen."); } Button confirmButton = (Button) view.findViewById(R.id.account_edit_confirm_button); confirmButton.setOnClickListener(new OnSingleClickListener() { @Override public void onSingleClick(View view) { if (!isPasswordForm) { try { User user = getUserFromView(); putUser(user); } catch (Exception e) { Timber.e(e, "Update user information exception."); MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_INTERNAL_ERROR, null, MsgUtils.ToastLength.SHORT); } } else { changePassword(); } // Remove soft keyboard if (getActivity().getCurrentFocus() != null) { InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0); } } }); return view; } @Override public void onPause() { if (getActivity().getCurrentFocus() != null) { InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0); } super.onPause(); } private User getUserFromView() { User user = new User(); user.setName(Utils.getTextFromInputLayout(nameInputWrapper)); user.setStreet(Utils.getTextFromInputLayout(streetInputWrapper)); user.setHouseNumber(Utils.getTextFromInputLayout(houseNumberInputWrapper)); user.setCity(Utils.getTextFromInputLayout(cityInputWrapper)); user.setZip(Utils.getTextFromInputLayout(zipInputWrapper)); user.setPhone(Utils.getTextFromInputLayout(phoneInputWrapper)); return user; } private void refreshScreen(User user) { Utils.setTextToInputLayout(nameInputWrapper, user.getName()); Utils.setTextToInputLayout(streetInputWrapper, user.getStreet()); Utils.setTextToInputLayout(houseNumberInputWrapper, user.getHouseNumber()); Utils.setTextToInputLayout(cityInputWrapper, user.getCity()); Utils.setTextToInputLayout(zipInputWrapper, user.getZip()); Utils.setTextToInputLayout(emailInputWrapper, user.getEmail()); Utils.setTextToInputLayout(phoneInputWrapper, user.getPhone()); } /** * Check if all input fields are filled. * Method highlights all unfilled input fields. * * @return true if everything is Ok. */ private boolean isRequiredFields() { // Check and show all missing values String fieldRequired = getString(R.string.Required_field); boolean nameCheck = Utils.checkTextInputLayoutValueRequirement(nameInputWrapper, fieldRequired); boolean streetCheck = Utils.checkTextInputLayoutValueRequirement(streetInputWrapper, fieldRequired); boolean houseNumberCheck = Utils.checkTextInputLayoutValueRequirement(houseNumberInputWrapper, fieldRequired); boolean cityCheck = Utils.checkTextInputLayoutValueRequirement(cityInputWrapper, fieldRequired); boolean zipCheck = Utils.checkTextInputLayoutValueRequirement(zipInputWrapper, fieldRequired); boolean phoneCheck = Utils.checkTextInputLayoutValueRequirement(phoneInputWrapper, fieldRequired); boolean emailCheck = Utils.checkTextInputLayoutValueRequirement(emailInputWrapper, fieldRequired); return nameCheck && streetCheck && houseNumberCheck && cityCheck && zipCheck && phoneCheck && emailCheck; } /** * Check if all input password fields are filled and entries for new password matches. * * @return true if everything is Ok. */ private boolean isRequiredPasswordFields() { String fieldRequired = getString(R.string.Required_field); boolean currentCheck = Utils.checkTextInputLayoutValueRequirement(currentPasswordWrapper, fieldRequired); boolean newCheck = Utils.checkTextInputLayoutValueRequirement(newPasswordWrapper, fieldRequired); boolean newAgainCheck = Utils.checkTextInputLayoutValueRequirement(newPasswordAgainWrapper, fieldRequired); if (newCheck && newAgainCheck) { if (!Utils.getTextFromInputLayout(newPasswordWrapper).equals(Utils.getTextFromInputLayout(newPasswordAgainWrapper))) { Timber.d("The entries for the new password must match"); newPasswordWrapper.setErrorEnabled(true); newPasswordAgainWrapper.setErrorEnabled(true); newPasswordWrapper.setError(getString(R.string.The_entries_must_match)); newPasswordAgainWrapper.setError(getString(R.string.The_entries_must_match)); return false; } else { newPasswordWrapper.setErrorEnabled(false); newPasswordAgainWrapper.setErrorEnabled(false); } } return currentCheck && newCheck && newAgainCheck; } /** * Volley request for update user details. * * @param user new user data. */ private void putUser(User user) { if (isRequiredFields()) { User activeUser = SettingsMy.getActiveUser(); if (activeUser != null) { JSONObject joUser = new JSONObject(); try { joUser.put(JsonUtils.TAG_NAME, user.getName()); joUser.put(JsonUtils.TAG_STREET, user.getStreet()); joUser.put(JsonUtils.TAG_HOUSE_NUMBER, user.getHouseNumber()); joUser.put(JsonUtils.TAG_CITY, user.getCity()); joUser.put(JsonUtils.TAG_ZIP, user.getZip()); joUser.put(JsonUtils.TAG_EMAIL, user.getEmail()); joUser.put(JsonUtils.TAG_PHONE, user.getPhone()); } catch (JSONException e) { Timber.e(e, "Parse new user registration exception."); MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_INTERNAL_ERROR, null, MsgUtils.ToastLength.SHORT); return; } String url = String.format(EndPoints.USER_SINGLE, SettingsMy.getActualNonNullShop(getActivity()).getId(), activeUser.getId()); progressDialog.show(); GsonRequest<User> req = new GsonRequest<>(Request.Method.PUT, url, joUser.toString(), User.class, new Response.Listener<User>() { @Override public void onResponse(@NonNull User user) { SettingsMy.setActiveUser(user); refreshScreen(user); progressDialog.cancel(); MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_MESSAGE, getString(R.string.Ok), MsgUtils.ToastLength.SHORT); getFragmentManager().popBackStackImmediate(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { if (progressDialog != null) progressDialog.cancel(); MsgUtils.logAndShowErrorMessage(getActivity(), error); } }, getFragmentManager(), activeUser.getAccessToken()); req.setRetryPolicy(MyApplication.getDefaultRetryPolice()); req.setShouldCache(false); MyApplication.getInstance().addToRequestQueue(req, CONST.ACCOUNT_EDIT_REQUESTS_TAG); } else { LoginExpiredDialogFragment loginExpiredDialogFragment = new LoginExpiredDialogFragment(); loginExpiredDialogFragment.show(getFragmentManager(), "loginExpiredDialogFragment"); } } else { Timber.d("Missing required fields."); } } /** * Updates the user's password. Before the request is sent, the input fields are checked for valid values. */ private void changePassword() { if (isRequiredPasswordFields()) { User user = SettingsMy.getActiveUser(); if (user != null) { String url = String.format(EndPoints.USER_CHANGE_PASSWORD, SettingsMy.getActualNonNullShop(getActivity()).getId(), user.getId()); JSONObject jo = new JSONObject(); try { jo.put(JsonUtils.TAG_OLD_PASSWORD, Utils.getTextFromInputLayout(currentPasswordWrapper).trim()); jo.put(JsonUtils.TAG_NEW_PASSWORD, Utils.getTextFromInputLayout(newPasswordWrapper).trim()); Utils.setTextToInputLayout(currentPasswordWrapper, ""); Utils.setTextToInputLayout(newPasswordWrapper, ""); Utils.setTextToInputLayout(newPasswordAgainWrapper, ""); } catch (JSONException e) { Timber.e(e, "Parsing change password exception."); MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_INTERNAL_ERROR, null, MsgUtils.ToastLength.SHORT); return; } progressDialog.show(); JsonRequest req = new JsonRequest(Request.Method.PUT, url, jo, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Timber.d("Change password successful: %s", response.toString()); MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_MESSAGE, getString(R.string.Ok), MsgUtils.ToastLength.SHORT); if (progressDialog != null) progressDialog.cancel(); getFragmentManager().popBackStackImmediate(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { if (progressDialog != null) progressDialog.cancel(); MsgUtils.logAndShowErrorMessage(getActivity(), error); } }, getFragmentManager(), user.getAccessToken()); req.setRetryPolicy(MyApplication.getDefaultRetryPolice()); req.setShouldCache(false); MyApplication.getInstance().addToRequestQueue(req, CONST.ACCOUNT_EDIT_REQUESTS_TAG); } else { LoginExpiredDialogFragment loginExpiredDialogFragment = new LoginExpiredDialogFragment(); loginExpiredDialogFragment.show(getFragmentManager(), "loginExpiredDialogFragment"); } } } @Override public void onStop() { if (progressDialog != null) progressDialog.cancel(); MyApplication.getInstance().cancelPendingRequests(CONST.ACCOUNT_EDIT_REQUESTS_TAG); super.onStop(); } }