Implemented making data element's value optional
This commit is contained in:
parent
9a094ed3fc
commit
4dfc53994c
|
@ -6,6 +6,13 @@ import net.dankito.fints.messages.Existenzstatus
|
|||
abstract class Datenelement(existenzstatus: Existenzstatus): DatenelementBase(existenzstatus) {
|
||||
|
||||
|
||||
abstract val isValueSet: Boolean
|
||||
|
||||
open val writeToOutput: Boolean
|
||||
get() = existenzstatus == Existenzstatus.Mandatory
|
||||
|| existenzstatus == Existenzstatus.Optional && isValueSet
|
||||
|
||||
|
||||
@Throws(IllegalArgumentException::class)
|
||||
abstract fun validate()
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
|||
/**
|
||||
* Es sind nur die jeweils aufgeführten Werte zulässig.
|
||||
*/
|
||||
abstract class Code(code: String, val allowedValues: List<String>, existenzstatus: Existenzstatus)
|
||||
abstract class Code(code: String?, val allowedValues: List<String>, existenzstatus: Existenzstatus)
|
||||
: AlphanumerischesDatenelement(code, existenzstatus) {
|
||||
|
||||
override fun validate() {
|
||||
super.validate()
|
||||
|
||||
if (allowedValues.contains(text) == false) {
|
||||
throwValidationException("'$text' ist kein Wert aus der Liste der zulässigen Werte: " +
|
||||
if (allowedValues.contains(value) == false) {
|
||||
throwValidationException("'$value' ist kein Wert aus der Liste der zulässigen Werte: " +
|
||||
allowedValues.joinToString(", ")
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,27 +11,16 @@ import java.util.*
|
|||
*
|
||||
* Erlaubt sind alle existenten Datumsangaben.
|
||||
*/
|
||||
open class Datum(date: Int, existenzstatus: Existenzstatus) : NumerischesDatenelement(date, 8, existenzstatus) {
|
||||
open class Datum(date: Int?, existenzstatus: Existenzstatus) : NumerischesDatenelement(date, 8, existenzstatus) {
|
||||
|
||||
companion object {
|
||||
const val HbciDateFormatString = "yyyyMMdd"
|
||||
|
||||
val HbciDateFormat = SimpleDateFormat(HbciDateFormatString)
|
||||
|
||||
const val DateNotSet = Int.MIN_VALUE
|
||||
}
|
||||
|
||||
|
||||
constructor(date: Date?, existenzstatus: Existenzstatus)
|
||||
: this(date?.let { HbciDateFormat.format(it).toInt() } ?: DateNotSet, existenzstatus)
|
||||
|
||||
|
||||
override fun format(): String {
|
||||
if (value == DateNotSet) {
|
||||
return "" // optional element and value not set -> write nothing to output
|
||||
}
|
||||
|
||||
return super.format()
|
||||
}
|
||||
: this(date?.let { HbciDateFormat.format(it).toInt() }, existenzstatus)
|
||||
|
||||
}
|
|
@ -9,5 +9,5 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
|||
*
|
||||
* Maximal 30 Zeichen
|
||||
*/
|
||||
abstract class Identifikation(identification: String, existenzstatus: Existenzstatus)
|
||||
abstract class Identifikation(identification: String?, existenzstatus: Existenzstatus)
|
||||
: AlphanumerischesDatenelement(identification, existenzstatus, 30)
|
|
@ -10,4 +10,4 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
|||
* Hat das DE den Status „Kann“, so gilt bei Auslassung der Standardwert „N“.
|
||||
*/
|
||||
open class JaNein(yes: Boolean?, existenzstatus: Existenzstatus)
|
||||
: AlphanumerischesDatenelement(if (yes == true) "J" else "N", existenzstatus, 1)
|
||||
: AlphanumerischesDatenelement(yes?.let { if (yes == true) "J" else "N" }, existenzstatus, 1)
|
|
@ -9,7 +9,7 @@ import net.dankito.fints.messages.datenelemente.basisformate.ZiffernDatenelement
|
|||
*
|
||||
* (Siehe z.B. PDF Messages_Geschaeftsvorfaelle Kapitel E.4 (S. 813) oder https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes .)
|
||||
*/
|
||||
open class Laenderkennzeichen(countryCode: Int, existenzstatus: Existenzstatus)
|
||||
open class Laenderkennzeichen(countryCode: Int?, existenzstatus: Existenzstatus)
|
||||
: ZiffernDatenelement(countryCode, 3, existenzstatus) {
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -12,27 +12,16 @@ import java.util.*
|
|||
* Gültige Uhrzeit. Es ist immer Ortszeit des sendenden Systems einzustellen.
|
||||
* Unterschiedliche Zeitzonen werden nicht unterstützt
|
||||
*/
|
||||
open class Uhrzeit(time: Int, existenzstatus: Existenzstatus) : ZiffernDatenelement(time, 6, existenzstatus) {
|
||||
open class Uhrzeit(time: Int?, existenzstatus: Existenzstatus) : ZiffernDatenelement(time, 6, existenzstatus) {
|
||||
|
||||
companion object {
|
||||
const val HbciTimeFormatString = "HHmmss"
|
||||
|
||||
val HbciTimeFormat = SimpleDateFormat(HbciTimeFormatString)
|
||||
|
||||
const val TimeNotSet = Int.MIN_VALUE
|
||||
}
|
||||
|
||||
|
||||
constructor(time: Date?, existenzstatus: Existenzstatus)
|
||||
: this(time?.let { HbciTimeFormat.format(it).toInt() } ?: 0, existenzstatus)
|
||||
|
||||
|
||||
override fun format(): String {
|
||||
if (value == TimeNotSet) {
|
||||
return "" // optional element and value not set -> write nothing to output
|
||||
}
|
||||
|
||||
return super.format()
|
||||
}
|
||||
: this(time?.let { HbciTimeFormat.format(it).toInt() }, existenzstatus)
|
||||
|
||||
}
|
|
@ -7,22 +7,24 @@ import net.dankito.fints.messages.Existenzstatus
|
|||
* Es gilt der FinTS-Basiszeichensatz ohne die Zeichen CR und LF.
|
||||
*/
|
||||
abstract class AlphanumerischesDatenelement @JvmOverloads constructor(
|
||||
alphanumericValue: String, existenzstatus: Existenzstatus, val maxLength: Int? = null
|
||||
alphanumericValue: String?, existenzstatus: Existenzstatus, val maxLength: Int? = null
|
||||
) : TextDatenelement(alphanumericValue, existenzstatus) {
|
||||
|
||||
|
||||
override fun validate() {
|
||||
super.validate()
|
||||
|
||||
if (text.contains("\r") || text.contains("\n")) {
|
||||
throwValidationException("Alphanumerischer Wert '$text' darf kein Carriage Return (\r) oder " +
|
||||
if (writeToOutput && value != null) { // if value is null and value has to be written to output then validation already fails above
|
||||
if (value.contains("\r") || value.contains("\n")) {
|
||||
throwValidationException("Alphanumerischer Wert '$value' darf kein Carriage Return (\r) oder " +
|
||||
"Line Feed (\n) enthalten.")
|
||||
}
|
||||
|
||||
maxLength?.let {
|
||||
if (text.length > maxLength) {
|
||||
throwValidationException("Wert '$text' darf maximal $maxLength Zeichen lang sein, " +
|
||||
"hat aber ${text.length} Zeichen.")
|
||||
if (value.length > maxLength) {
|
||||
throwValidationException("Wert '$value' darf maximal $maxLength Zeichen lang sein, " +
|
||||
"hat aber ${value.length} Zeichen.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package net.dankito.fints.messages.datenelemente.basisformate
|
||||
|
||||
import net.dankito.fints.messages.Existenzstatus
|
||||
import net.dankito.fints.messages.datenelemente.Datenelement
|
||||
|
||||
|
||||
/**
|
||||
|
@ -10,12 +9,13 @@ import net.dankito.fints.messages.datenelemente.Datenelement
|
|||
* für binäre Daten keine Gültigkeit besitzt. Ferner gelten die speziellen Syntaxregeln für
|
||||
* binäre Daten (s. Kap. H.1.3).
|
||||
*/
|
||||
open class BinaerDatenelement @JvmOverloads constructor(val data: String, existenzstatus: Existenzstatus, val maxLength: Int? = null)
|
||||
: Datenelement(existenzstatus) {
|
||||
open class BinaerDatenelement @JvmOverloads constructor(data: String?, existenzstatus: Existenzstatus, val maxLength: Int? = null)
|
||||
: TextDatenelement(data, existenzstatus) {
|
||||
|
||||
@JvmOverloads constructor(data: ByteArray, existenzstatus: Existenzstatus, maxLength: Int? = null) :
|
||||
this(String(data), existenzstatus, maxLength)
|
||||
|
||||
|
||||
/**
|
||||
* Für binäre Daten gilt eine besondere Syntaxregelung: Das Auftreten dieser Daten wird eingeleitet mit dem
|
||||
* Binärdatenkennzeichen (@). Anschließend folgt die Längenangabe zu den binären Daten und der binäre Wert selbst,
|
||||
|
@ -27,21 +27,23 @@ open class BinaerDatenelement @JvmOverloads constructor(val data: String, existe
|
|||
* Bei Elementen, die entsprechende Zeichen enthalten können (z. B. DE „SEPAName) ist eine base64-Kodierung in der
|
||||
* Spezifikation vorzusehen.
|
||||
*/
|
||||
override fun format(): String {
|
||||
if (data.length > 0) {
|
||||
return "@${data.length}@" + data
|
||||
}
|
||||
|
||||
return ""
|
||||
override fun formatValue(value: String): String {
|
||||
return "@${value.length}@" + value
|
||||
}
|
||||
|
||||
override fun validate() {
|
||||
// binary data aren't checked, so they are always valid
|
||||
|
||||
if (writeToOutput) {
|
||||
checkIfMandatoryValueIsSet()
|
||||
|
||||
value?.let { // if value is null and value has to be written to output then validation already fails above
|
||||
maxLength?.let {
|
||||
if (data.length > maxLength) {
|
||||
throwValidationException("Binäre Daten dürfen nur eine maximale Größe von $maxLength Bytes haben, " +
|
||||
"haben aber ${data.length} Bytes.")
|
||||
if (value.length > maxLength) {
|
||||
throwValidationException("Binäre Daten dürfen nur eine maximale Größe von $maxLength Bytes " +
|
||||
"haben, haben aber ${value.length} Bytes.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
package net.dankito.fints.messages.datenelemente.basisformate
|
||||
|
||||
import net.dankito.fints.messages.Existenzstatus
|
||||
import net.dankito.fints.messages.datenelemente.Datenelement
|
||||
|
||||
|
||||
/**
|
||||
* Zulässig sind lediglich die Ziffern ‘0’ bis ‘9’. Führende Nullen sind nicht zugelassen.
|
||||
*/
|
||||
abstract class NumerischesDatenelement(val value: Int, val numberOfDigits: Int, existenzstatus: Existenzstatus)
|
||||
: Datenelement(existenzstatus) {
|
||||
|
||||
|
||||
override fun format(): String {
|
||||
return value.toString()
|
||||
}
|
||||
abstract class NumerischesDatenelement(val number: Int?, val numberOfDigits: Int, existenzstatus: Existenzstatus)
|
||||
: TextDatenelement(number?.toString(), existenzstatus) {
|
||||
|
||||
|
||||
override fun validate() {
|
||||
super.validate()
|
||||
|
||||
if (writeToOutput && number != null) { // if number is null and number has to be written to output then validation already fails above
|
||||
val maxValue = Math.pow(10.0, numberOfDigits.toDouble()) - 1
|
||||
|
||||
if (value < 0 || value > maxValue) {
|
||||
throwValidationException("Wert '$value' muss im Wertebereich von 0 - $maxValue liegen.")
|
||||
if (number < 0 || number > maxValue) {
|
||||
throwValidationException("Wert '$number' muss im Wertebereich von 0 - $maxValue liegen.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,27 +8,49 @@ import net.dankito.fints.messages.datenelemente.Datenelement
|
|||
/**
|
||||
* Es gilt der vollständige FinTS-Basiszeichensatz.
|
||||
*/
|
||||
abstract class TextDatenelement(val text: String, existenzstatus: Existenzstatus) : Datenelement(existenzstatus) {
|
||||
abstract class TextDatenelement(val value: String?, existenzstatus: Existenzstatus) : Datenelement(existenzstatus) {
|
||||
|
||||
|
||||
override val isValueSet = value != null
|
||||
|
||||
override fun format(): String {
|
||||
return text
|
||||
if (writeToOutput) {
|
||||
value?.let {
|
||||
return formatValue(it)
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
protected open fun formatValue(value: String): String {
|
||||
return value // may overwritten in sub classes
|
||||
}
|
||||
|
||||
|
||||
override fun validate() {
|
||||
if (writeToOutput) {
|
||||
checkIfMandatoryValueIsSet()
|
||||
|
||||
try {
|
||||
if (HbciCharset.DefaultCharset.newEncoder().canEncode(text) == false) {
|
||||
if (HbciCharset.DefaultCharset.newEncoder().canEncode(value) == false) {
|
||||
throwInvalidCharacterException()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throwInvalidCharacterException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun checkIfMandatoryValueIsSet() {
|
||||
if (existenzstatus == Existenzstatus.Mandatory && value == null) {
|
||||
throwValidationException("Wert ist auf dem Pflichtfeld ${javaClass.simpleName} not set")
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun throwInvalidCharacterException() {
|
||||
throwValidationException(
|
||||
"Wert '$text' enthält Zeichen die gemäß des Zeichensatzes " +
|
||||
"Wert '$value' enthält Zeichen die gemäß des Zeichensatzes " +
|
||||
"${HbciCharset.DefaultCharset.displayName()} nicht erlaubt sind."
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ import net.dankito.fints.messages.Existenzstatus
|
|||
/**
|
||||
* Zulässig sind die Ziffern ‘0’ bis ‘9’. Führende Nullen sind zugelassen.
|
||||
*/
|
||||
abstract class ZiffernDatenelement(value: Int, numberOfDigits: Int, existenzstatus: Existenzstatus)
|
||||
abstract class ZiffernDatenelement(value: Int?, numberOfDigits: Int, existenzstatus: Existenzstatus)
|
||||
: NumerischesDatenelement(value, numberOfDigits, existenzstatus) {
|
||||
|
||||
|
||||
override fun format(): String {
|
||||
return String.format("%0${numberOfDigits}d", value)
|
||||
override fun formatValue(value: String): String {
|
||||
return String.format("%0${numberOfDigits}d", number)
|
||||
}
|
||||
|
||||
}
|
|
@ -18,11 +18,14 @@ import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenele
|
|||
abstract class Bezugssegment(segmentNumber: Int, existenzstatus: Existenzstatus)
|
||||
: NumerischesDatenelement(segmentNumber, 3, existenzstatus) {
|
||||
|
||||
|
||||
override fun validate() {
|
||||
super.validate()
|
||||
|
||||
if (value < 1) {
|
||||
throwValidationException("Bezug Segmentnummer '$value' muss größer oder gleich 1 sein.")
|
||||
number?.let { // if number is null and number has to be written to output then validation already fails above
|
||||
if (number < 1) {
|
||||
throwValidationException("Bezug Segmentnummer '$number' muss größer oder gleich 1 sein.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,14 @@ import net.dankito.fints.messages.datenelemente.basisformate.NumerischesDatenele
|
|||
*/
|
||||
open class Segmentnummer(number: Int) : NumerischesDatenelement(number, 3, Existenzstatus.Mandatory) {
|
||||
|
||||
|
||||
override fun validate() {
|
||||
super.validate()
|
||||
|
||||
if (value < 1) {
|
||||
throwValidationException("Segmentnummer '$value' muss größer oder gleich 1 sein.")
|
||||
number?.let { // if number is null and number has to be written to output then validation already fails above
|
||||
if (number < 1) {
|
||||
throwValidationException("Segmentnummer '$number' muss größer oder gleich 1 sein.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,4 +12,4 @@ import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Identifikatio
|
|||
* Es ist zu beachten, dass Kontonummern auch führende Nullen beinhalten können, die
|
||||
* bankfachlich relevant sind und nicht abgeschnitten werden dürfen.
|
||||
*/
|
||||
open class KontoDepotnummer(number: String, existenzstatus: Existenzstatus) : Identifikation(number, existenzstatus)
|
||||
open class KontoDepotnummer(number: String?, existenzstatus: Existenzstatus) : Identifikation(number, existenzstatus)
|
|
@ -9,4 +9,4 @@ import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Identifikatio
|
|||
* geführt werden. Anstatt einer Kontonummer kann auch ein anderes identifizierendes Merkmal
|
||||
* angegeben werden (z.B. der entsprechende ISO-Währungscode bei Währungskonten).
|
||||
*/
|
||||
open class Unterkontomerkmal(attribute: String, existenzstatus: Existenzstatus) : Identifikation(attribute, existenzstatus)
|
||||
open class Unterkontomerkmal(attribute: String?, existenzstatus: Existenzstatus) : Identifikation(attribute, existenzstatus)
|
|
@ -9,5 +9,5 @@ import net.dankito.fints.messages.datenelemente.basisformate.AlphanumerischesDat
|
|||
* kann in Verwaltungs-Geschäftsvorfällen benutzt werden, wenn z. B. die Angabe der echten Handynummer
|
||||
* aus Datenschutzgründen nicht möglich ist oder auch um die Benutzerfreundlichkeit zu erhöhen.
|
||||
*/
|
||||
open class BezeichnungDesTANMediums(identifier: String, existenzstatus: Existenzstatus)
|
||||
open class BezeichnungDesTANMediums(identifier: String?, existenzstatus: Existenzstatus)
|
||||
: AlphanumerischesDatenelement(identifier, existenzstatus, 32)
|
|
@ -27,9 +27,9 @@ open class KontoverbindungInternational(
|
|||
) : Datenelementgruppe(listOf(
|
||||
IBAN(iban ?: "", Existenzstatus.Optional),
|
||||
BIC(bic ?: "", Existenzstatus.Optional),
|
||||
KontoDepotnummer(accountNumber ?: "", Existenzstatus.Optional),
|
||||
Unterkontomerkmal(subAccountAttribute ?: "", Existenzstatus.Optional),
|
||||
Kreditinstitutskennung(bankCountryCode ?: 0, bankCode ?: "", Existenzstatus.Optional)
|
||||
KontoDepotnummer(accountNumber, Existenzstatus.Optional),
|
||||
Unterkontomerkmal(subAccountAttribute, Existenzstatus.Optional),
|
||||
Kreditinstitutskennung(bankCountryCode ?: 0, bankCode ?: "", if (bankCountryCode != null && bankCode != null) Existenzstatus.Optional else Existenzstatus.NotAllowed)
|
||||
), Existenzstatus.Mandatory) {
|
||||
|
||||
constructor(bank: BankData, customer: CustomerData, subAccountAttribute: String?)
|
||||
|
|
|
@ -33,6 +33,6 @@ open class ZweiSchrittTanEinreichung(
|
|||
NotAllowedDatenelement(), // TODO: SMS-Abbuchungskonto // M: Bei TAN-Process=1, 3, 4 und „SMS-Abbuchungskonto erforderlich“=2. O: sonst
|
||||
NotAllowedDatenelement(), // TODO: Challenge-Klasse // M: bei TAN-Prozess=1 und „Challenge-Klasse erforderlich“=J. N: sonst
|
||||
NotAllowedDatenelement(), // TODO: Parameter Challenge-Klasse // O: Bei TAN-Process=1 „Challenge-Klasse erforderlich“=J. N: sonst
|
||||
BezeichnungDesTANMediums(tanMediaIdentifier ?: "", Existenzstatus.Optional), // M: bei TAN-Prozess=1, 3, 4 und „Anzahl unterstützter aktiver TAN-Medien“ nicht vorhanden. O: sonst
|
||||
BezeichnungDesTANMediums(tanMediaIdentifier, Existenzstatus.Optional), // M: bei TAN-Prozess=1, 3, 4 und „Anzahl unterstützter aktiver TAN-Medien“ nicht vorhanden. O: sonst
|
||||
NotAllowedDatenelement() // TODO: Antwort HHD_UC // M: bei TAN-Prozess=2 und „Antwort HHD_UC erforderlich“=“J“. O: sonst
|
||||
), Existenzstatus.Mandatory)
|
Loading…
Reference in New Issue