diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java index eac0415..ee71bfc 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java @@ -32,7 +32,7 @@ public class SettingsActivity extends BaseBackActivity { super.initViews(); // Display the fragment as the main content. - getFragmentManager().beginTransaction().replace(R.id.content, new SettingsFragment()).commit(); + getFragmentManager().beginTransaction().replace(R.id.contentView, new SettingsFragment()).commit(); } public static class SettingsFragment extends PreferenceFragment { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AddAccountActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AddAccountActivity.java index e885ac2..c799790 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AddAccountActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AddAccountActivity.java @@ -33,9 +33,9 @@ public class AddAccountActivity extends BaseBackActivity { private IValidator accountValidator; - @BindView(R.id.content) + @BindView(R.id.contentView) View contentView; - @BindView(R.id.et_title) + @BindView(R.id.etTitle) EditText etTitle; @BindView(R.id.et_init_sum) EditText etInitSum; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/TransferActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/TransferActivity.java index 668fb73..06676fe 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/TransferActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/TransferActivity.java @@ -37,7 +37,7 @@ public class TransferActivity extends BaseBackActivity { private List accountList; - @BindView(R.id.content) + @BindView(R.id.contentView) View contentView; @BindView(R.id.spinner_from) AppCompatSpinner spinnerFrom; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/exchange_rate/AddExchangeRateActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/exchange_rate/AddExchangeRateActivity.java index c24cb85..c0cb44d 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/exchange_rate/AddExchangeRateActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/exchange_rate/AddExchangeRateActivity.java @@ -44,7 +44,7 @@ public class AddExchangeRateActivity extends BaseBackActivity { @Nullable private ExchangeRatePair exchangeRatePair; - @BindView(R.id.content) + @BindView(R.id.contentView) View contentView; @BindView(R.id.spinner_from_currency) AppCompatSpinner spinnerFromCurrency; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/AddRecordActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/AddRecordActivity.java deleted file mode 100644 index ff23db7..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/AddRecordActivity.java +++ /dev/null @@ -1,383 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.activity.record; - -import android.annotation.SuppressLint; -import android.app.DatePickerDialog; -import android.app.TimePickerDialog; -import android.support.annotation.Nullable; -import android.support.v7.widget.AppCompatSpinner; -import android.text.InputFilter; -import android.text.Spanned; -import android.text.format.DateFormat; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.DatePicker; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.TimePicker; - -import com.blogspot.e_kanivets.moneytracker.R; -import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; -import com.blogspot.e_kanivets.moneytracker.adapter.CategoryAutoCompleteAdapter; -import com.blogspot.e_kanivets.moneytracker.controller.FormatController; -import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController; -import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController; -import com.blogspot.e_kanivets.moneytracker.controller.data.CategoryController; -import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController; -import com.blogspot.e_kanivets.moneytracker.entity.data.Account; -import com.blogspot.e_kanivets.moneytracker.entity.data.Category; -import com.blogspot.e_kanivets.moneytracker.entity.data.Record; -import com.blogspot.e_kanivets.moneytracker.ui.AddRecordUiDecorator; -import com.blogspot.e_kanivets.moneytracker.util.AnswersProxy; -import com.blogspot.e_kanivets.moneytracker.util.CategoryAutoCompleter; -import com.blogspot.e_kanivets.moneytracker.util.validator.IValidator; -import com.blogspot.e_kanivets.moneytracker.util.validator.RecordValidator; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.OnClick; - -/** - * Created on 1/26/16. - * - * @author Evgenii Kanivets - */ -public class AddRecordActivity extends BaseBackActivity { - @SuppressWarnings("unused") - private static final String TAG = "AddRecordActivity"; - - public static final String KEY_RECORD = "key_record"; - public static final String KEY_MODE = "key_mode"; - public static final String KEY_TYPE = "key_type"; - - @Nullable - private Record record; - private Mode mode; - private int type; - - private List accountList; - private long timestamp; - - @Inject - CategoryController categoryController; - @Inject - RecordController recordController; - @Inject - AccountController accountController; - @Inject - FormatController formatController; - @Inject - PreferenceController preferenceController; - - private IValidator recordValidator; - private AddRecordUiDecorator uiDecorator; - private CategoryAutoCompleter autoCompleter; - - @BindView(R.id.content) - View contentView; - @BindView(R.id.tv_date) - TextView tvDate; - @BindView(R.id.tv_time) - TextView tvTime; - @BindView(R.id.et_title) - EditText etTitle; - @BindView(R.id.et_category) - AutoCompleteTextView etCategory; - @BindView(R.id.et_price) - EditText etPrice; - @BindView(R.id.spinner_account) - AppCompatSpinner spinnerAccount; - - @Override - protected int getContentViewId() { - return R.layout.activity_add_record; - } - - @Override - protected boolean initData() { - super.initData(); - getAppComponent().inject(AddRecordActivity.this); - - uiDecorator = new AddRecordUiDecorator(AddRecordActivity.this); - - record = getIntent().getParcelableExtra(KEY_RECORD); - mode = (Mode) getIntent().getSerializableExtra(KEY_MODE); - type = getIntent().getIntExtra(KEY_TYPE, -1); - accountList = accountController.readActiveAccounts(); - - if (mode == Mode.MODE_EDIT && record != null) timestamp = record.getTime(); - else timestamp = new Date().getTime(); - - return mode != null && (type == Record.TYPE_INCOME || type == Record.TYPE_EXPENSE) - && (!mode.equals(Mode.MODE_EDIT) || record != null); - } - - @SuppressWarnings("deprecation") - @SuppressLint("SetTextI18n") - @Override - protected void initViews() { - super.initViews(); - - recordValidator = new RecordValidator(AddRecordActivity.this, contentView); - autoCompleter = new CategoryAutoCompleter(categoryController, preferenceController); - - // Add texts to dialog if it's edit dialog - if (mode == Mode.MODE_EDIT) { - etTitle.setText(record.getTitle()); - if (record.getCategory() != null) etCategory.setText(record.getCategory().getName()); - etPrice.setText(formatController.formatPrecisionNone(record.getFullPrice())); - } - - uiDecorator.decorateActionBar(getSupportActionBar(), mode, type); - presentSpinnerAccount(); - - - final CategoryAutoCompleteAdapter categoryAutoCompleteAdapter = new CategoryAutoCompleteAdapter( - AddRecordActivity.this, R.layout.view_category_item, autoCompleter); - etCategory.setAdapter(categoryAutoCompleteAdapter); - etCategory.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - etCategory.setText((String) parent.getAdapter().getItem(position)); - etCategory.setSelection(etCategory.getText().length()); - } - }); - etCategory.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_DONE) tryRecord(); - return false; - } - }); - etCategory.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (hasFocus && etCategory.getText().toString().trim().isEmpty()) { - String title = etTitle.getText().toString().trim(); - String prediction = autoCompleter.completeByRecordTitle(title); - if (prediction != null) { - etCategory.setAdapter(null); - etCategory.setText(prediction); - etCategory.selectAll(); - etCategory.setAdapter(categoryAutoCompleteAdapter); - } - } - } - }); - - // Restrict ';' for input, because it's used as delimiter when exporting - etTitle.setFilters(new InputFilter[]{new SemicolonInputFilter()}); - etCategory.setFilters(new InputFilter[]{new SemicolonInputFilter()}); - - updateDateAndTime(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_add_record, menu); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - switch (mode) { - case MODE_ADD: - menu.removeItem(R.id.action_delete); - break; - - default: - break; - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_done: - tryRecord(); - return true; - - case R.id.action_delete: - if (recordController.delete(record)) { - setResult(RESULT_OK); - finish(); - } - return true; - - default: - return super.onOptionsItemSelected(item); - } - } - - @OnClick(R.id.tv_date) - public void selectDate() { - AnswersProxy.get().logButton("Select Date"); - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(timestamp); - DatePickerDialog dialog = new DatePickerDialog(AddRecordActivity.this, uiDecorator.getTheme(type), - new DatePickerDialog.OnDateSetListener() { - @Override - public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(timestamp); - calendar.set(Calendar.YEAR, year); - calendar.set(Calendar.MONTH, monthOfYear); - calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); - - if (calendar.getTimeInMillis() < new Date().getTime()) { - timestamp = calendar.getTimeInMillis(); - updateDateAndTime(); - } else { - showToast(R.string.record_in_future); - } - } - }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), - calendar.get(Calendar.DAY_OF_MONTH)); - dialog.show(); - } - - @OnClick(R.id.tv_time) - public void selectTime() { - AnswersProxy.get().logButton("Show Time"); - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(timestamp); - TimePickerDialog dialog = new TimePickerDialog(AddRecordActivity.this, uiDecorator.getTheme(type), - new TimePickerDialog.OnTimeSetListener() { - @Override - public void onTimeSet(TimePicker view, int hourOfDay, int minute) { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(timestamp); - calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); - calendar.set(Calendar.MINUTE, minute); - - if (calendar.getTimeInMillis() < new Date().getTime()) { - timestamp = calendar.getTimeInMillis(); - updateDateAndTime(); - } else { - showToast(R.string.record_in_future); - } - } - }, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), - DateFormat.is24HourFormat(AddRecordActivity.this)); - dialog.show(); - } - - private void presentSpinnerAccount() { - List accounts = new ArrayList<>(); - for (Account account : accountList) { - accounts.add(account.getTitle()); - } - - int selectedAccountIndex = -1; - - if (mode == Mode.MODE_EDIT) { - if (record != null && record.getAccount() != null) { - for (int i = 0; i < accountList.size(); i++) { - Account account = accountList.get(i); - if (account.getId() == record.getAccount().getId()) selectedAccountIndex = i; - } - } - } else if (mode == Mode.MODE_ADD) { - Account defaultAccount = accountController.readDefaultAccount(); - if (defaultAccount != null) { - for (int i = 0; i < accountList.size(); i++) { - Account account = accountList.get(i); - if (account.getId() == defaultAccount.getId()) selectedAccountIndex = i; - } - } - } - - if (selectedAccountIndex == -1) { - selectedAccountIndex = 0; - spinnerAccount.setEnabled(false); - - if (accounts.size() == 0) { - accounts.add(getString(R.string.none)); - } else { - accounts.add(getString(R.string.account_was_removed)); - } - } - - spinnerAccount.setAdapter(new ArrayAdapter<>(AddRecordActivity.this, - R.layout.view_spinner_item, accounts)); - spinnerAccount.setSelection(selectedAccountIndex); - } - - private void tryRecord() { - AnswersProxy.get().logButton("Done Record"); - if (addRecord()) { - AnswersProxy.get().logEvent("Done Record"); - setResult(RESULT_OK); - finish(); - } - } - - @SuppressWarnings("SimplifiableIfStatement") - private boolean addRecord() { - if (recordValidator.validate()) { - long now = new Date().getTime(); - if (timestamp > now) { - showToast(R.string.record_in_future); - return false; - } - - String title = etTitle.getText().toString().trim(); - String category = etCategory.getText().toString().trim(); - double price = Double.parseDouble(etPrice.getText().toString()); - Account account = accountList.get(spinnerAccount.getSelectedItemPosition()); - - if (title.isEmpty()) { - title = category; - } - - Record newRecord = null; - - if (mode == Mode.MODE_ADD) { - newRecord = recordController.create(new Record(timestamp, type, title, - new Category(category), price, account, account.getCurrency())); - } else if (mode == Mode.MODE_EDIT) { - long recordId = record == null ? -1 : record.getId(); - newRecord = recordController.update(new Record(recordId, timestamp, type, title, - new Category(category), price, account, account.getCurrency())); - } - - if (newRecord == null) { - return false; - } else { - autoCompleter.addRecordTitleCategoryPair(title, category); - return true; - } - } else { - return false; - } - } - - private void updateDateAndTime() { - tvDate.setText(formatController.formatDateToNumber(timestamp)); - tvTime.setText(formatController.formatTime(timestamp)); - } - - public enum Mode {MODE_ADD, MODE_EDIT} - - private static class SemicolonInputFilter implements InputFilter { - - @Override - public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { - if (source != null && ";".equals(source.toString())) return ""; - else return null; - } - } -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/AddRecordActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/AddRecordActivity.kt new file mode 100644 index 0000000..7b02025 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/AddRecordActivity.kt @@ -0,0 +1,297 @@ +package com.blogspot.e_kanivets.moneytracker.activity.record + +import android.annotation.SuppressLint +import android.app.Activity +import android.app.DatePickerDialog +import android.app.TimePickerDialog +import android.text.InputFilter +import android.text.Spanned +import android.text.format.DateFormat +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.view.inputmethod.EditorInfo +import android.widget.AdapterView +import android.widget.ArrayAdapter +import com.blogspot.e_kanivets.moneytracker.R +import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity +import com.blogspot.e_kanivets.moneytracker.adapter.CategoryAutoCompleteAdapter +import com.blogspot.e_kanivets.moneytracker.controller.FormatController +import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController +import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController +import com.blogspot.e_kanivets.moneytracker.controller.data.CategoryController +import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController +import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import com.blogspot.e_kanivets.moneytracker.entity.data.Category +import com.blogspot.e_kanivets.moneytracker.entity.data.Record +import com.blogspot.e_kanivets.moneytracker.ui.AddRecordUiDecorator +import com.blogspot.e_kanivets.moneytracker.util.AnswersProxy +import com.blogspot.e_kanivets.moneytracker.util.CategoryAutoCompleter +import com.blogspot.e_kanivets.moneytracker.util.validator.IValidator +import com.blogspot.e_kanivets.moneytracker.util.validator.RecordValidator +import kotlinx.android.synthetic.main.content_add_record.* +import java.util.* +import javax.inject.Inject + +class AddRecordActivity : BaseBackActivity() { + + private var record: Record? = null + private var mode: Mode? = null + private var type: Int = 0 + + private var accountList: List = listOf() + private var timestamp: Long = 0 + + @Inject + lateinit var categoryController: CategoryController + @Inject + lateinit var recordController: RecordController + @Inject + lateinit var accountController: AccountController + @Inject + lateinit var formatController: FormatController + @Inject + lateinit var preferenceController: PreferenceController + + private lateinit var recordValidator: IValidator + private lateinit var uiDecorator: AddRecordUiDecorator + private lateinit var autoCompleter: CategoryAutoCompleter + + override fun getContentViewId() = R.layout.activity_add_record + + + override fun initData(): Boolean { + super.initData() + appComponent.inject(this) + + record = intent.getParcelableExtra(KEY_RECORD) + mode = intent.getSerializableExtra(KEY_MODE) as Mode + type = intent.getIntExtra(KEY_TYPE, -1) + accountList = accountController.readActiveAccounts() + + timestamp = record?.time ?: Date().time + + return (mode != null && (type == Record.TYPE_INCOME || type == Record.TYPE_EXPENSE) + && ((mode == Mode.MODE_EDIT && record != null) || (mode == Mode.MODE_ADD && record == null))) + } + + @SuppressLint("SetTextI18n") + override fun initViews() { + super.initViews() + + recordValidator = RecordValidator(this, contentView) + autoCompleter = CategoryAutoCompleter(categoryController, preferenceController) + uiDecorator = AddRecordUiDecorator(this) + + uiDecorator.decorateActionBar(supportActionBar, mode, type) + + if (mode == Mode.MODE_EDIT) { + record?.let { record -> + etTitle.setText(record.title) + etCategory.setText(record.category?.name.orEmpty()) + etPrice.setText(formatController.formatPrecisionNone(record.fullPrice)) + } + } + + initCategoryAutocomplete() + presentSpinnerAccount() + + // Restrict ';' for input, because it's used as delimiter when exporting + etTitle.filters = arrayOf(SemicolonInputFilter()) + etCategory.filters = arrayOf(SemicolonInputFilter()) + + tvDate.setOnClickListener { selectDate() } + tvTime.setOnClickListener { selectTime() } + + updateDateAndTime() + } + + private fun initCategoryAutocomplete() { + val categoryAutoCompleteAdapter = CategoryAutoCompleteAdapter( + this, R.layout.view_category_item, autoCompleter) + etCategory.setAdapter(categoryAutoCompleteAdapter) + etCategory.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> + etCategory.setText(parent.adapter.getItem(position) as String) + etCategory.setSelection(etCategory.text.length) + } + etCategory.setOnEditorActionListener { v, actionId, event -> + if (actionId == EditorInfo.IME_ACTION_DONE) tryRecord() + false + } + etCategory.onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus -> + if (hasFocus && etCategory.text.toString().trim().isEmpty()) { + val title = etTitle.text.toString().trim() + autoCompleter.completeByRecordTitle(title)?.let { prediction -> + etCategory.setText(prediction) + etCategory.selectAll() + } + } + } + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_add_record, menu) + return true + } + + override fun onPrepareOptionsMenu(menu: Menu): Boolean { + when (mode) { + Mode.MODE_ADD -> menu.removeItem(R.id.action_delete) + else -> { + } + } + + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.action_done -> { + tryRecord() + return true + } + + R.id.action_delete -> { + if (recordController.delete(record)) { + setResult(Activity.RESULT_OK) + finish() + } + return true + } + + else -> return super.onOptionsItemSelected(item) + } + } + + private fun selectDate() { + AnswersProxy.get().logButton("Select Date") + val calendar = Calendar.getInstance() + calendar.timeInMillis = timestamp + val dialog = DatePickerDialog(this, uiDecorator.getTheme(type), + DatePickerDialog.OnDateSetListener { view, year, monthOfYear, dayOfMonth -> + val newCalendar = Calendar.getInstance() + newCalendar.timeInMillis = timestamp + newCalendar.set(Calendar.YEAR, year) + newCalendar.set(Calendar.MONTH, monthOfYear) + newCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth) + + if (newCalendar.timeInMillis < Date().time) { + timestamp = newCalendar.timeInMillis + updateDateAndTime() + } else { + showToast(R.string.record_in_future) + } + }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), + calendar.get(Calendar.DAY_OF_MONTH)) + dialog.show() + } + + private fun selectTime() { + AnswersProxy.get().logButton("Show Time") + val calendar = Calendar.getInstance() + calendar.timeInMillis = timestamp + val dialog = TimePickerDialog(this, uiDecorator.getTheme(type), + TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute -> + val newCalendar = Calendar.getInstance() + newCalendar.timeInMillis = timestamp + newCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay) + newCalendar.set(Calendar.MINUTE, minute) + + if (newCalendar.timeInMillis < Date().time) { + timestamp = newCalendar.timeInMillis + updateDateAndTime() + } else { + showToast(R.string.record_in_future) + } + }, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), + DateFormat.is24HourFormat(this)) + dialog.show() + } + + private fun presentSpinnerAccount() { + val accounts = accountList.map { it.title }.toMutableList() + + var selectedAccountIndex = -1 + + if (mode == Mode.MODE_EDIT) { + if (record?.account != null) { + selectedAccountIndex = accountList.indexOf(accountList.find { it.id == record?.account?.id }) + } + } else if (mode == Mode.MODE_ADD) { + val defaultAccount = accountController.readDefaultAccount() + selectedAccountIndex = accountList.indexOf(accountList.find { it.id == defaultAccount?.id }) + } + + if (selectedAccountIndex == -1) { + spinnerAccount.isEnabled = false + + accounts.clear() + accounts.add(getString(R.string.account_removed)) + } + + spinnerAccount.adapter = ArrayAdapter(this, R.layout.view_spinner_item, accounts) + spinnerAccount.setSelection(selectedAccountIndex) + } + + private fun tryRecord() { + AnswersProxy.get().logButton("Done Record") + if (addRecord()) { + AnswersProxy.get().logEvent("Done Record") + setResult(Activity.RESULT_OK) + finish() + } + } + + private fun addRecord(): Boolean { + if (recordValidator.validate()) { + val now = Date().time + if (timestamp > now) { + showToast(R.string.record_in_future) + return false + } + + var title = etTitle.text.toString().trim() + val category = etCategory.text.toString().trim() + val price = etPrice.text.toString().toDouble() + val account = accountList[spinnerAccount.selectedItemPosition] + + if (title.isEmpty()) { + title = category + } + + if (mode == Mode.MODE_ADD) { + recordController.create(Record(timestamp, type, title, + Category(category), price, account, account.currency)) + } else if (mode == Mode.MODE_EDIT) { + recordController.update(Record(record?.id ?: -1, + timestamp, type, title, Category(category), price, account, account.currency)) + } + + autoCompleter.addRecordTitleCategoryPair(title, category) + return true + } else { + return false + } + } + + private fun updateDateAndTime() { + tvDate.text = formatController.formatDateToNumber(timestamp) + tvTime.text = formatController.formatTime(timestamp) + } + + enum class Mode { MODE_ADD, MODE_EDIT } + + private class SemicolonInputFilter : InputFilter { + + override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence? { + return if (source != null && ";" == source.toString()) "" + else null + } + } + + companion object { + const val KEY_RECORD = "key_record" + const val KEY_MODE = "key_mode" + const val KEY_TYPE = "key_type" + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/CategoryAutoCompleteAdapter.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/CategoryAutoCompleteAdapter.java index a7d0673..8f47160 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/CategoryAutoCompleteAdapter.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/CategoryAutoCompleteAdapter.java @@ -12,6 +12,8 @@ import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.util.CategoryAutoCompleter; +import org.jetbrains.annotations.NotNull; + import java.util.ArrayList; import java.util.List; @@ -26,7 +28,6 @@ */ public class CategoryAutoCompleteAdapter extends ArrayAdapter implements Filterable { private final CategoryAutoCompleter autoCompleter; - private List resultList; public CategoryAutoCompleteAdapter(Context context, int resource, CategoryAutoCompleter autoCompleter) { super(context, resource); @@ -34,7 +35,7 @@ public CategoryAutoCompleteAdapter(Context context, int resource, CategoryAutoCo } @Override - public View getView(int position, View convertView, ViewGroup parent) { + public View getView(int position, View convertView, @NotNull ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { @@ -43,14 +44,14 @@ public View getView(int position, View convertView, ViewGroup parent) { convertView.setTag(viewHolder); } else viewHolder = (ViewHolder) convertView.getTag(); - final String category = resultList.get(position); + final String category = getItem(position); viewHolder.tvCategory.setText(category); viewHolder.ivCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { autoCompleter.removeFromAutoComplete(category); - resultList.remove(category); + remove(category); notifyDataSetChanged(); } }); @@ -58,16 +59,7 @@ public void onClick(View v) { return convertView; } - @Override - public int getCount() { - return resultList.size(); - } - - @Override - public String getItem(int index) { - return resultList.get(index); - } - + @NotNull @Override public Filter getFilter() { return new Filter() { @@ -77,7 +69,8 @@ protected FilterResults performFiltering(CharSequence constraint) { List tempList; - if (constraint != null) tempList = autoCompleter.completeByPart(constraint.toString()); + if (constraint != null) + tempList = autoCompleter.completeByPart(constraint.toString()); else tempList = new ArrayList<>(); filterResults.values = tempList; @@ -88,11 +81,14 @@ protected FilterResults performFiltering(CharSequence constraint) { @Override protected void publishResults(CharSequence constraint, FilterResults results) { - if (results != null) //noinspection unchecked - resultList = (List) results.values; - - if (results != null && results.count > 0) notifyDataSetChanged(); - else notifyDataSetInvalidated(); + clear(); + + if (results != null && results.count > 0) { + addAll((List) results.values); + notifyDataSetChanged(); + } else { + notifyDataSetInvalidated(); + } } }; } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/AccountValidator.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/AccountValidator.java index 0d095ed..e05d6d1 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/AccountValidator.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/AccountValidator.java @@ -27,7 +27,7 @@ public class AccountValidator implements IValidator { @BindView(R.id.til_title) TextInputLayout tilTitle; - @BindView(R.id.et_title) + @BindView(R.id.etTitle) EditText etTitle; @BindView(R.id.til_init_sum) TextInputLayout tilInitSum; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/RecordValidator.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/RecordValidator.java index 3a842a9..8d9fd94 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/RecordValidator.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/RecordValidator.java @@ -28,17 +28,17 @@ public class RecordValidator implements IValidator { @BindView(R.id.til_title) TextInputLayout tilTitle; - @BindView(R.id.et_title) + @BindView(R.id.etTitle) EditText etTitle; @BindView(R.id.til_category) TextInputLayout tilCategory; - @BindView(R.id.et_category) + @BindView(R.id.etCategory) EditText etCategory; @BindView(R.id.til_price) TextInputLayout tilPrice; - @BindView(R.id.et_price) + @BindView(R.id.etPrice) EditText etPrice; - @BindView(R.id.spinner_account) + @BindView(R.id.spinnerAccount) AppCompatSpinner spinnerAccount; public RecordValidator(@NonNull Context context, @NonNull View view) { diff --git a/app/src/main/res/layout/activity_add_exchange_rate.xml b/app/src/main/res/layout/activity_add_exchange_rate.xml index 9a62337..5011497 100644 --- a/app/src/main/res/layout/activity_add_exchange_rate.xml +++ b/app/src/main/res/layout/activity_add_exchange_rate.xml @@ -21,7 +21,7 @@ diff --git a/app/src/main/res/layout/content_add_account.xml b/app/src/main/res/layout/content_add_account.xml index d29168f..52c5e30 100644 --- a/app/src/main/res/layout/content_add_account.xml +++ b/app/src/main/res/layout/content_add_account.xml @@ -2,7 +2,7 @@ @@ -87,7 +87,7 @@ android:layout_height="wrap_content"> На счет Курсы обмена Добавить курс обмена - Счет был удален + Счет удален Краткий отчет Другой diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index d828602..3f6d25b 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -44,7 +44,7 @@ На рахунок Курси обміну Додати курс обміну - Рахунок було видалено + Рахунок видалено Короткий звіт Інший diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index a8fc9f1..8215513 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -40,7 +40,7 @@ 转换汇率 添加汇率 - 账户已清空 + 账户已清空 简要汇总 个性化 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8e44a5b..85fe9a4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,7 +44,7 @@ Exchange rates Add exchange rate " -> " - Account was removed + Account removed Short summary Custom