Implemented retrieving and displaying account transactions
This commit is contained in:
parent
a6a24311d7
commit
a6fd9a4d42
|
@ -35,10 +35,17 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(":fints4k")
|
||||
|
||||
implementation "net.dankito.utils:android-utils:1.1.2"
|
||||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0-rc02'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.0.0-rc02'
|
||||
|
||||
implementation "org.slf4j:slf4j-android:1.7.32"
|
||||
}
|
|
@ -2,6 +2,9 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.codinux.banking.fints4k.android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package net.codinux.banking.fints4k.android
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ContextThemeWrapper
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import net.codinux.banking.fints4k.android.adapter.AccountTransactionsListRecyclerAdapter
|
||||
import net.codinux.banking.fints4k.android.databinding.FragmentFirstBinding
|
||||
|
||||
/**
|
||||
|
@ -15,6 +18,8 @@ class FirstFragment : Fragment() {
|
|||
|
||||
private var _binding: FragmentFirstBinding? = null
|
||||
|
||||
private val accountTransactionsAdapter = AccountTransactionsListRecyclerAdapter()
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
@ -32,8 +37,17 @@ class FirstFragment : Fragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.buttonFirst.setOnClickListener {
|
||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
||||
binding.rcyvwAccountTransactions.apply {
|
||||
layoutManager = LinearLayoutManager(this@FirstFragment.context, LinearLayoutManager.VERTICAL, false)
|
||||
addItemDecoration(DividerItemDecoration(ContextThemeWrapper(this@FirstFragment.context, R.style.Theme_Fints4kProject), (layoutManager as LinearLayoutManager).orientation))
|
||||
adapter = accountTransactionsAdapter
|
||||
}
|
||||
|
||||
// TODO: set your credentials here
|
||||
Presenter().retrieveAccountData("", "", "", "") { response ->
|
||||
if (response.successful) {
|
||||
accountTransactionsAdapter.items = response.retrievedData.flatMap { it.bookedTransactions }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package net.codinux.banking.fints4k.android
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.datetime.LocalDate
|
||||
import net.dankito.banking.fints.FinTsClientDeprecated
|
||||
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
|
||||
import net.dankito.banking.fints.model.AddAccountParameter
|
||||
import net.dankito.banking.fints.response.client.AddAccountResponse
|
||||
import net.dankito.utils.multiplatform.extensions.millisSinceEpochAtSystemDefaultTimeZone
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.math.BigDecimal
|
||||
import java.text.DateFormat
|
||||
import java.util.*
|
||||
|
||||
class Presenter {
|
||||
|
||||
companion object {
|
||||
val ValueDateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
|
||||
|
||||
private val log = LoggerFactory.getLogger(Presenter::class.java)
|
||||
}
|
||||
|
||||
private val fintsClient = FinTsClientDeprecated(SimpleFinTsClientCallback())
|
||||
|
||||
|
||||
|
||||
fun retrieveAccountData(bankCode: String, customerId: String, pin: String, finTs3ServerAddress: String, retrievedResult: (AddAccountResponse) -> Unit) {
|
||||
fintsClient.addAccountAsync(AddAccountParameter(bankCode, customerId, pin, finTs3ServerAddress)) { response ->
|
||||
log.info("Retrieved response from ${response.bank.bankName} for ${response.bank.customerName}")
|
||||
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
retrievedResult(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun formatDate(date: LocalDate): String {
|
||||
try {
|
||||
return ValueDateFormat.format(Date(date.millisSinceEpochAtSystemDefaultTimeZone))
|
||||
} catch (e: Exception) {
|
||||
log.error("Could not format date $date", e)
|
||||
}
|
||||
|
||||
return date.toString()
|
||||
}
|
||||
|
||||
fun formatAmount(amount: BigDecimal): String {
|
||||
return String.format("%.02f", amount)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package net.codinux.banking.fints4k.android.adapter
|
||||
|
||||
import android.view.View
|
||||
import net.codinux.banking.fints4k.android.Presenter
|
||||
import net.codinux.banking.fints4k.android.R
|
||||
import net.codinux.banking.fints4k.android.adapter.viewholder.AccountTransactionsViewHolder
|
||||
import net.dankito.banking.fints.model.AccountTransaction
|
||||
import net.dankito.banking.fints.util.toBigDecimal
|
||||
import net.dankito.utils.android.extensions.setTextColorToColorResource
|
||||
import net.dankito.utils.android.ui.adapter.ListRecyclerAdapter
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.math.BigDecimal
|
||||
|
||||
class AccountTransactionsListRecyclerAdapter : ListRecyclerAdapter<AccountTransaction, AccountTransactionsViewHolder>() {
|
||||
|
||||
private val presenter = Presenter() // TOOD: inject
|
||||
|
||||
private val log = LoggerFactory.getLogger(AccountTransactionsListRecyclerAdapter::class.java)
|
||||
|
||||
|
||||
override fun getListItemLayoutId() = R.layout.list_item_account_transaction
|
||||
|
||||
override fun createViewHolder(itemView: View): AccountTransactionsViewHolder {
|
||||
return AccountTransactionsViewHolder(itemView)
|
||||
}
|
||||
|
||||
override fun bindItemToView(viewHolder: AccountTransactionsViewHolder, item: AccountTransaction) {
|
||||
try {
|
||||
viewHolder.txtvwBookingText.text = item.bookingText ?: ""
|
||||
|
||||
viewHolder.txtvwOtherPartyName.visibility = if (item.showOtherPartyName) View.VISIBLE else View.GONE
|
||||
viewHolder.txtvwOtherPartyName.text = item.otherPartyName ?: ""
|
||||
|
||||
viewHolder.txtvwReference.text = item.reference
|
||||
|
||||
viewHolder.txtvwDate.text = presenter.formatDate(item.valueDate)
|
||||
|
||||
val amount = item.amount.toBigDecimal()
|
||||
viewHolder.txtvwAmount.text = presenter.formatAmount(amount)
|
||||
viewHolder.txtvwAmount.setTextColorToColorResource(if (amount >= BigDecimal.ZERO) R.color.positiveAmount else R.color.negativeAmount)
|
||||
} catch (e: Exception) {
|
||||
log.error("Could not display account transaction $item", e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.codinux.banking.fints4k.android.adapter.viewholder
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import net.codinux.banking.fints4k.android.R
|
||||
|
||||
class AccountTransactionsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val txtvwBookingText: TextView = itemView.findViewById(R.id.txtvwBookingText)
|
||||
|
||||
val txtvwOtherPartyName: TextView = itemView.findViewById(R.id.txtvwOtherPartyName)
|
||||
|
||||
val txtvwReference: TextView = itemView.findViewById(R.id.txtvwReference)
|
||||
|
||||
val txtvwAmount: TextView = itemView.findViewById(R.id.txtvwAmount)
|
||||
|
||||
val txtvwDate: TextView = itemView.findViewById(R.id.txtvwDate)
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/activity_content_padding"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<fragment
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
@ -7,25 +7,13 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context=".FirstFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview_first"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello_first_fragment"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/button_first"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_first"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/next"
|
||||
app:layout_constraintTop_toBottomOf="@id/textview_first"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.recyclerview.widget.RecyclerView android:id="@+id/rcyvwAccountTransactions"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
>
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,89 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/list_item_account_transaction_height"
|
||||
android:padding="@dimen/list_item_account_transaction_padding"
|
||||
>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toLeftOf="@+id/lytAmountAndDate"
|
||||
android:layout_toStartOf="@+id/lytAmountAndDate"
|
||||
android:layout_marginLeft="@dimen/list_item_account_transaction_transaction_text_margin_left_and_right"
|
||||
android:layout_marginStart="@dimen/list_item_account_transaction_transaction_text_margin_left_and_right"
|
||||
android:layout_marginRight="@dimen/list_item_account_transaction_transaction_text_margin_left_and_right"
|
||||
android:layout_marginEnd="@dimen/list_item_account_transaction_transaction_text_margin_left_and_right"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvwBookingText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvwOtherPartyName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/list_item_account_transaction_other_party_name_margin_top_and_bottom"
|
||||
android:layout_marginBottom="@dimen/list_item_account_transaction_other_party_name_margin_top_and_bottom"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvwReference"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lytAmountAndDate"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="@dimen/list_item_account_transaction_amount_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvwBankIcon"
|
||||
android:layout_width="@dimen/list_item_account_transaction_bank_icon_width_and_height"
|
||||
android:layout_height="@dimen/list_item_account_transaction_bank_icon_width_and_height"
|
||||
android:layout_marginTop="@dimen/list_item_account_transaction_bank_icon_margin_top"
|
||||
android:layout_marginBottom="@dimen/list_item_account_transaction_bank_icon_margin_bottom"
|
||||
android:layout_gravity="end"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvwAmount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvwDate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/list_item_account_transaction_date_margin_top"
|
||||
android:layout_marginBottom="@dimen/list_item_account_transaction_date_margin_bottom"
|
||||
android:gravity="end"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -7,4 +7,9 @@
|
|||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
|
||||
|
||||
<color name="positiveAmount">#43A047</color>
|
||||
<color name="negativeAmount">#E53935</color>
|
||||
|
||||
</resources>
|
|
@ -1,3 +1,18 @@
|
|||
<resources>
|
||||
<dimen name="activity_content_padding">4dp</dimen>
|
||||
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
||||
|
||||
<dimen name="list_item_account_transaction_height">100dp</dimen>
|
||||
<dimen name="list_item_account_transaction_padding">4dp</dimen>
|
||||
<dimen name="list_item_account_transaction_bank_icon_width_and_height">16dp</dimen>
|
||||
<dimen name="list_item_account_transaction_bank_icon_margin_top">8dp</dimen>
|
||||
<dimen name="list_item_account_transaction_bank_icon_margin_bottom">12dp</dimen>
|
||||
<dimen name="list_item_account_transaction_amount_width">70dp</dimen>
|
||||
<dimen name="list_item_account_transaction_date_margin_top">12dp</dimen>
|
||||
<dimen name="list_item_account_transaction_date_margin_bottom">8dp</dimen>
|
||||
<dimen name="list_item_account_transaction_transaction_text_margin_left_and_right">4dp</dimen>
|
||||
<dimen name="list_item_account_transaction_other_party_name_margin_top_and_bottom">6dp</dimen>
|
||||
|
||||
</resources>
|
|
@ -75,8 +75,6 @@ kotlin {
|
|||
dependencies {
|
||||
api project(":multiplatform-utils")
|
||||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.3.2"
|
||||
|
||||
implementation "co.touchlab:stately-concurrency:1.2.0"
|
||||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion"
|
||||
|
|
|
@ -54,6 +54,9 @@ open class AccountTransaction(
|
|||
null, "", "", null, null, "", null)
|
||||
|
||||
|
||||
open val showOtherPartyName: Boolean
|
||||
get() = otherPartyName.isNullOrBlank() == false /* && type != "ENTGELTABSCHLUSS" && type != "AUSZAHLUNG" */ // TODO
|
||||
|
||||
val reference: String
|
||||
get() = sepaReference ?: unparsedReference
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package net.dankito.banking.fints.util
|
||||
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import net.dankito.banking.fints.model.Money
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
||||
fun Amount.toBigDecimal(): BigDecimal {
|
||||
return BigDecimal(this.string.replace(',', '.'))
|
||||
}
|
||||
|
||||
fun Money.toBigDecimal(): BigDecimal {
|
||||
return this.amount.toBigDecimal()
|
||||
}
|
|
@ -65,7 +65,7 @@ kotlin {
|
|||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.3.2"
|
||||
api "org.jetbrains.kotlinx:kotlinx-datetime:0.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue