Skip to content
This repository was archived by the owner on Jun 27, 2020. It is now read-only.

Commit 84e3b7f

Browse files
author
Evgenii Kanivets
authored
Merge pull request #156 from evgenii-kanivets/feature-95_account_operations
Feature 95 account operations
2 parents 857ff38 + b622cbd commit 84e3b7f

File tree

21 files changed

+497
-266
lines changed

21 files changed

+497
-266
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ jdk: oraclejdk8
33
android:
44
components:
55
# The BuildTools version used by your project
6-
- build-tools-26.0.2
6+
- build-tools-27.0.3
77

88
# The SDK version used to compile your project
99
- android-21
10-
- android-26
10+
- android-27
1111

1212
# Additional components
1313
- extra-google-google_play_services
1414
- extra-google-m2repository
1515
- extra-android-m2repository
16-
- addon-google_apis-google-26
16+
- addon-google_apis-google-27
1717

1818
# Specify at least one system image,
1919
# if you need to run emulator(s) during your tests

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
android:screenOrientation="portrait"
8888
android:theme="@style/Theme.Default" />
8989
<activity
90-
android:name=".activity.account.EditAccountActivity"
90+
android:name=".activity.account.edit.EditAccountActivity"
9191
android:label="@string/title_activity_edit_account"
9292
android:screenOrientation="portrait"
9393
android:theme="@style/Theme.Default"

app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AccountsActivity.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.widget.ListView;
88

99
import com.blogspot.e_kanivets.moneytracker.R;
10+
import com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity;
1011
import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity;
1112
import com.blogspot.e_kanivets.moneytracker.adapter.AccountAdapter;
1213
import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController;
Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
package com.blogspot.e_kanivets.moneytracker.activity.account
1+
package com.blogspot.e_kanivets.moneytracker.activity.account.edit
22

33
import android.app.Activity
44
import android.app.AlertDialog
55
import android.content.Context
66
import android.content.Intent
7+
import android.support.v4.view.ViewPager.OnPageChangeListener
78
import android.view.Menu
89
import android.view.MenuItem
9-
1010
import com.blogspot.e_kanivets.moneytracker.R
11+
import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountOperationsFragment
12+
import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment
1113
import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity
14+
import com.blogspot.e_kanivets.moneytracker.adapter.GeneralViewPagerAdapter
1215
import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController
1316
import com.blogspot.e_kanivets.moneytracker.entity.data.Account
14-
import kotlinx.android.synthetic.main.activity_edit_account.*
15-
17+
import kotlinx.android.synthetic.main.activity_edit_account.fabDone
18+
import kotlinx.android.synthetic.main.activity_edit_account.tabLayout
19+
import kotlinx.android.synthetic.main.activity_edit_account.viewPager
1620
import javax.inject.Inject
1721

1822
class EditAccountActivity : BaseBackActivity() {
@@ -22,9 +26,7 @@ class EditAccountActivity : BaseBackActivity() {
2226

2327
private lateinit var account: Account
2428

25-
override fun getContentViewId(): Int {
26-
return R.layout.activity_edit_account
27-
}
29+
override fun getContentViewId(): Int = R.layout.activity_edit_account
2830

2931
override fun initData(): Boolean {
3032
appComponent.inject(this@EditAccountActivity)
@@ -40,19 +42,27 @@ class EditAccountActivity : BaseBackActivity() {
4042
override fun initViews() {
4143
super.initViews()
4244

43-
etTitle.setText(account.title)
44-
etGoal.setText(account.goal.toString())
45-
viewColor.setBackgroundColor(account.color)
45+
tabLayout.setupWithViewPager(viewPager)
46+
47+
val adapter = GeneralViewPagerAdapter(supportFragmentManager)
48+
adapter.addFragment(EditAccountFragment.newInstance(account), getString(R.string.information))
49+
adapter.addFragment(AccountOperationsFragment.newInstance(account), getString(R.string.operations))
50+
viewPager.adapter = adapter
51+
52+
viewPager.addOnPageChangeListener(object : OnPageChangeListener {
53+
override fun onPageScrollStateChanged(state: Int) {}
54+
55+
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
56+
57+
override fun onPageSelected(position: Int) {
58+
if (position == 0) fabDone.show() else fabDone.hide()
59+
}
4660

47-
fabDone.setOnClickListener { done() }
61+
})
4862
}
4963

5064
override fun onCreateOptionsMenu(menu: Menu): Boolean {
51-
if (account.isArchived) {
52-
menuInflater.inflate(R.menu.menu_archived_account, menu)
53-
} else {
54-
menuInflater.inflate(R.menu.menu_account, menu)
55-
}
65+
menuInflater.inflate(if (account.isArchived) R.menu.menu_archived_account else R.menu.menu_account, menu)
5666
return true
5767
}
5868

@@ -65,24 +75,6 @@ class EditAccountActivity : BaseBackActivity() {
6575
}
6676
}
6777

68-
private fun done() {
69-
val title = etTitle.text.toString().trim { it <= ' ' }
70-
71-
if (title.isEmpty()) {
72-
tilTitle.error = getString(R.string.field_cant_be_empty)
73-
} else {
74-
val newAccount = Account(
75-
account.id, title, account.curSum.toDouble(),
76-
account.currency, account.goal, account.isArchived, account.color
77-
)
78-
val updated = accountController.update(newAccount) != null
79-
if (updated) {
80-
setResult(Activity.RESULT_OK)
81-
finish()
82-
}
83-
}
84-
}
85-
8678
private fun archive(): Boolean {
8779
if (account == accountController.readDefaultAccount()) {
8880
showToast(R.string.cant_archive_default_account)
@@ -120,7 +112,7 @@ class EditAccountActivity : BaseBackActivity() {
120112

121113
companion object {
122114

123-
const val KEY_ACCOUNT = "key_account"
115+
private const val KEY_ACCOUNT = "key_account"
124116

125117
fun newIntent(context: Context, account: Account): Intent {
126118
val intent = Intent(context, EditAccountActivity::class.java)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment
2+
3+
import android.os.Bundle
4+
import android.view.View
5+
import com.blogspot.e_kanivets.moneytracker.R
6+
import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment
7+
import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter
8+
import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController
9+
import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController
10+
import com.blogspot.e_kanivets.moneytracker.controller.data.TransferController
11+
import com.blogspot.e_kanivets.moneytracker.entity.data.Account
12+
import com.blogspot.e_kanivets.moneytracker.entity.data.Category
13+
import com.blogspot.e_kanivets.moneytracker.entity.data.Record
14+
import com.blogspot.e_kanivets.moneytracker.entity.data.Transfer
15+
import kotlinx.android.synthetic.main.fragment_account_operations.*
16+
import javax.inject.Inject
17+
18+
class AccountOperationsFragment : BaseFragment() {
19+
20+
@Inject
21+
internal lateinit var accountController: AccountController
22+
@Inject
23+
internal lateinit var recordController: RecordController
24+
@Inject
25+
internal lateinit var transferController: TransferController
26+
27+
private lateinit var account: Account
28+
29+
override val contentViewId: Int = R.layout.fragment_account_operations
30+
31+
override fun initData() {
32+
appComponent.inject(this@AccountOperationsFragment)
33+
arguments?.let { arguments -> account = arguments.getParcelable(AccountOperationsFragment.KEY_ACCOUNT) }
34+
}
35+
36+
override fun initViews(view: View) {
37+
listView.adapter = RecordAdapter(activity, getRecords())
38+
}
39+
40+
private fun getRecords(): List<Record> {
41+
val accountRecords = recordController.getRecordsForAccount(account)
42+
val accountTransfers = transferController.getTransfersForAccount(account)
43+
44+
accountRecords += obtainRecordsFromTransfers(accountTransfers)
45+
accountRecords.sortByDescending { it.time }
46+
47+
return accountRecords
48+
}
49+
50+
private fun obtainRecordsFromTransfers(transfers: List<Transfer>): List<Record> {
51+
val records = mutableListOf<Record>()
52+
53+
transfers.forEach {
54+
val type = if (it.fromAccountId == account.id) Record.TYPE_EXPENSE else Record.TYPE_INCOME
55+
val title = constructRecordTitle(type, it)
56+
val category = Category(getString(R.string.transfer).toLowerCase())
57+
val price = if (type == Record.TYPE_EXPENSE) it.fromAmount else it.toAmount
58+
val decimals = if (type == Record.TYPE_EXPENSE) it.fromDecimals else it.toDecimals
59+
60+
records += Record(it.id, it.time, type, title, category, price, account, account.currency, decimals)
61+
}
62+
63+
return records.toList()
64+
}
65+
66+
private fun constructRecordTitle(type: Int, transfer: Transfer): String {
67+
val titlePrefix = getString(if (type == Record.TYPE_EXPENSE) R.string.to else R.string.from)
68+
val oppositeAccountId = if (type == Record.TYPE_EXPENSE) transfer.toAccountId else transfer.fromAccountId
69+
val oppositeAccountTitle = "$titlePrefix ${accountController.read(oppositeAccountId)?.title}"
70+
return "${getString(R.string.transfer)} $oppositeAccountTitle".toLowerCase()
71+
}
72+
73+
companion object {
74+
75+
private const val KEY_ACCOUNT = "key_account"
76+
77+
fun newInstance(account: Account): AccountOperationsFragment {
78+
val fragment = AccountOperationsFragment()
79+
val arguments = Bundle()
80+
arguments.putParcelable(KEY_ACCOUNT, account)
81+
fragment.arguments = arguments
82+
return fragment
83+
}
84+
85+
}
86+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment
2+
3+
import android.app.Activity
4+
import android.os.Bundle
5+
import android.support.design.widget.FloatingActionButton
6+
import android.view.View
7+
import com.blogspot.e_kanivets.moneytracker.R
8+
import com.blogspot.e_kanivets.moneytracker.R.layout
9+
import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment
10+
import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController
11+
import com.blogspot.e_kanivets.moneytracker.entity.data.Account
12+
import kotlinx.android.synthetic.main.fragment_edit_account.*
13+
import javax.inject.Inject
14+
15+
class EditAccountFragment : BaseFragment() {
16+
17+
@Inject
18+
internal lateinit var accountController: AccountController
19+
20+
private lateinit var account: Account
21+
22+
override val contentViewId: Int = layout.fragment_edit_account
23+
24+
override fun initData() {
25+
appComponent.inject(this@EditAccountFragment)
26+
arguments?.let { arguments -> account = arguments.getParcelable(KEY_ACCOUNT) }
27+
}
28+
29+
override fun initViews(view: View) {
30+
etTitle.setText(account.title)
31+
etGoal.setText(account.goal.toString())
32+
viewColor.setBackgroundColor(account.color)
33+
34+
val fabDone = view.rootView.findViewById<FloatingActionButton>(R.id.fabDone)
35+
fabDone.setOnClickListener { done() }
36+
}
37+
38+
private fun done() {
39+
val title = etTitle.text.toString().trim { it <= ' ' }
40+
41+
if (title.isEmpty()) {
42+
tilTitle.error = getString(R.string.field_cant_be_empty)
43+
} else {
44+
val newAccount = Account(
45+
account.id, title, account.curSum.toDouble(),
46+
account.currency, account.goal, account.isArchived, account.color
47+
)
48+
val updated = accountController.update(newAccount) != null
49+
if (updated) {
50+
activity?.setResult(Activity.RESULT_OK)
51+
activity?.finish()
52+
}
53+
}
54+
}
55+
56+
companion object {
57+
58+
private const val KEY_ACCOUNT = "key_account"
59+
60+
fun newInstance(account: Account): EditAccountFragment {
61+
val fragment = EditAccountFragment()
62+
val arguments = Bundle()
63+
arguments.putParcelable(KEY_ACCOUNT, account)
64+
fragment.arguments = arguments
65+
return fragment
66+
}
67+
68+
}
69+
70+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.blogspot.e_kanivets.moneytracker.activity.base
2+
3+
import android.os.Bundle
4+
import android.support.v4.app.Fragment
5+
import android.view.LayoutInflater
6+
import android.view.View
7+
import android.view.ViewGroup
8+
import com.blogspot.e_kanivets.moneytracker.MtApp
9+
import com.blogspot.e_kanivets.moneytracker.di.AppComponent
10+
11+
abstract class BaseFragment : Fragment() {
12+
13+
protected val appComponent: AppComponent = MtApp.get().appComponent
14+
15+
protected abstract val contentViewId: Int
16+
17+
protected abstract fun initData()
18+
19+
protected abstract fun initViews(view: View)
20+
21+
override fun onCreate(savedInstanceState: Bundle?) {
22+
super.onCreate(savedInstanceState)
23+
initData()
24+
}
25+
26+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
27+
inflater.inflate(contentViewId, container, false)
28+
29+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
30+
super.onViewCreated(view, savedInstanceState)
31+
initViews(view)
32+
}
33+
}

0 commit comments

Comments
 (0)