Repository: digitalfabrik/entitlementcard
Issue: Fix import 

**Describe the bug**
With the new data format in bavaria, we are required to adjust the parsing of the XML. New fields are `p_eak_agentur_id` and `anbieter_name`. If any of the values is an empty string, it should be interpretet as None/null. The first is an empty string or a number, the latter a string or an empty string.

Changed files:
backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/FilterDuplicates.kt
backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/LbeAcceptingStore.kt
backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/AcceptingStore.kt
backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/SanitizeAddress.kt
backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/MapFromLbe.kt

diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/FilterDuplicates.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/FilterDuplicates.kt
index c73ed13f..c9ac3732 100644
--- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/FilterDuplicates.kt
+++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/FilterDuplicates.kt
@@ -23,6 +23,8 @@ class FilterDuplicates(private val logger: Logger) : PipelineStep<List<Accepting
         val store = last()
 
         logger.logRemoveDuplicates(store, size - 1)
+        val issuers = map { "'${it.districtName ?: it.freinetId.toString()}'" }.toSet().joinToString()
+        logger.info("Duplicates issued by $issuers")
 
         val location = lastValue("locations") { it.location }
         val categoryId = lastValue("categoryIds") { it.categoryId }
@@ -53,7 +55,9 @@ class FilterDuplicates(private val logger: Logger) : PipelineStep<List<Accepting
             email,
             telephone,
             website,
-            discounts
+            discounts,
+            store.freinetId,
+            store.districtName
         )
     }
 
diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/MapFromLbe.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/MapFromLbe.kt
index 9e1762d7..b95ecf0f 100644
--- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/MapFromLbe.kt
+++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/MapFromLbe.kt
@@ -27,7 +27,9 @@ class MapFromLbe(private val logger: Logger) : PipelineStep<List<LbeAcceptingSto
                 it.email.clean(),
                 it.telephone.clean(),
                 it.homepage.clean(),
-                it.discount.clean(false)
+                it.discount.clean(false),
+                it.freinetId.clean()?.toInt(),
+                it.districtName.clean()
             )
         } catch (e: Exception) {
             logger.info("Exception occurred while mapping $it", e)
diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/SanitizeAddress.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/SanitizeAddress.kt
index 38ebed3d..3be42a6c 100644
--- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/SanitizeAddress.kt
+++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/steps/SanitizeAddress.kt
@@ -62,7 +62,7 @@ class SanitizeAddress(private val logger: Logger) : PipelineStep<List<AcceptingS
             // Residue that is neither the street nor the house number, e.g. "im Hauptbahnhof", "Ecke Theaterstraße"
             val residue = if (houseNumberMatch.range.last < address.length - 1) {
                 val res = address.substring(houseNumberMatch.range.last + 1).trim { !it.isLetterOrDigit() }
-                if (res != cleanHouseNumber) res else null
+                if (res != cleanHouseNumber && res.isNotEmpty()) res else null
             } else null
 
             val newAddress = listOfNotNull(cleanStreet, cleanHouseNumber, residue).filterNot { it.isEmpty() }.joinToString("|")
diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/AcceptingStore.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/AcceptingStore.kt
index 3ae4d1f0..36838d29 100644
--- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/AcceptingStore.kt
+++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/AcceptingStore.kt
@@ -15,6 +15,12 @@ data class AcceptingStore(
     val telephone: String?,
     val website: String?,
     val discount: String?,
+
+    // All stores either come from a district directly or from freinet.
+    // In the first case, freinetId is null and districtName is set. In the second case, it is the other way round.
+    val freinetId: Int?,
+    val districtName: String?,
+
     val streetWithHouseNumber: String? =
         if (street != null || houseNumber != null) listOfNotNull(street, houseNumber).joinToString(" ")
         else null
diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/LbeAcceptingStore.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/LbeAcceptingStore.kt
index 4c6a7255..72ee7766 100644
--- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/LbeAcceptingStore.kt
+++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/stores/importer/types/LbeAcceptingStore.kt
@@ -39,5 +39,11 @@ data class LbeAcceptingStore(
         var discount: String?,
         @JsonProperty("kategorie")
         @JacksonXmlCData
-        var category: String?
+        var category: String?,
+        @JsonProperty("p_eak_agentur_id")
+        @JacksonXmlCData
+        var freinetId: String?,
+        @JsonProperty("anbieter_name")
+        @JacksonXmlCData
+        var districtName: String?
 )