Implemented generating EQP QR Code
This commit is contained in:
parent
737d35b9a6
commit
3d474f38ae
|
@ -78,6 +78,7 @@ kotlin {
|
|||
|
||||
implementation(libs.banking.client.model)
|
||||
implementation(libs.fints4k.banking.client)
|
||||
implementation(libs.epcqrcode)
|
||||
|
||||
implementation(libs.kcsv)
|
||||
implementation(libs.klf)
|
||||
|
|
|
@ -56,6 +56,12 @@ fun FloatingActionMenu(
|
|||
if (fabVisibilityAnimation.value > 0) {
|
||||
Box(Modifier.fillMaxSize().padding(bottom = bottomPadding, end = 12.dp), contentAlignment = Alignment.BottomEnd) {
|
||||
Column(Modifier, horizontalAlignment = Alignment.End) {
|
||||
FloatingActionMenuItem("QR Code erstellen", "EPC QR Code erstellen") {
|
||||
handleClick {
|
||||
uiState.showCreateEpcQrCodeScreen.value = true
|
||||
}
|
||||
}
|
||||
|
||||
FloatingActionMenuItem("Überweisung", "Neue Überweisung", enabled = accountsThatSupportMoneyTransfer.isNotEmpty()) {
|
||||
handleClick {
|
||||
uiState.showTransferMoneyDialogData.value = ShowTransferMoneyDialogData()
|
||||
|
|
|
@ -15,6 +15,7 @@ private val formatUtil = DI.formatUtil
|
|||
fun StateHandler(uiState: UiState, snackbarHostState: SnackbarHostState) {
|
||||
val showAddAccountDialog by uiState.showAddAccountDialog.collectAsState()
|
||||
val showTransferMoneyDialogData by uiState.showTransferMoneyDialogData.collectAsState()
|
||||
val showCreateEpcQrCodeScreen by uiState.showCreateEpcQrCodeScreen.collectAsState()
|
||||
|
||||
val showAccountTransactionDetailsScreenForId by uiState.showAccountTransactionDetailsScreenForId.collectAsState()
|
||||
val showBankSettingsScreenForBank by uiState.showBankSettingsScreenForBank.collectAsState()
|
||||
|
@ -38,6 +39,10 @@ fun StateHandler(uiState: UiState, snackbarHostState: SnackbarHostState) {
|
|||
TransferMoneyDialog(data) { uiState.showTransferMoneyDialogData.value = null }
|
||||
}
|
||||
|
||||
if (showCreateEpcQrCodeScreen) {
|
||||
CreateEpcQrCodeScreen { uiState.showCreateEpcQrCodeScreen.value = false }
|
||||
}
|
||||
|
||||
|
||||
showAccountTransactionDetailsScreenForId?.let { transactionId ->
|
||||
DI.bankingService.getTransaction(transactionId)?.let { transaction ->
|
||||
|
|
|
@ -22,6 +22,9 @@ object Colors {
|
|||
val BackgroundColorLight = Color("#FFFFFF")
|
||||
|
||||
|
||||
val MaterialThemeTextColor = Color(0xFF4F4F4F) // to match dialog's text color of Material theme
|
||||
|
||||
|
||||
val DrawerContentBackground = BackgroundColorDark
|
||||
|
||||
val DrawerPrimaryText = PrimaryTextColorDark
|
||||
|
|
|
@ -29,6 +29,8 @@ object DI {
|
|||
|
||||
val accountTransactionsFilterService = AccountTransactionsFilterService()
|
||||
|
||||
val epcQrCodeService = EpcQrCodeService()
|
||||
|
||||
val uiService = UiService()
|
||||
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ fun EnterTanDialog(tanChallengeReceived: TanChallengeReceived, onDismiss: () ->
|
|||
|
||||
if (challenge.tanImage != null || challenge.flickerCode != null) {
|
||||
Column(Modifier.fillMaxWidth().padding(top = 6.dp)) {
|
||||
val textColor = Color(0xFF4F4F4F) // to match dialog's text color of Material theme
|
||||
val textColor = Colors.MaterialThemeTextColor // to match dialog's text color of Material theme
|
||||
|
||||
challenge.flickerCode?.let { flickerCode ->
|
||||
ChipTanFlickerCodeView(flickerCode, textColor)
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
package net.codinux.banking.ui.screens
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import net.codinux.banking.ui.composables.tan.ImageSizeControls
|
||||
import net.codinux.banking.ui.config.Colors
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.extensions.ImeNext
|
||||
import net.codinux.banking.ui.forms.OutlinedTextField
|
||||
import net.codinux.banking.ui.service.createImageBitmap
|
||||
|
||||
private val epcQrCodeService = DI.epcQrCodeService
|
||||
|
||||
@Composable
|
||||
fun CreateEpcQrCodeScreen(onClosed: () -> Unit) {
|
||||
|
||||
var receiverName by remember { mutableStateOf("") }
|
||||
|
||||
var iban by remember { mutableStateOf("") }
|
||||
|
||||
var bic by remember { mutableStateOf("") }
|
||||
|
||||
var amount by remember { mutableStateOf("") }
|
||||
|
||||
var reference by remember { mutableStateOf("") }
|
||||
|
||||
|
||||
val epcQrCodeBytes by remember(receiverName, iban, bic, amount, reference) {
|
||||
derivedStateOf {
|
||||
if (receiverName.isNotBlank() && iban.isNotBlank()) {
|
||||
epcQrCodeService.generateEpcQrCode(receiverName, iban, bic.takeUnless { it.isBlank() }, amount.takeUnless { it.isBlank() }, reference.takeUnless { it.isBlank() })
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var imageHeight by remember { mutableStateOf(350) }
|
||||
val minImageHeight = 100
|
||||
val maxImageHeight = 700
|
||||
|
||||
|
||||
FullscreenViewBase("EPC QR Code erstellen", "Schließen", onClosed = onClosed) {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
if (epcQrCodeBytes == null) {
|
||||
Text("Mit EPC QR Codes, welche als GiroCode, scan2code, ... vermarktet werden, können Überweisungsdaten ganz einfach von Banking Apps eingelesen werden.")
|
||||
Text("Hier können Sie Ihren eigenen erstellen, so dass jemand Ihre Überweisungsdaten einlesen und Ihnen ganz schnell Geld überweisen kann.")
|
||||
} else {
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
|
||||
ImageSizeControls(imageHeight > minImageHeight, imageHeight < maxImageHeight, Colors.MaterialThemeTextColor, { imageHeight -= 25 }) { imageHeight += 25 }
|
||||
}
|
||||
|
||||
Row(Modifier.fillMaxWidth().padding(bottom = 8.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
|
||||
Image(createImageBitmap(epcQrCodeBytes!!), "Erzeugter EPC QR Code", Modifier.height(imageHeight.dp), contentScale = ContentScale.FillHeight)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OutlinedTextField(
|
||||
label = { Text("Empfänger*in") },
|
||||
value = receiverName,
|
||||
onValueChange = { receiverName = it },
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
keyboardOptions = KeyboardOptions.ImeNext
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
label = { Text("IBAN") },
|
||||
value = iban,
|
||||
onValueChange = { iban = it },
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
keyboardOptions = KeyboardOptions.ImeNext
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
label = { Text("BIC (optional)") },
|
||||
value = bic,
|
||||
onValueChange = { bic = it },
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
keyboardOptions = KeyboardOptions.ImeNext
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
label = { Text("Betrag (optional)") },
|
||||
value = amount,
|
||||
onValueChange = { amount = it },
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
keyboardOptions = KeyboardOptions.ImeNext
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
label = { Text("Verwendungszweck (optional)") },
|
||||
value = reference,
|
||||
onValueChange = { reference = it },
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
keyboardOptions = KeyboardOptions.ImeNext
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package net.codinux.banking.ui.service
|
||||
|
||||
import net.codinux.banking.epcqrcode.EpcQrCode
|
||||
import net.codinux.banking.epcqrcode.EpcQrCodeConfig
|
||||
import net.codinux.banking.epcqrcode.EpcQrCodeGenerator
|
||||
|
||||
class EpcQrCodeService {
|
||||
|
||||
fun generateEpcQrCode(receiverName: String, iban: String, bic: String?, amount: String?, reference: String?, heightAndWidth: Int = EpcQrCode.DefaultHeightAndWidth): ByteArray {
|
||||
val generator = EpcQrCodeGenerator()
|
||||
|
||||
return generator.generateEpcQrCode(EpcQrCodeConfig(receiverName, iban, bic, amount, reference, qrCodeHeightAndWidth = heightAndWidth)).bytes
|
||||
}
|
||||
|
||||
}
|
|
@ -67,6 +67,8 @@ class UiState : ViewModel() {
|
|||
|
||||
val showTransferMoneyDialogData = MutableStateFlow<ShowTransferMoneyDialogData?>(null)
|
||||
|
||||
val showCreateEpcQrCodeScreen = MutableStateFlow(false)
|
||||
|
||||
val showAccountTransactionDetailsScreenForId = MutableStateFlow<Long?>(null)
|
||||
|
||||
val showBankSettingsScreenForBank = MutableStateFlow<BankAccessEntity?>(null)
|
||||
|
|
|
@ -3,6 +3,7 @@ kotlin = "2.0.10"
|
|||
kotlinx-coroutines = "1.8.1"
|
||||
|
||||
banking-client = "0.6.2-SNAPSHOT"
|
||||
epcqrcode = "1.0.0-SNAPSHOT"
|
||||
|
||||
kcsv = "2.2.0"
|
||||
kotlinx-serializable = "1.7.1"
|
||||
|
@ -36,6 +37,7 @@ junit = "4.13.2"
|
|||
[libraries]
|
||||
banking-client-model = { group = "net.codinux.banking.client", name = "banking-client-model", version.ref = "banking-client" }
|
||||
fints4k-banking-client = { group = "net.codinux.banking.client", name = "fints4k-banking-client", version.ref = "banking-client" }
|
||||
epcqrcode = { group = "net.codinux.banking.epcqrcode", name = "epc-qr-code", version.ref = "epcqrcode" }
|
||||
|
||||
kcsv = { group = "net.codinux.csv", name = "kcsv", version.ref = "kcsv" }
|
||||
coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
|
||||
|
|
Loading…
Reference in New Issue