package com.odoo.core.account; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.odoo.App; import com.odoo.OdooActivity; import com.odoo.R; import com.odoo.base.addons.res.ResCompany; import com.odoo.config.FirstLaunchConfig; import com.odoo.core.auth.OdooAccountManager; import com.odoo.core.auth.OdooAuthenticator; import com.odoo.core.orm.ODataRow; import com.odoo.core.support.OUser; import com.odoo.core.support.OdooInstancesSelectorDialog; import com.odoo.core.support.OdooUserLoginSelectorDialog; import com.odoo.core.utils.IntentUtils; import com.odoo.core.utils.OResource; import com.odoo.datas.OConstants; import java.util.ArrayList; import java.util.List; import odoo.Odoo; import odoo.helper.OdooInstance; import odoo.listeners.IDatabaseListListener; import odoo.listeners.IOdooConnectionListener; import odoo.listeners.IOdooInstanceListener; import odoo.listeners.IOdooLoginCallback; import odoo.listeners.OdooError; public class OdooLogin extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, OdooInstancesSelectorDialog.OnInstanceSelectListener, OdooUserLoginSelectorDialog.IUserLoginSelectListener, IOdooConnectionListener, IOdooLoginCallback { private EditText edtUsername, edtPassword, edtSelfHosted; private Boolean mCreateAccountRequest = false; private Boolean mSelfHostedURL = false; private Boolean mConnectedToServer = false; private Boolean mAutoLogin = false; private Boolean mRequestedForAccount = false; private AccountCreater accountCreator = null; private Spinner databaseSpinner = null; private List<String> databases = new ArrayList<>(); private TextView mLoginProcessStatus = null; private TextView mTermsCondition; private App mApp; private Odoo mOdoo; private odoo.helper.OUser mUser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.base_login); mApp = (App) getApplicationContext(); Bundle extras = getIntent().getExtras(); if (extras != null) { if (extras.containsKey(OdooAuthenticator.KEY_NEW_ACCOUNT_REQUEST)) mCreateAccountRequest = true; if (extras.containsKey(OdooActivity.KEY_ACCOUNT_REQUEST)) { mRequestedForAccount = true; setResult(RESULT_CANCELED); } } if (!mCreateAccountRequest) { if (OdooAccountManager.anyActiveUser(this)) { startOdooActivity(); return; } else if (OdooAccountManager.hasAnyAccount(this)) { onRequestAccountSelect(); } } init(); } private void init() { mLoginProcessStatus = (TextView) findViewById(R.id.login_process_status); mTermsCondition = (TextView) findViewById(R.id.termsCondition); mTermsCondition.setMovementMethod(LinkMovementMethod.getInstance()); findViewById(R.id.btnLogin).setOnClickListener(this); findViewById(R.id.forgot_password).setOnClickListener(this); findViewById(R.id.create_account).setOnClickListener(this); findViewById(R.id.txvAddSelfHosted).setOnClickListener(this); edtSelfHosted = (EditText) findViewById(R.id.edtSelfHostedURL); } private void startOdooActivity() { startActivity(new Intent(this, OdooActivity.class)); finish(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_base_login, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.txvAddSelfHosted: toggleSelfHostedURL(); break; case R.id.btnLogin: loginUser(); break; case R.id.forgot_password: IntentUtils.openURLInBrowser(this, OConstants.URL_ODOO_RESET_PASSWORD); break; case R.id.create_account: IntentUtils.openURLInBrowser(this, OConstants.URL_ODOO_SIGN_UP); break; } } private void toggleSelfHostedURL() { TextView txvAddSelfHosted = (TextView) findViewById(R.id.txvAddSelfHosted); if (!mSelfHostedURL) { mSelfHostedURL = true; findViewById(R.id.layoutSelfHosted).setVisibility(View.VISIBLE); edtSelfHosted.setOnFocusChangeListener(this); edtSelfHosted.requestFocus(); txvAddSelfHosted.setText(R.string.label_login_with_odoo); } else { findViewById(R.id.layoutBorderDB).setVisibility(View.GONE); findViewById(R.id.layoutDatabase).setVisibility(View.GONE); findViewById(R.id.layoutSelfHosted).setVisibility(View.GONE); mSelfHostedURL = false; txvAddSelfHosted.setText(R.string.label_add_self_hosted_url); edtSelfHosted.setText(""); } } @Override public void onFocusChange(final View v, final boolean hasFocus) { new Handler().postDelayed(new Runnable() { @Override public void run() { if (mSelfHostedURL && v.getId() == R.id.edtSelfHostedURL && !hasFocus) { if (!TextUtils.isEmpty(edtSelfHosted.getText()) && validateURL(edtSelfHosted.getText().toString())) { edtSelfHosted.setError(null); if (mAutoLogin) { findViewById(R.id.controls).setVisibility(View.GONE); findViewById(R.id.login_progress).setVisibility(View.VISIBLE); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_connecting_to_server)); } findViewById(R.id.imgValidURL).setVisibility(View.GONE); findViewById(R.id.serverURLCheckProgress).setVisibility(View.VISIBLE); findViewById(R.id.layoutBorderDB).setVisibility(View.GONE); findViewById(R.id.layoutDatabase).setVisibility(View.GONE); String test_url = createServerURL(edtSelfHosted.getText().toString()); Log.v("", "Testing URL :" + test_url); Odoo.createInstance(OdooLogin.this, test_url).setOnConnect(OdooLogin.this); } } } }, 500); } private boolean validateURL(String url) { return (url.contains(".")); } private String createServerURL(String server_url) { StringBuilder serverURL = new StringBuilder(); if (!server_url.contains("http://") && !server_url.contains("https://")) { serverURL.append("http://"); } serverURL.append(server_url); return serverURL.toString(); } // User Login private void loginUser() { Log.v("", "LoginUser()"); String serverURL = createServerURL((mSelfHostedURL) ? edtSelfHosted.getText().toString() : OConstants.URL_ODOO); String databaseName; edtUsername = (EditText) findViewById(R.id.edtUserName); edtPassword = (EditText) findViewById(R.id.edtPassword); if (mSelfHostedURL) { edtSelfHosted.setError(null); if (TextUtils.isEmpty(edtSelfHosted.getText())) { edtSelfHosted.setError(OResource.string(this, R.string.error_provide_server_url)); edtSelfHosted.requestFocus(); return; } if (databaseSpinner != null && databases.size() > 1 && databaseSpinner.getSelectedItemPosition() == 0) { Toast.makeText(this, OResource.string(this, R.string.label_select_database), Toast.LENGTH_LONG).show(); return; } } edtUsername.setError(null); edtPassword.setError(null); if (TextUtils.isEmpty(edtUsername.getText())) { edtUsername.setError(OResource.string(this, R.string.error_provide_username)); edtUsername.requestFocus(); return; } if (TextUtils.isEmpty(edtPassword.getText())) { edtPassword.setError(OResource.string(this, R.string.error_provide_password)); edtPassword.requestFocus(); return; } findViewById(R.id.controls).setVisibility(View.GONE); findViewById(R.id.login_progress).setVisibility(View.VISIBLE); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_connecting_to_server)); if (mConnectedToServer) { databaseName = databases.get(0); if (databaseSpinner != null) { databaseName = databases.get(databaseSpinner.getSelectedItemPosition()); } mAutoLogin = false; loginProcess(null, serverURL, databaseName); } else { mAutoLogin = true; Log.v("", "Testing URL: " + serverURL); Odoo.createInstance(OdooLogin.this, serverURL).setOnConnect(OdooLogin.this); } } private void showDatabases() { if (databases.size() > 1) { findViewById(R.id.layoutBorderDB).setVisibility(View.VISIBLE); findViewById(R.id.layoutDatabase).setVisibility(View.VISIBLE); databaseSpinner = (Spinner) findViewById(R.id.spinnerDatabaseList); databases.add(0, OResource.string(this, R.string.label_select_database)); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, databases); databaseSpinner.setAdapter(adapter); } else { databaseSpinner = null; findViewById(R.id.layoutBorderDB).setVisibility(View.GONE); findViewById(R.id.layoutDatabase).setVisibility(View.GONE); } } @Override public void onUserSelected(OUser user) { OdooAccountManager.login(this, user.getAndroidName()); startOdooActivity(); } @Override public void onRequestAccountSelect() { OdooUserLoginSelectorDialog dialog = new OdooUserLoginSelectorDialog(this); dialog.setUserLoginSelectListener(this); dialog.show(); } @Override public void onNewAccountRequest() { init(); } @Override public void onConnect(Odoo odoo) { Log.v("Odoo", "Connected to server."); mOdoo = odoo; databases.clear(); findViewById(R.id.serverURLCheckProgress).setVisibility(View.GONE); edtSelfHosted.setError(null); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_connected_to_server)); mOdoo.getDatabaseList(new IDatabaseListListener() { @Override public void onDatabasesLoad(List<String> strings) { databases.addAll(strings); showDatabases(); mConnectedToServer = true; findViewById(R.id.imgValidURL).setVisibility(View.VISIBLE); if (mAutoLogin) { loginUser(); } } }); } @Override public void onError(OdooError error) { // Some error occurred if (error.getResponseCode() == Odoo.ErrorCode.InvalidURL.get() || error.getResponseCode() == -1) { edtSelfHosted.setError(OResource.string(OdooLogin.this, R.string.error_invalid_odoo_url)); edtSelfHosted.requestFocus(); } canceledInstanceSelect(); } @Override public void onCancelSelect() { } @Override public void canceledInstanceSelect() { findViewById(R.id.controls).setVisibility(View.VISIBLE); findViewById(R.id.login_progress).setVisibility(View.GONE); findViewById(R.id.serverURLCheckProgress).setVisibility(View.VISIBLE); } @Override public void instanceSelected(OdooInstance instance) { // Logging in to instance loginProcess(instance, null, null); } private void loginProcess(final OdooInstance instance, String url, final String database) { Log.v("", "LoginProcess"); final String username = edtUsername.getText().toString(); final String password = edtPassword.getText().toString(); if (instance == null && url.equals(OConstants.URL_ODOO)) { // OAuth Login or Odoo.com Login mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_getting_instances)); mOdoo.authenticate(username, password, database, new IOdooLoginCallback() { @Override public void onLoginSuccess(Odoo odoo, odoo.helper.OUser oUser) { mOdoo = odoo; mUser = oUser; mOdoo.getSaasInstances(new IOdooInstanceListener() { @Override public void onInstancesLoad(List<OdooInstance> odooInstances) { OdooInstance oInstance = new OdooInstance(); oInstance.setCompanyName(OConstants.ODOO_COMPANY_NAME); oInstance.setUrl(OConstants.URL_ODOO); oInstance.setDbName(database); odooInstances.add(0, oInstance); if (odooInstances.size() > 1) { OdooInstancesSelectorDialog instancesSelectorDialog = new OdooInstancesSelectorDialog(OdooLogin.this); instancesSelectorDialog.setInstances(odooInstances); instancesSelectorDialog.setOnInstanceSelectListener(OdooLogin.this); instancesSelectorDialog.showDialog(); } else { //Loggin in to odoo.com (default instance) loginProcess(oInstance, oInstance.getUrl(), database); } } }); } @Override public void onLoginFail(OdooError error) { loginFail(error); } }); } else if (instance == null) { Log.v("", "Processing Self Hosted Server Login"); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_logging_in)); mOdoo.authenticate(username, password, database, this); } else { // Instance login Log.v("", "Processing Odoo Instance Login"); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_logging_in_with_instance)); new AsyncTask<Void, Void, odoo.helper.OUser>() { @Override protected odoo.helper.OUser doInBackground(Void... params) { // Need to execute in background task. return mOdoo.oAuthLogin(instance, username, password); } @Override protected void onPostExecute(odoo.helper.OUser oUser) { super.onPostExecute(oUser); onLoginSuccess(mOdoo, oUser); } }.execute(); } } @Override public void onLoginSuccess(Odoo odoo, odoo.helper.OUser oUser) { mApp.setOdoo(odoo, oUser); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_login_success)); mOdoo = odoo; if (accountCreator != null) { accountCreator.cancel(true); } accountCreator = new AccountCreater(); OUser user = new OUser(); user.setFromBundle(oUser.getAsBundle()); accountCreator.execute(user); } @Override public void onLoginFail(OdooError error) { loginFail(error); } private void loginFail(OdooError error) { findViewById(R.id.controls).setVisibility(View.VISIBLE); findViewById(R.id.login_progress).setVisibility(View.GONE); edtUsername.setError(OResource.string(this, R.string.error_invalid_username_or_password)); } private class AccountCreater extends AsyncTask<OUser, Void, Boolean> { private OUser mUser; @Override protected void onPreExecute() { super.onPreExecute(); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_creating_account)); } @Override protected Boolean doInBackground(OUser... params) { mUser = params[0]; if (OdooAccountManager.createAccount(OdooLogin.this, mUser)) { mUser = OdooAccountManager.getDetails(OdooLogin.this, mUser.getAndroidName()); OdooAccountManager.login(OdooLogin.this, mUser.getAndroidName()); FirstLaunchConfig.onFirstLaunch(OdooLogin.this, mUser); try { // Syncing company details ODataRow company_details = new ODataRow(); company_details.put("id", mUser.getCompanyId()); ResCompany company = new ResCompany(OdooLogin.this, mUser); company.quickCreateRecord(company_details); Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } return true; } return false; } @Override protected void onPostExecute(Boolean success) { super.onPostExecute(success); mLoginProcessStatus.setText(OResource.string(OdooLogin.this, R.string.status_redirecting)); new Handler().postDelayed(new Runnable() { @Override public void run() { if (!mRequestedForAccount) startOdooActivity(); else { Intent intent = new Intent(); intent.putExtra(OdooActivity.KEY_NEW_USER_NAME, mUser.getAndroidName()); setResult(RESULT_OK, intent); finish(); } } }, 1500); } } }