Implemented creating money transfer with same data as original account transaction (not only remittee name and IBAN)

This commit is contained in:
dankito 2020-09-04 13:58:26 +02:00
parent c9ed160043
commit a3bb940d46
18 changed files with 96 additions and 36 deletions

View File

@ -18,6 +18,9 @@ expect class BigDecimal {
val isPositive: Boolean val isPositive: Boolean
fun negated(): BigDecimal
fun format(countDecimalPlaces: Int): String fun format(countDecimalPlaces: Int): String
} }

View File

@ -26,6 +26,13 @@ actual class BigDecimal(val decimal: NSDecimalNumber) : Comparable<BigDecimal> {
actual val isPositive: Boolean actual val isPositive: Boolean
get() = this >= Zero get() = this >= Zero
actual fun negated(): BigDecimal {
val negated = decimal.decimalNumberByMultiplyingBy(NSDecimalNumber(1.toULong(), 0, true))
return BigDecimal(negated)
}
actual fun format(countDecimalPlaces: Int): String { actual fun format(countDecimalPlaces: Int): String {
val formatter = NSNumberFormatter() val formatter = NSNumberFormatter()

View File

@ -29,6 +29,11 @@ actual class BigDecimal actual constructor(decimal: String) : java.math.BigDecim
actual val isPositive: Boolean actual val isPositive: Boolean
get() = this >= ZERO get() = this >= ZERO
actual fun negated(): BigDecimal {
return BigDecimal(super.negate().toString())
}
actual fun format(countDecimalPlaces: Int): String { actual fun format(countDecimalPlaces: Int): String {
return String.format("%.0${countDecimalPlaces}f", this) return String.format("%.0${countDecimalPlaces}f", this)
} }

View File

@ -69,8 +69,12 @@ open class AccountTransactionAdapter(protected val presenter: BankingPresenter)
selectedTransaction = getItem(viewHolder.adapterPosition) selectedTransaction = getItem(viewHolder.adapterPosition)
menu.findItem(R.id.mnitmShowTransferMoneyDialog)?.let { mnitmShowTransferMoneyDialog -> val canCreateMoneyTransferFrom = selectedTransaction?.canCreateMoneyTransferFrom ?: false
mnitmShowTransferMoneyDialog.isVisible = selectedTransaction?.bankAccount?.supportsTransferringMoney ?: false
menu.findItem(R.id.mnitmNewTransferWithSameData)?.isVisible = canCreateMoneyTransferFrom
menu.findItem(R.id.mnitmNewTransferToSameRemittee)?.let { mnitmShowTransferMoneyDialog ->
mnitmShowTransferMoneyDialog.isVisible = canCreateMoneyTransferFrom
val remitteeName = selectedTransaction?.otherPartyName ?: "" val remitteeName = selectedTransaction?.otherPartyName ?: ""

View File

@ -224,21 +224,22 @@ open class TransferMoneyDialog : DialogFragment() {
remitteeBic = data.creditorBic remitteeBic = data.creditorBic
if (data.amount > BigDecimal.ZERO) { if (data.amount > BigDecimal.ZERO) {
edtxtAmount.setText(AmountFormat.format(data.amount)) edtxtAmount.setText(data.amount.toString())
} }
edtxtUsage.setText(data.usage)
focusEditTextAccordingToPreselectedValues() focusEditTextAccordingToPreselectedValues()
} }
} }
protected open fun focusEditTextAccordingToPreselectedValues() { protected open fun focusEditTextAccordingToPreselectedValues() {
if (edtxtRemitteeName.text.toString().trim().isNotEmpty()) { when {
if (edtxtRemitteeIban.text.toString().trim().isNotEmpty()) { edtxtRemitteeName.text.toString().isBlank() -> edtxtRemitteeName.requestFocus()
edtxtAmount.requestFocus() edtxtRemitteeIban.text.toString().isBlank() -> edtxtRemitteeIban.requestFocus()
} edtxtAmount.text.toString().isBlank() -> edtxtAmount.requestFocus()
else { edtxtUsage.text.toString().isBlank() -> edtxtUsage.requestFocus()
edtxtRemitteeIban.requestFocus() else -> edtxtUsage.requestFocus()
}
} }
} }

View File

@ -15,7 +15,6 @@ import androidx.recyclerview.widget.RecyclerView
import net.dankito.banking.ui.android.R import net.dankito.banking.ui.android.R
import net.dankito.banking.ui.android.di.BankingComponent import net.dankito.banking.ui.android.di.BankingComponent
import net.dankito.banking.ui.android.adapter.AccountTransactionAdapter import net.dankito.banking.ui.android.adapter.AccountTransactionAdapter
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.parameters.TransferMoneyData import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.responses.GetTransactionsResponse import net.dankito.banking.ui.model.responses.GetTransactionsResponse
import net.dankito.banking.ui.presenter.BankingPresenter import net.dankito.banking.ui.presenter.BankingPresenter
@ -119,8 +118,12 @@ class HomeFragment : Fragment() {
override fun onContextItemSelected(item: MenuItem): Boolean { override fun onContextItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.mnitmShowTransferMoneyDialog -> { R.id.mnitmNewTransferToSameRemittee -> {
showTransferMoneyDialog() newTransferToSameRemittee()
return true
}
R.id.mnitmNewTransferWithSameData -> {
newTransferWithSameData()
return true return true
} }
} }
@ -172,18 +175,16 @@ class HomeFragment : Fragment() {
} }
private fun showTransferMoneyDialog() { private fun newTransferToSameRemittee() {
transactionAdapter.selectedTransaction?.let { selectedTransaction -> transactionAdapter.selectedTransaction?.let { selectedTransaction ->
presenter.showTransferMoneyDialog(mapPreselectedValues(selectedTransaction)) presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransactionWithoutAmountAndUsage(selectedTransaction))
} }
} }
private fun mapPreselectedValues(selectedTransaction: AccountTransaction?): TransferMoneyData? { private fun newTransferWithSameData() {
selectedTransaction?.let { transactionAdapter.selectedTransaction?.let { selectedTransaction ->
return TransferMoneyData.fromAccountTransaction(selectedTransaction) presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransaction(selectedTransaction))
} }
return null
} }

View File

@ -2,8 +2,13 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/mnitmShowTransferMoneyDialog" android:id="@+id/mnitmNewTransferToSameRemittee"
android:title="@string/fragment_home_transfer_money_to" android:title="@string/fragment_home_transfer_money_to"
/> />
<item
android:id="@+id/mnitmNewTransferWithSameData"
android:title="@string/fragment_home_transfer_money_with_same_data"
/>
</menu> </menu>

View File

@ -31,6 +31,7 @@
<string name="fragment_home_could_not_retrieve_account_transactions">Kontoumsätze für \'%1$s\' konnten nicht empfangen werden.\n\nFehlermeldung Ihrer Bank:\n\n%2$s</string> <string name="fragment_home_could_not_retrieve_account_transactions">Kontoumsätze für \'%1$s\' konnten nicht empfangen werden.\n\nFehlermeldung Ihrer Bank:\n\n%2$s</string>
<string name="fragment_home_transfer_money_to">Neue Überweisung an %s</string> <string name="fragment_home_transfer_money_to">Neue Überweisung an %s</string>
<string name="fragment_home_transfer_money_with_same_data">Neue Überweisung mit gleichen Daten</string>
<string name="dialog_add_account_enter_bank">Bank (Suche auch mittels Bankleitzahl oder Ort):</string> <string name="dialog_add_account_enter_bank">Bank (Suche auch mittels Bankleitzahl oder Ort):</string>
<string name="dialog_add_account_customer_id_and_password_hint">Geben Sie hier die selben Werte ein wie auf Ihrer Online Banking Webseite:</string> <string name="dialog_add_account_customer_id_and_password_hint">Geben Sie hier die selben Werte ein wie auf Ihrer Online Banking Webseite:</string>

View File

@ -31,6 +31,7 @@
<string name="fragment_home_could_not_retrieve_account_transactions">Could not retrieve account transactions for \'%1$s\'.\n\nError message from your bank:\n\n%2$s</string> <string name="fragment_home_could_not_retrieve_account_transactions">Could not retrieve account transactions for \'%1$s\'.\n\nError message from your bank:\n\n%2$s</string>
<string name="fragment_home_transfer_money_to">Transfer money to %s</string> <string name="fragment_home_transfer_money_to">Transfer money to %s</string>
<string name="fragment_home_transfer_money_with_same_data">New transfer with same data</string>
<string name="dialog_add_account_enter_bank">Bank (find also by bank code or city):</string> <string name="dialog_add_account_enter_bank">Bank (find also by bank code or city):</string>
<string name="dialog_add_account_customer_id_and_password_hint">Enter the same values here as in your online banking portal</string> <string name="dialog_add_account_customer_id_and_password_hint">Enter the same values here as in your online banking portal</string>

View File

@ -30,7 +30,8 @@ account.transactions.control.view.could.not.retrieve.account.transactions=Could
account.transactions.table.column.header.value.date=Value date account.transactions.table.column.header.value.date=Value date
account.transactions.table.column.header.usage=Usage account.transactions.table.column.header.usage=Usage
account.transactions.table.column.header.amount=Amount account.transactions.table.column.header.amount=Amount
account.transactions.table.context.menu.transfer.money.to=Transfer money to %s account.transactions.table.context.menu.new.transfer.to.same.remittee=Transfer money to %s
account.transactions.table.context.menu.new.transfer.with.same.data=New transfer with same data
account.transactions.table.context.menu.show.transaction.details=Show details account.transactions.table.context.menu.show.transaction.details=Show details

View File

@ -30,7 +30,8 @@ account.transactions.control.view.could.not.retrieve.account.transactions=Kontou
account.transactions.table.column.header.value.date=Buchungstag account.transactions.table.column.header.value.date=Buchungstag
account.transactions.table.column.header.usage=Verwendungszweck account.transactions.table.column.header.usage=Verwendungszweck
account.transactions.table.column.header.amount=Betrag account.transactions.table.column.header.amount=Betrag
account.transactions.table.context.menu.transfer.money.to=Neue Überweisung an %s account.transactions.table.context.menu.new.transfer.to.same.remittee=Neue Überweisung an %s
account.transactions.table.context.menu.new.transfer.with.same.data=Neue Überweisung mit gleichen Daten
account.transactions.table.context.menu.show.transaction.details=Details anzeigen account.transactions.table.context.menu.show.transaction.details=Details anzeigen

View File

@ -83,9 +83,13 @@ open class AccountTransactionsView(private val presenter: BankingPresenter) : Vi
val contextMenu = ContextMenu() val contextMenu = ContextMenu()
contextMenu.apply { contextMenu.apply {
if (selectedItem.bankAccount.supportsTransferringMoney && selectedItem.otherPartyName.isNullOrBlank() == false) { if (selectedItem.canCreateMoneyTransferFrom) {
item(String.format(FX.messages["account.transactions.table.context.menu.transfer.money.to"], selectedItem.otherPartyName)) { item(String.format(FX.messages["account.transactions.table.context.menu.new.transfer.to.same.remittee"], selectedItem.otherPartyName)) {
action { showTransferMoneyDialog(selectedItem) } action { newTransferToSameRemittee(selectedItem) }
}
item(String.format(FX.messages["account.transactions.table.context.menu.new.transfer.with.same.data"], selectedItem.otherPartyName)) {
action { newTransferWithSameData(selectedItem) }
} }
separator() separator()
@ -106,7 +110,11 @@ open class AccountTransactionsView(private val presenter: BankingPresenter) : Vi
// presenter.showTransactionDetailsWindow(transaction.item) // presenter.showTransactionDetailsWindow(transaction.item)
} }
protected open fun showTransferMoneyDialog(transaction: AccountTransaction) { protected open fun newTransferToSameRemittee(transaction: AccountTransaction) {
presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransactionWithoutAmountAndUsage(transaction))
}
protected open fun newTransferWithSameData(transaction: AccountTransaction) {
presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransaction(transaction)) presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransaction(transaction))
} }

View File

@ -87,6 +87,9 @@ open class AccountTransaction(
open val showOtherPartyName: Boolean open val showOtherPartyName: Boolean
get() = otherPartyName.isNullOrBlank() == false /* && type != "ENTGELTABSCHLUSS" && type != "AUSZAHLUNG" */ // TODO get() = otherPartyName.isNullOrBlank() == false /* && type != "ENTGELTABSCHLUSS" && type != "AUSZAHLUNG" */ // TODO
open val canCreateMoneyTransferFrom: Boolean
get() = otherPartyAccountId != null && bankAccount.supportsTransferringMoney
open val usage: String open val usage: String
get() = sepaUsage ?: unparsedUsage get() = sepaUsage ?: unparsedUsage

View File

@ -17,7 +17,7 @@ open class TransferMoneyData(
companion object { companion object {
fun fromAccountTransaction(transaction: AccountTransaction): TransferMoneyData { fun fromAccountTransactionWithoutAmountAndUsage(transaction: AccountTransaction): TransferMoneyData {
return TransferMoneyData( return TransferMoneyData(
transaction.bankAccount, transaction.bankAccount,
transaction.otherPartyName ?: "", transaction.otherPartyName ?: "",
@ -28,6 +28,17 @@ open class TransferMoneyData(
) )
} }
fun fromAccountTransaction(transaction: AccountTransaction): TransferMoneyData {
return TransferMoneyData(
transaction.bankAccount,
transaction.otherPartyName ?: "",
transaction.otherPartyAccountId ?: "",
transaction.otherPartyBankCode ?: "",
if (transaction.amount.isPositive) transaction.amount else transaction.amount.negated(),
transaction.usage
)
}
} }
} }

View File

@ -55,7 +55,9 @@
"%@ transactions" = "%@ transactions"; "%@ transactions" = "%@ transactions";
"Fetch all account transactions" = "Fetch earlier transactions (requires TAN)"; "Fetch all account transactions" = "Fetch earlier transactions (requires TAN)";
"Transfer money to %@" = "Transfer money to %@"; "Transfer money to %@" = "Transfer money to %@";
"New transfer with same data" = "New transfer with same data";
"Could not fetch latest transactions" = "Could not fetch latest transactions"; "Could not fetch latest transactions" = "Could not fetch latest transactions";
"Could not fetch latest transactions for %@. Error message from your bank: %@." = "Could not fetch latest transactions for %@.\nError message from your bank:\n%@."; "Could not fetch latest transactions for %@. Error message from your bank: %@." = "Could not fetch latest transactions for %@.\nError message from your bank:\n%@.";

View File

@ -55,7 +55,9 @@
"%@ transactions" = "%@ Umsätze"; "%@ transactions" = "%@ Umsätze";
"Fetch all account transactions" = "Ältere Umsätze laden (erfordert TAN)"; "Fetch all account transactions" = "Ältere Umsätze laden (erfordert TAN)";
"Transfer money to %@" = "Neue Überweisung an %@"; "Transfer money to %@" = "Neue Überweisung an %@";
"New transfer with same data" = "Neue Überweisung mit gleichen Daten";
"Could not fetch latest transactions" = "Umsätze konnte nicht aktualisiert werden"; "Could not fetch latest transactions" = "Umsätze konnte nicht aktualisiert werden";
"Could not fetch latest transactions for %@. Error message from your bank: %@." = "Die Umsätze für %@ konnten nicht aktualisiert werden.\nFehlermeldung Ihrer Bank:\n%@."; "Could not fetch latest transactions for %@. Error message from your bank: %@." = "Die Umsätze für %@ konnten nicht aktualisiert werden.\nFehlermeldung Ihrer Bank:\n%@.";

View File

@ -18,9 +18,6 @@ struct AccountTransactionListItem: View {
private let areMoreThanOneBanksTransactionsDisplayed: Bool private let areMoreThanOneBanksTransactionsDisplayed: Bool
private var transferMoneyData: TransferMoneyData
@Inject private var presenter: BankingPresenterSwift @Inject private var presenter: BankingPresenterSwift
@ -28,8 +25,6 @@ struct AccountTransactionListItem: View {
self.transaction = transaction self.transaction = transaction
self.areMoreThanOneBanksTransactionsDisplayed = areMoreThanOneBanksTransactionsDisplayed self.areMoreThanOneBanksTransactionsDisplayed = areMoreThanOneBanksTransactionsDisplayed
self.transferMoneyData = TransferMoneyData.Companion().fromAccountTransaction(transaction: transaction)
} }
@ -64,14 +59,22 @@ struct AccountTransactionListItem: View {
} }
} }
.contextMenu { .contextMenu {
if transaction.otherPartyAccountId != nil && transaction.bankAccount.supportsTransferringMoney { if transaction.canCreateMoneyTransferFrom {
NavigationLink(destination: LazyView(TransferMoneyDialog(preselectedBankAccount: self.transaction.bankAccount, preselectedValues: self.transferMoneyData))) { NavigationLink(destination: LazyView(TransferMoneyDialog(preselectedValues: TransferMoneyData.Companion().fromAccountTransactionWithoutAmountAndUsage(transaction: self.transaction)))) {
HStack { HStack {
Text("Transfer money to \(transaction.otherPartyName ?? "")") Text("Transfer money to \(transaction.otherPartyName ?? "")")
Image("BankTransfer") Image("BankTransfer")
} }
} }
NavigationLink(destination: LazyView(TransferMoneyDialog(preselectedValues: TransferMoneyData.Companion().fromAccountTransaction(transaction: self.transaction)))) {
HStack {
Text("New transfer with same data")
Image("BankTransfer")
}
}
} }
} }
} }

View File

@ -76,9 +76,10 @@ struct TransferMoneyDialog: View {
self.showAccounts = self.accountsSupportingTransferringMoney.count > 1 self.showAccounts = self.accountsSupportingTransferringMoney.count > 1
} }
init(preselectedBankAccount: BankAccount, preselectedValues: TransferMoneyData) { init(preselectedValues: TransferMoneyData) {
self.init() self.init()
let preselectedBankAccount = preselectedValues.account
self._selectedAccountIndex = State(initialValue: accountsSupportingTransferringMoney.firstIndex(where: { account in account == preselectedBankAccount }) ?? 0) self._selectedAccountIndex = State(initialValue: accountsSupportingTransferringMoney.firstIndex(where: { account in account == preselectedBankAccount }) ?? 0)
self._remitteeName = State(initialValue: preselectedValues.creditorName) self._remitteeName = State(initialValue: preselectedValues.creditorName)