Implemented BankListPrettifier to remove duplicate bank entries and to set better names (e.g. 'Deutsche Bank' instead of 'DB Privat- und Firmenkundenbank ...')
This commit is contained in:
parent
2fd11b2e56
commit
826af7c8b8
|
@ -2,7 +2,7 @@ package net.dankito.banking.bankfinder
|
||||||
|
|
||||||
|
|
||||||
open class BankInfo constructor(
|
open class BankInfo constructor(
|
||||||
open val name: String,
|
open var name: String,
|
||||||
open val bankCode: String,
|
open val bankCode: String,
|
||||||
open val bic: String,
|
open val bic: String,
|
||||||
open val postalCode: String,
|
open val postalCode: String,
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -19,9 +19,9 @@ dependencies {
|
||||||
implementation 'org.docx4j:docx4j-JAXB-ReferenceImpl:8.1.3'
|
implementation 'org.docx4j:docx4j-JAXB-ReferenceImpl:8.1.3'
|
||||||
|
|
||||||
|
|
||||||
testCompile "junit:junit:$junitVersion"
|
testImplementation "junit:junit:$junitVersion"
|
||||||
testCompile "org.assertj:assertj-core:$assertJVersion"
|
testImplementation "org.assertj:assertj-core:$assertJVersion"
|
||||||
|
|
||||||
testCompile "ch.qos.logback:logback-core:$logbackVersion"
|
testImplementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||||
testCompile "ch.qos.logback:logback-classic:$logbackVersion"
|
testImplementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
}
|
}
|
|
@ -1,20 +1,41 @@
|
||||||
package net.dankito.banking.banklistcreator
|
package net.dankito.banking.banklistcreator
|
||||||
|
|
||||||
|
import net.dankito.banking.bankfinder.BankInfo
|
||||||
import net.dankito.banking.banklistcreator.parser.DeutscheKreditwirtschaftBankListParser
|
import net.dankito.banking.banklistcreator.parser.DeutscheKreditwirtschaftBankListParser
|
||||||
|
import net.dankito.banking.banklistcreator.prettifier.BankListPrettifier
|
||||||
|
import net.dankito.banking.banklistcreator.prettifier.BankListPrettifierOption
|
||||||
import net.dankito.utils.serialization.JacksonJsonSerializer
|
import net.dankito.utils.serialization.JacksonJsonSerializer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
open class BankListCreator @JvmOverloads constructor(
|
open class BankListCreator @JvmOverloads constructor(
|
||||||
protected open val parser: DeutscheKreditwirtschaftBankListParser = DeutscheKreditwirtschaftBankListParser()
|
protected open val parser: DeutscheKreditwirtschaftBankListParser = DeutscheKreditwirtschaftBankListParser(),
|
||||||
|
protected open val prettifier: BankListPrettifier = BankListPrettifier()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
open fun createBankListFromDeutscheKreditwirtschaftXlsxFile(bankFileOutputFile: File,
|
open fun createBankListFromDeutscheKreditwirtschaftXlsxFile(deutscheKreditwirtschaftXlsxFile: File,
|
||||||
deutscheKreditwirtschaftXlsxFile: File) {
|
bankListOutputFile: File) {
|
||||||
|
|
||||||
val banks = parser.parse(deutscheKreditwirtschaftXlsxFile)
|
val banks = parser.parse(deutscheKreditwirtschaftXlsxFile)
|
||||||
|
|
||||||
JacksonJsonSerializer().serializeObject(banks, bankFileOutputFile)
|
saveBankListAsJson(banks, bankListOutputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun createDetailedAndPrettifiedBankListFromDeutscheKreditwirtschaftXlsxFile(
|
||||||
|
deutscheKreditwirtschaftXlsxFile: File, detailedBankListOutputFile: File,
|
||||||
|
prettifiedBankListOutputFile: File, prettifyOptions: List<BankListPrettifierOption>) {
|
||||||
|
|
||||||
|
val allBanks = parser.parse(deutscheKreditwirtschaftXlsxFile)
|
||||||
|
|
||||||
|
saveBankListAsJson(allBanks, detailedBankListOutputFile)
|
||||||
|
|
||||||
|
val mappedBanks = allBanks.map { BankInfo(it.name, it.bankCode, it.bic, it.postalCode, it.city, it.pinTanAddress, it.pinTanVersion) }
|
||||||
|
val prettifiedBanks = prettifier.prettify(mappedBanks, prettifyOptions)
|
||||||
|
saveBankListAsJson(prettifiedBanks, prettifiedBankListOutputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun saveBankListAsJson(banks: List<BankInfo>, bankListOutputFile: File) {
|
||||||
|
JacksonJsonSerializer().serializeObject(banks, bankListOutputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package net.dankito.banking.banklistcreator.prettifier
|
||||||
|
|
||||||
|
import net.dankito.banking.bankfinder.BankInfo
|
||||||
|
|
||||||
|
|
||||||
|
open class BankListPrettifier {
|
||||||
|
|
||||||
|
open fun prettify(banks: List<BankInfo>, options: List<BankListPrettifierOption>): List<BankInfo> {
|
||||||
|
var prettifiedList = banks
|
||||||
|
|
||||||
|
if (options.contains(BankListPrettifierOption.RemoveInstitutionInternalBank)) {
|
||||||
|
prettifiedList = removeInstitutionInternalBank(prettifiedList)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.contains(BankListPrettifierOption.RemoveBanksWithSameBankCodeAndPostalCode)) {
|
||||||
|
prettifiedList = removeBanksWithSameBankCodeAndPostalCode(prettifiedList)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.contains(BankListPrettifierOption.RemoveBanksWithSameBankCodeAndCity)) {
|
||||||
|
prettifiedList = removeBanksWithSameBankCodeAndCity(prettifiedList)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.contains(BankListPrettifierOption.MapBankNamesToWellKnownNames)) {
|
||||||
|
prettifiedList = mapBankNamesToWellKnownNames(prettifiedList)
|
||||||
|
}
|
||||||
|
|
||||||
|
return prettifiedList
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun mapBankNamesToWellKnownNames(banks: List<BankInfo>): List<BankInfo> {
|
||||||
|
banks.forEach { bank ->
|
||||||
|
when {
|
||||||
|
bank.name.contains("Postbank") -> bank.name = "Postbank"
|
||||||
|
bank.name.startsWith("Deutsche Kreditbank") -> bank.name = "DKB (Deutsche Kreditbank)"
|
||||||
|
bank.name.startsWith("Deutsche Bank") || bank.name.startsWith("DB Privat- und Firmenkundenbank") -> bank.name = "Deutsche Bank"
|
||||||
|
bank.name.startsWith("Commerzbank") -> bank.name = "Commerzbank" // TODO: keep "vormals Dresdner Bank"?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return banks
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun removeInstitutionInternalBank(banks: List<BankInfo>): List<BankInfo> {
|
||||||
|
return banks.filterNot {
|
||||||
|
(it.name.contains("intern", true) && it.name.contains("international", true) == false)
|
||||||
|
|| it.name.startsWith("UniCredit Bank - HVB Settlement")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun removeBanksWithSameBankCodeAndPostalCode(banks: List<BankInfo>): List<BankInfo> {
|
||||||
|
val groupedByBankCodeAndPostalCode = banks.groupBy { it.bankCode + "_" + it.postalCode }
|
||||||
|
|
||||||
|
val banksToRemove = groupedByBankCodeAndPostalCode.values.flatMap { banksWithSameBankCodeAndPostalCode ->
|
||||||
|
if (banksWithSameBankCodeAndPostalCode.size > 1) {
|
||||||
|
val bankWithBestName = findBankWithShortestName(banksWithSameBankCodeAndPostalCode)
|
||||||
|
val banksWithoutBankWithBestName = banksWithSameBankCodeAndPostalCode.toMutableList()
|
||||||
|
|
||||||
|
banksWithoutBankWithBestName.remove(bankWithBestName)
|
||||||
|
return@flatMap banksWithoutBankWithBestName
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf<BankInfo>()
|
||||||
|
}
|
||||||
|
|
||||||
|
val prettifiedList = banks.toMutableList()
|
||||||
|
prettifiedList.removeAll(banksToRemove)
|
||||||
|
|
||||||
|
return prettifiedList
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: there are many banks like "Volksbank Nordmünsterland -alt-" and "Volksbank Nordmünsterland (Gf P2)" where each time "-alt-" gets selected
|
||||||
|
protected open fun findBankWithShortestName(banks: List<BankInfo>): BankInfo {
|
||||||
|
var bankWithBestName = banks.first()
|
||||||
|
|
||||||
|
for (i in 1 until banks.size) {
|
||||||
|
val bank = banks[i]
|
||||||
|
if (bank.name.length < bankWithBestName.name.length) {
|
||||||
|
bankWithBestName = bank
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bankWithBestName
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun removeBanksWithSameBankCodeAndCity(banks: List<BankInfo>): List<BankInfo> {
|
||||||
|
val groupedByBankCodeAndCity = banks.groupBy { it.bankCode + "_" + it.city }
|
||||||
|
|
||||||
|
val banksToRemove = groupedByBankCodeAndCity.values.flatMap { banksWithSameBankCodeAndCity ->
|
||||||
|
if (banksWithSameBankCodeAndCity.size > 1) {
|
||||||
|
val banksToRemove = banksWithSameBankCodeAndCity.toMutableList()
|
||||||
|
banksToRemove.remove(banksWithSameBankCodeAndCity.first())
|
||||||
|
|
||||||
|
return@flatMap banksToRemove
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf<BankInfo>()
|
||||||
|
}
|
||||||
|
|
||||||
|
val prettifiedList = banks.toMutableList()
|
||||||
|
prettifiedList.removeAll(banksToRemove)
|
||||||
|
|
||||||
|
return prettifiedList
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package net.dankito.banking.banklistcreator.prettifier
|
||||||
|
|
||||||
|
|
||||||
|
enum class BankListPrettifierOption {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps e.g. 'DB Privat- und Firmenkundenbank ...' to 'Deutsche Bank' or 'Deutsche Kreditbank' to 'DKB'
|
||||||
|
*/
|
||||||
|
MapBankNamesToWellKnownNames,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Often the same bank is contained multiple times but with a '(Gf 2)' etc. suffix in name. Filters these out that have the same bank code and postal code.
|
||||||
|
*/
|
||||||
|
RemoveBanksWithSameBankCodeAndPostalCode,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Often the same bank is contained multiple times but with a '(Gf 2)' etc. suffix in name. Filters these out that have the same bank code and city.
|
||||||
|
*/
|
||||||
|
RemoveBanksWithSameBankCodeAndCity,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes banks like 'Deutsche Bank (Gf intern)' or 'UniCredit Bank - HVB Settlement EAC01' etc.
|
||||||
|
*/
|
||||||
|
RemoveInstitutionInternalBank
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package net.dankito.banking.banklistcreator
|
package net.dankito.banking.banklistcreator
|
||||||
|
|
||||||
|
import net.dankito.banking.banklistcreator.prettifier.BankListPrettifierOption
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
|
@ -15,9 +16,12 @@ class BankListCreatorTest {
|
||||||
@Test
|
@Test
|
||||||
fun createBankListJson() {
|
fun createBankListJson() {
|
||||||
// TODO: set path to bank list file from Deutsche Kreditwirtschaft in TestConfig.DeutscheKreditwirtschaftBankListXlsxFile
|
// TODO: set path to bank list file from Deutsche Kreditwirtschaft in TestConfig.DeutscheKreditwirtschaftBankListXlsxFile
|
||||||
underTest.createBankListFromDeutscheKreditwirtschaftXlsxFile(
|
underTest.createDetailedAndPrettifiedBankListFromDeutscheKreditwirtschaftXlsxFile(
|
||||||
|
TestConfig.DeutscheKreditwirtschaftBankListXlsxFile,
|
||||||
|
File("../BankFinder/src/commonMain/resources/DetailedBankList.json"),
|
||||||
File("../BankFinder/src/commonMain/resources/BankList.json"),
|
File("../BankFinder/src/commonMain/resources/BankList.json"),
|
||||||
TestConfig.DeutscheKreditwirtschaftBankListXlsxFile)
|
BankListPrettifierOption.values().toList()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package net.dankito.banking.banklistcreator.prettifier
|
||||||
|
|
||||||
|
import net.dankito.banking.banklistcreator.TestConfig
|
||||||
|
import net.dankito.banking.banklistcreator.parser.DeutscheKreditwirtschaftBankListParser
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Ignore
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
|
@Ignore // not an automatic test, set your path to your bank list file in TestConfig.DeutscheKreditwirtschaftBankListXlsxFile
|
||||||
|
class BankListPrettifierTest {
|
||||||
|
|
||||||
|
private val underTest = BankListPrettifier()
|
||||||
|
|
||||||
|
private val allBanks = DeutscheKreditwirtschaftBankListParser().parse(TestConfig.DeutscheKreditwirtschaftBankListXlsxFile)
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun mapBankNamesToWellKnownNames() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.mapBankNamesToWellKnownNames(allBanks)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).hasSize(allBanks.size)
|
||||||
|
|
||||||
|
val resultingBanksNames = result.map { it.name }
|
||||||
|
|
||||||
|
assertThat(resultingBanksNames.filter { it.contains("DB Privat- und Firmenkundenbank") }).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun removeBanksWithSameBankCodeAndPostalCode() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
val result = underTest.removeBanksWithSameBankCodeAndPostalCode(allBanks)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).hasSizeLessThan(allBanks.size)
|
||||||
|
|
||||||
|
val resultingBanksNames = result.map { it.name }
|
||||||
|
|
||||||
|
assertThat(resultingBanksNames.filter { it.contains("PSD Bank München (Gf P2)") }).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -59,7 +59,7 @@ struct BankInfoListItem: View {
|
||||||
struct BankInfoListItem_Previews: PreviewProvider {
|
struct BankInfoListItem_Previews: PreviewProvider {
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
BankInfoListItem(BankInfo(name: "Abzockbank Berlin", bankCode: "12345678", bic: "ABZODEBBXXX", postalCode: "12345", city: "Berlin", checksumMethod: "", pinTanAddress: nil, pinTanVersion: "FinTS 3.0", oldBankCode: nil))
|
BankInfoListItem(BankInfo(name: "Abzockbank Berlin", bankCode: "12345678", bic: "ABZODEBBXXX", postalCode: "12345", city: "Berlin", pinTanAddress: nil, pinTanVersion: "FinTS 3.0"))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue