/* * Copyright 2019 Arcus Project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package arcus.app.account.registration; import android.app.Activity; import android.graphics.Color; import android.graphics.PorterDuff; import android.os.Bundle; import androidx.annotation.NonNull; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.TextView; import com.iris.client.model.AccountModel; import arcus.app.R; import arcus.app.account.registration.controller.task.SaveCreditCardTask; import arcus.app.account.registration.controller.task.UpdateCreditCardTask; import arcus.app.common.adapters.SpinnerAdapter; import arcus.app.common.backstack.BackstackManager; import arcus.app.common.error.ErrorDuring; import arcus.app.common.error.ErrorManager; import arcus.app.common.utils.GlobalSetting; import arcus.app.common.validation.CreditCardTextFormatter; import arcus.app.common.view.Version1ButtonColor; import arcus.app.common.view.Version1EditText; import arcus.app.common.view.Version1TextView; import arcus.app.subsystems.alarm.SkipFloatingFragment; import arcus.app.subsystems.scenes.editor.controller.AccountBillingInfoFragmentController; import org.apache.commons.lang3.StringUtils; import java.util.HashMap; public class AccountBillingInfoFragment extends AccountCreationStepFragment implements AccountBillingInfoFragmentController.Callbacks { private static final String FROM_SETTING = "SCREEN_VARIANT"; private Spinner state; private Version1EditText zipcode; private Version1EditText street1; private Version1EditText street2; private Version1EditText city; private Version1EditText firstName; private Version1EditText lastName; private Version1EditText cardNumber; private Version1EditText cvc; private Spinner expMonth; private Spinner expYear; private SpinnerAdapter adapter; private boolean skipEnabled = true; @NonNull private ScreenVariant variant = ScreenVariant.ACCOUNT_CREATION; public enum ScreenVariant { SETTINGS, ACCOUNT_CREATION } @NonNull public static AccountBillingInfoFragment newInstance(ScreenVariant variant) { AccountBillingInfoFragment fragment = new AccountBillingInfoFragment(); Bundle bundle = new Bundle(); bundle.putSerializable(FROM_SETTING, variant); fragment.setArguments(bundle); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); Bundle bundle = getArguments(); if (bundle != null) { variant = (ScreenVariant) bundle.getSerializable(FROM_SETTING); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); Version1TextView expiration = (Version1TextView) view.findViewById(R.id.expiration_text); firstName = (Version1EditText) view.findViewById(R.id.etCardFirstName); lastName = (Version1EditText) view.findViewById(R.id.etCardLastName); cardNumber = (Version1EditText) view.findViewById(R.id.etCardNumber); cvc = (Version1EditText) view.findViewById(R.id.etCvc); expMonth = (Spinner) view.findViewById(R.id.spMonthExp); expYear = (Spinner) view.findViewById(R.id.spExpYear); setupMonthSpinner(); setUpYearSpinner(); street1 = (Version1EditText) view.findViewById(R.id.fragment_account_billing_street1); street2 = (Version1EditText) view.findViewById(R.id.fragment_account_billing_street2); city = (Version1EditText) view.findViewById(R.id.fragment_account_billing_city); zipcode = (Version1EditText) view.findViewById(R.id.fragment_account_billing_zipcode); state = (Spinner) view.findViewById(R.id.fragment_account_billing_state); setUpStateSpinner(); cardNumber.addTextChangedListener(new CreditCardTextFormatter()); if (variant == ScreenVariant.SETTINGS) { firstName.useLightColorScheme(true).useUppercaseLabels(); lastName.useLightColorScheme(true).useUppercaseLabels(); cardNumber.useLightColorScheme(true).useUppercaseLabels(); street1.useLightColorScheme(true).useUppercaseLabels(); street2.useLightColorScheme(true).useUppercaseLabels(); city.useLightColorScheme(true).useUppercaseLabels(); zipcode.useLightColorScheme(true).useUppercaseLabels(); cvc.useLightColorScheme(true).useUppercaseLabels(); expiration.setTextColor(getResources().getColor(R.color.overlay_white_with_60)); getButton().setColorScheme(Version1ButtonColor.WHITE); getButton().setText(getString(R.string.account_setting_save_btn)); } switch (variant) { case SETTINGS: AccountBillingInfoFragmentController controller = new AccountBillingInfoFragmentController(); controller.loadAccountModel(this); break; case ACCOUNT_CREATION: default: //in this cae, we want to leave the fields alone break; } return view; } @Override public String getTitle() { switch (variant) { case SETTINGS: return getString(R.string.payment_info_text); default: return getString(R.string.account_registration_credit_card); } } @Override public Integer getLayoutId() { return R.layout.fragment_account_credit; } private void setupMonthSpinner() { boolean isSettingsVariant = variant == ScreenVariant.SETTINGS; adapter = new SpinnerAdapter( //context getActivity(), //spinner closed state (view) R.layout.spinner_item_state_closed, //model getResources().getStringArray(R.array .account_registration_exp_month_list), //color scheme isSettingsVariant ); adapter.setDisabledItems(0); expMonth.setAdapter(adapter); if (isSettingsVariant) { expMonth.getBackground().setColorFilter(getResources().getColor(R.color.overlay_white_with_50), PorterDuff.Mode.SRC_ATOP); } } private void setUpYearSpinner() { boolean isSettingsVariant = variant == ScreenVariant.SETTINGS; adapter = new SpinnerAdapter( //context getActivity(), //spinner closed state (view) R.layout.spinner_item_state_closed, //model getResources().getStringArray(R.array .account_registration_exp_year_list), //color scheme isSettingsVariant ); adapter.setDisabledItems(0); expYear.setAdapter(adapter); if (isSettingsVariant) { expYear.getBackground().setColorFilter(getResources().getColor(R.color.overlay_white_with_50), PorterDuff.Mode.SRC_ATOP); } } private void setUpStateSpinner() { boolean isSettingsVariant = variant == ScreenVariant.SETTINGS; adapter = new SpinnerAdapter( //context getActivity(), //spinner closed state (view) R.layout.spinner_item_state_closed, //model getResources().getStringArray(R.array.states), //color scheme isSettingsVariant ); adapter.setDisabledItems(0); state.setAdapter(adapter); if (isSettingsVariant) { state.getBackground().setColorFilter(getResources().getColor(R.color.overlay_white_with_50), PorterDuff.Mode.SRC_ATOP); } } @Override public boolean validate() { boolean dataIsValid = true; TextView errorExpMonth; TextView errorExpYear; TextView errorState; if (firstName.getText() != null && StringUtils.isBlank(firstName.getText().toString())) { firstName.setError(getString(R.string.account_registration_first_name_blank_error)); dataIsValid = false; } if (lastName.getText() != null && StringUtils.isBlank(lastName.getText().toString())) { lastName.setError(getString(R.string.account_registration_last_name_blank_error)); dataIsValid = false; } if (cardNumber.getText() != null && StringUtils.isBlank(cardNumber.getText().toString())) { cardNumber.setError(getString(R.string.account_registration_card_number_blank_error)); dataIsValid = false; } if (cvc.getText() != null && StringUtils.isBlank(cvc.getText().toString())) { cvc.setError(getString(R.string.account_registration_cvv_blank_error)); dataIsValid = false; } if (expMonth.getSelectedItemPosition() == 0) { errorExpMonth = (TextView) expMonth.getSelectedView(); errorExpMonth.setError(""); errorExpMonth.setTextColor(Color.RED); dataIsValid = false; } if (expYear.getSelectedItemPosition() == 0) { errorExpYear = (TextView) expYear.getSelectedView(); errorExpYear.setError(""); errorExpYear.setTextColor(Color.RED); dataIsValid = false; } if (state.getSelectedItemPosition() == 0) { errorState = (TextView) state.getSelectedView(); errorState.setError(getString(R.string.account_registration_state_blank_error)); errorState.setTextColor(Color.RED); dataIsValid = false; } if (street1.getText() != null && StringUtils.isBlank(street1.getText().toString())) { street1.setError(getString(R.string.account_registration_street_blank_error)); dataIsValid = false; } if (city.getText() != null && StringUtils.isBlank(city.getText().toString())) { city.setError(getString(R.string.account_registration_city_blank_error)); dataIsValid = false; } if (zipcode.getText() != null && StringUtils.isBlank(zipcode.getText().toString())) { zipcode.setError(getString(R.string.account_registration_zipcode_blank_error)); dataIsValid = false; } return dataIsValid; } @Override public boolean submit() { HashMap<String, String> creditInfo = new HashMap<>(); creditInfo.put(GlobalSetting.CREDIT_INFO_FIRST_NAME_KEY, firstName.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_LAST_NAME_KEY, lastName.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_YEAR_KEY, expYear.getSelectedItem().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_MONTH_KEY, expMonth.getSelectedItem().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_ADDRESS1_KEY, street1.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_ADDRESS2_KEY, street2.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_CITY_KEY, city.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_STATE_KEY, state.getSelectedItem().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_ZIPCODE_KEY, zipcode.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_COUNTRY_KEY, "USA"); creditInfo.put(GlobalSetting.CREDIT_INFO_CARD_NUMBER_KEY, cardNumber.getText().toString()); creditInfo.put(GlobalSetting.CREDIT_INFO_VERIFICATION_CODE_KEY, cvc.getText().toString()); registrationContext.setCreditInfo(creditInfo); if (variant == ScreenVariant.SETTINGS) { new UpdateCreditCardTask(getActivity(), this, this, getCorneaService(), registrationContext).execute(); } else { new SaveCreditCardTask(getActivity(), this, this, getCorneaService(), registrationContext).execute(); } return true; } @Override public void onComplete(boolean result) { logger.debug("Successfully submit credit card info:{}", result); if (variant == ScreenVariant.SETTINGS) { hideProgressBar(); BackstackManager.getInstance().navigateBack(); } else { super.onComplete(result); } } @Override public void onError(Exception e) { logger.error("Got exception when sending credit card info: {}", e); hideProgressBar(); getButton().setEnabled(true); ErrorManager.in(getActivity()).got(e).during(ErrorDuring.ENTER_BILLING_INFO); } private void setSpinnerByValue(Spinner spinner, String value){ ArrayAdapter<CharSequence> arrayAdapter = (ArrayAdapter<CharSequence>) spinner.getAdapter(); int spinnerPosition = arrayAdapter.getPosition(value); spinner.setSelection(spinnerPosition); } //callback methods for AccountBillingInfoFragmentController @Override public void onAccountModelLoaded(AccountModel model) { firstName.setText(model.getBillingFirstName()); lastName.setText(model.getBillingLastName()); street1.setText(model.getBillingStreet1()); street2.setText(model.getBillingStreet2()); city.setText(model.getBillingCity()); zipcode.setText(model.getBillingZip()); setSpinnerByValue(state, model.getBillingState()); } @Override public void onCorneaError(Throwable cause) { ErrorManager.in(getActivity()).showGenericBecauseOf(cause); } public void setSkipEnabled(boolean skip) { this.skipEnabled = skip; getActivity().invalidateOptionsMenu(); } private void showSkipDialog() { setSkipEnabled(false); final SkipFloatingFragment skipCreditCard = SkipFloatingFragment.newInstance( getActivity().getString(R.string.skip_cc_no), getActivity().getString(R.string.skip_cc_yes), new SkipFloatingFragment.AlertButtonCallback() { @Override public boolean topAlertButtonClicked() { setSkipEnabled(true); return true; } @Override public boolean bottomAlertButtonClicked() { BackstackManager.getInstance().navigateBack(); getController().skipForward(AccountCongratsFragment.newInstance()); return false; } @Override public void dialogClosed() { setSkipEnabled(true); } } ); BackstackManager.getInstance().navigateToFloatingFragment(skipCreditCard, skipCreditCard.getClass().getSimpleName(), true); } public void handleBackPress() { if (!skipEnabled) { // Hide the skip dialog. // Is called from the MainActivity class overriding the default sequenced fragment behavior of normal goBack() call. setSkipEnabled(true); BackstackManager.getInstance().navigateBack(); } else { goBack(); } } @Override public void onResume() { super.onResume(); Activity activity = getActivity(); if (activity != null) { activity.setTitle(getTitle()); activity.invalidateOptionsMenu(); Window window = activity.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); } } @Override public void onDestroy() { super.onDestroy(); Activity activity = getActivity(); if (activity != null) { Window window = activity.getWindow(); window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } } @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); if (ScreenVariant.SETTINGS.equals(variant)) { return; } if (skipEnabled) menu.getItem(0).setEnabled(true); else menu.getItem(0).setEnabled(false); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if (ScreenVariant.SETTINGS.equals(variant)) { return; } inflater.inflate(R.menu.menu_credit_card, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (ScreenVariant.SETTINGS.equals(variant)) { return false; } switch (item.getItemId()) { case R.id.skip_menu_item: showSkipDialog(); return true; default: return true; } } }