Skip to content

Commit

Permalink
Merge pull request #277 from BRP-API/276-aktenummers-kan-in-sommige-g…
Browse files Browse the repository at this point in the history
…evallen-resulteren-in-een-nullpointer-exceptie

refactoren van aktenummer afleidingen + unit testen toegevoegd
  • Loading branch information
FrozenSync authored Jan 13, 2025
2 parents 00bdf23 + 2a7f731 commit 54cf92e
Show file tree
Hide file tree
Showing 12 changed files with 630 additions and 131 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package nl.rijksoverheid.mev.gezagsmodule.domain;

import java.util.*;

/**
* Functionaliteit voor het afleiden van aktenummers
*/
public class AktenummerAfleiding {

private static final char TABEL_39_AKTEAANDUIDING_ERKENNING_BIJ_DE_GEBOORTE_AANGIFTE = 'B';
private static final char TABEL_39_AKTEAANDUIDING_ONTKENNING_OUDERSCHAP = 'E';
private static final char TABEL_39_AKTEAANDUIDING_ERKENNING_NA_DE_GEBOORTEAANGIFTE = 'C';
private static final char TABEL_39_AKTEAANDUIDING_NOTARIELE_AKTE_VAN_ERKENNING = 'J';
private static final char TABEL_39_AKTEAANDUIDING_ADOPTIE = 'Q';
private static final char TABEL_39_AKTEAANDUIDING_GEBOORTE = 'A';
private static final char TABEL_39_AKTEAANDUIDING_GERECHTELIJKE_VASTSTELLING_OUDERSCHAP = 'V';
private static final Set<Character> erkenningsCodes = new HashSet<>(Arrays.asList(
TABEL_39_AKTEAANDUIDING_ERKENNING_BIJ_DE_GEBOORTE_AANGIFTE,
TABEL_39_AKTEAANDUIDING_ERKENNING_NA_DE_GEBOORTEAANGIFTE,
TABEL_39_AKTEAANDUIDING_NOTARIELE_AKTE_VAN_ERKENNING,
TABEL_39_AKTEAANDUIDING_GERECHTELIJKE_VASTSTELLING_OUDERSCHAP));

private static final int AKTE_NUMMER_LENGTE = 3;

private AktenummerAfleiding() {
}

/**
* Valideer of de persoon erkend is / een persoon heeft erkend.
* Dit is af te lezen uit het aktenummer actueel en historisch.
* Waarbij zowel op de persoon als bij de ouders als 3e karakter de indicatie staat opgenomen.
* <p>
* Indicaties:
* <ul>
* <li>Erkenning bij geboorte aangifte: B</li>
* <li>Erkenning na geboorte aangifte: C</li>
* <li>Erkenning middels notariele akte: J</li>
* <li>Erkenning middels gerechtelijke vaststelleing: V</li>
* </ul>
*
* @param current de huidige gegevens
* @param historic de historische gegevens
* @return of de gegeven persoon is / heeft erkend
*/
public static boolean ongeborenVruchtErkendOfGerechtelijkeVaststelling(final WithAktenummer current, final List<WithAktenummer> historic) {
return controleerAkteNummers(current, historic, erkenningsCodes);
}

/**
* Bepaal of de gegeven persoon (een ouder) de erkenning heeft ontkend.
* Hierbij is als 3e karakter de indicatie opgenomen: E
*
* @param current de huidige gegevens
* @param historic de historische gegevens
* @return of de gegeven persoon heeft ontkend
*/
public static boolean ontkenningOuderschapDoorOuder(final WithAktenummer current, final List<WithAktenummer> historic) {
return controleerAkteNummers(current, historic, Set.of(TABEL_39_AKTEAANDUIDING_ONTKENNING_OUDERSCHAP));
}

/**
* Bepaal of de gegeven persoon als ongeboren vrucht is erkend.
* Hierbij is als 3e karakter de indicatie opgenomen: A
*
* @param current de huidige gegevens
* @param historic de historische gegevens
* @return of de gegeven persoon als ongeboren vrucht is erkend
*/
public static boolean ongeborenVruchtErkend(final WithAktenummer current, final List<WithAktenummer> historic) {
return controleerAkteNummers(current, historic, Set.of(TABEL_39_AKTEAANDUIDING_GEBOORTE));
}

/**
* Bepaal of de gegeven persoon is geadopteerd.
* Hierbij is als 3e karakter de indicatie opgenomen: Q
*
* @param current de huidige gegevens
* @param historic de historische gegevens
* @return of de gegeven persoon is geadopteerd
*/
public static boolean geadopteerdMetNlAkte(final WithAktenummer current, final List<WithAktenummer> historic) {
return controleerAkteNummers(current, historic, Set.of(TABEL_39_AKTEAANDUIDING_ADOPTIE));
}

private static boolean controleerAkteNummers(final WithAktenummer current, final List<WithAktenummer> historic, final Set<Character> geldigeErkenningCodes) {
if (geldigeErkenningCodes != null) {
List<String> akteNummers = new ArrayList<>();
if (current != null) {
akteNummers.add(current.getAktenummer());
}
if (historic != null) {
akteNummers.addAll(historic.stream().map(WithAktenummer::getAktenummer).toList());
}

return akteNummers.stream()
.filter(aktenummer -> aktenummer != null && aktenummer.length() >= AKTE_NUMMER_LENGTE)
.anyMatch(aktenummer -> geldigeErkenningCodes.contains(aktenummer.charAt(2)));
} else {
return false;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Geschiedenis persoon
*/
@Categorie(number = "52", name = "ouder 1 (historie)")
public class GeschiedenisOuder1 extends PotentieelInOnderzoek {
public class GeschiedenisOuder1 extends PotentieelInOnderzoek implements WithAktenummer {

@VeldNummer(number = "528120", name = "aktenummer van ouder 1 (historie)")
private final String aktenummer;
Expand All @@ -23,6 +23,7 @@ public GeschiedenisOuder1(final Lo3PlPersoonRecord lo3PlPersoonRecord) {
datumEindeOnderzoek = Objects.toString(lo3PlPersoonRecord.getOnderzoekEindDatum(), null);
}

@Override
public String getAktenummer() {
registerIfInOnderzoek("aktenummer", getClass());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Geschiedenis persoon
*/
@Categorie(number = "53", name = "ouder 2 (historie)")
public class GeschiedenisOuder2 extends PotentieelInOnderzoek {
public class GeschiedenisOuder2 extends PotentieelInOnderzoek implements WithAktenummer {

@VeldNummer(number = "538120", name = "aktenummer van ouder 2")
private final String aktenummer;
Expand All @@ -23,6 +23,7 @@ public GeschiedenisOuder2(final Lo3PlPersoonRecord lo3PlPersoonRecord) {
datumEindeOnderzoek = Objects.toString(lo3PlPersoonRecord.getOnderzoekEindDatum(), null);
}

@Override
public String getAktenummer() {
registerIfInOnderzoek("aktenummer", getClass());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Geschiedenis persoon
*/
@Categorie(number = "51", name = "persoon (historie)")
public class GeschiedenisPersoon extends PotentieelInOnderzoek {
public class GeschiedenisPersoon extends PotentieelInOnderzoek implements WithAktenummer {

@VeldNummer(number = "518120", name = "aktenummer van persoon (historie)")
private final String aktenummer;
Expand All @@ -23,6 +23,7 @@ public GeschiedenisPersoon(final Lo3PlPersoonRecord lo3PlPersoonRecord) {
datumEindeOnderzoek = Objects.toString(lo3PlPersoonRecord.getOnderzoekEindDatum(), null);
}

@Override
public String getAktenummer() {
registerIfInOnderzoek("aktenummer", getClass());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Ouder1 voor persoon
*/
@Categorie(number = "02", name = "ouder 1")
public class Ouder1 extends PotentieelInOnderzoek {
public class Ouder1 extends PotentieelInOnderzoek implements WithAktenummer {

@VeldNummer(number = "020120", name = "burgerservicenummer van ouder 1")
private final String burgerservicenummer;
Expand Down Expand Up @@ -54,6 +54,7 @@ public String getDatumIngangFamiliebetrekking() {
return datumIngangFamilieBetrekking;
}

@Override
public String getAktenummer() {
registerIfInOnderzoek("aktenummer", getClass());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Ouder2 voor persoon
*/
@Categorie(number = "03", name = "ouder 2")
public class Ouder2 extends PotentieelInOnderzoek {
public class Ouder2 extends PotentieelInOnderzoek implements WithAktenummer {

@VeldNummer(number = "030120", name = "burgerservicenummer van ouder 2")
private final String burgerservicenummer;
Expand Down Expand Up @@ -54,6 +54,7 @@ public String getDatumIngangFamiliebetrekking() {
return datumIngangFamilieBetrekking;
}

@Override
public String getAktenummer() {
registerIfInOnderzoek("aktenummer", getClass());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Persoon (vanuit persoonslijst zoals opgenomen in de BRP)
*/
@Categorie(number = "01", name = "persoon")
public class Persoon extends PotentieelInOnderzoek {
public class Persoon extends PotentieelInOnderzoek implements WithAktenummer {

@VeldNummer(number = "010120", name = "burgerservicenummer van persoon")
private final String burgerservicenummer;
Expand Down Expand Up @@ -53,6 +53,7 @@ public String getGeboorteland() {
return geboorteland;
}

@Override
public String getAktenummer() {
registerIfInOnderzoek("aktenummer", getClass());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,12 @@
public class Persoonslijst {

private static final int MEERDERJARIGE_LEEFTIJD = 180000;
private static final int AKTE_NUMMER_LENGTE = 3;
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
private static final String GEEN_OUDERS = "Geen_ouders";
private static final String EEN_OUDER = "Een_ouder";
private static final String TWEE_OUDERS = "Twee_ouders";
private static final String GESLACHTNAAM_AANDUIDING_PUNTOUDER = ".";
private static final String PUNTOUDERS = "1_of_2_puntouders";
private static final char TABEL_39_AKTEAANDUIDING_ERKENNING_BIJ_DE_GEBOORTE_AANGIFTE = 'B';
private static final char TABEL_39_AKTEAANDUIDING_ONTKENNING_OUDERSCHAP = 'E'; // Rechtelijke uitspraak
private static final char TABEL_39_AKTEAANDUIDING_ERKENNING_NA_DE_GEBOORTEAANGIFTE = 'C';
private static final char TABEL_39_AKTEAANDUIDING_NOTARIELE_AKTE_VAN_ERKENNING = 'J';
private static final char TABEL_39_AKTEAANDUIDING_ADOPTIE = 'Q';
private static final char TABEL_39_AKTEAANDUIDING_GEBOORTE = 'A';
private static final char TABEL_39_AKTEAANDUIDING_GERECHTELIJKE_VASTSTELLING_OUDERSCHAP = 'V';
private static final String PUNTOUDER_INDICATIE = ".";
private static final List<String> INDICATIE_GEZAG_CODES = Arrays.asList("1", "2", "12", "1D", "2D", "D");

Expand Down Expand Up @@ -227,126 +219,41 @@ public static boolean isValideGeslachtsnaam(String str) {
return str != null && !str.isBlank() && !str.equals(PUNTOUDER_INDICATIE);
}

/**
* Controleert een lijst van aktenummers op geldige erkenningscodes.
*
* @param akteNummers Een lijst van String objecten die de te controleren aktenummers bevat.
* Elk aktenummer moet minimaal {@value #AKTE_NUMMER_LENGTE} tekens lang zijn.
* @param geldigeErkenningCodes Een Set van Character objecten die de geldige erkenningscodes bevat.
* Deze codes worden vergeleken met het derde teken van elk aktenummer.
* @return {@code true} als er minstens één aktenummer is gevonden met een geldige erkenningscode,
* {@code false} als er geen enkel aktenummer met een geldige erkenningscode is gevonden.
* @throws NullPointerException als {@code akteNummers} of {@code geldigeErkenningCodes} null is.
*/
public static boolean controleerAkteNummers(List<String> akteNummers, Set<Character> geldigeErkenningCodes) {
return akteNummers.stream()
.filter(aktenummer -> aktenummer != null && aktenummer.length() >= AKTE_NUMMER_LENGTE)
.anyMatch(aktenummer -> geldigeErkenningCodes.contains(aktenummer.charAt(2)));
}

public boolean ongeborenVruchtErkendOfGerechtelijkeVaststelling() {
// controleer dan persoon op akte erkenning actueel en geschiedenis op B, C, J en V
// voorbereiding, zet alle aktenummers in een lijst
List<String> akteNummers = new ArrayList<>();
akteNummers.add(persoon.getAktenummer());
if (geschiedenisPersoon != null) {
for (GeschiedenisPersoon p : geschiedenisPersoon) {
akteNummers.add(p.getAktenummer());
}
}
Set<Character> geldigeErkenningCodes = new HashSet<>(Arrays.asList(
TABEL_39_AKTEAANDUIDING_ERKENNING_BIJ_DE_GEBOORTE_AANGIFTE,
TABEL_39_AKTEAANDUIDING_ERKENNING_NA_DE_GEBOORTEAANGIFTE,
TABEL_39_AKTEAANDUIDING_NOTARIELE_AKTE_VAN_ERKENNING,
TABEL_39_AKTEAANDUIDING_GERECHTELIJKE_VASTSTELLING_OUDERSCHAP));
// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(akteNummers, geldigeErkenningCodes);
return AktenummerAfleiding
.ongeborenVruchtErkendOfGerechtelijkeVaststelling(persoon, new ArrayList<>(geschiedenisPersoon));
}


public boolean ongeborenVruchtDoorOuder1ErkendOfGerechtelijkeVaststelling() {
// controleer dan op akte erkenning actueel en geschiedenis op B, C, J en V
// voorbereiding, zet alle aktenummers in een lijst
List<String> akteNummers = new ArrayList<>();
akteNummers.add(ouder1.getAktenummer());
if (geschiedenisOuder1 != null) {
for (GeschiedenisOuder1 p : geschiedenisOuder1) {
akteNummers.add(p.getAktenummer());
}
}
Set<Character> geldigeErkenningCodes = new HashSet<>(Arrays.asList(
TABEL_39_AKTEAANDUIDING_ERKENNING_BIJ_DE_GEBOORTE_AANGIFTE,
TABEL_39_AKTEAANDUIDING_ERKENNING_NA_DE_GEBOORTEAANGIFTE,
TABEL_39_AKTEAANDUIDING_NOTARIELE_AKTE_VAN_ERKENNING,
TABEL_39_AKTEAANDUIDING_GERECHTELIJKE_VASTSTELLING_OUDERSCHAP));
// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(akteNummers, geldigeErkenningCodes);
return AktenummerAfleiding
.ongeborenVruchtErkendOfGerechtelijkeVaststelling(ouder1, new ArrayList<>(geschiedenisOuder1));
}

public boolean ongeborenVruchtDoorOuder2ErkendOfGerechtelijkeVaststelling() {
return AktenummerAfleiding
.ongeborenVruchtErkendOfGerechtelijkeVaststelling(ouder2, new ArrayList<>(geschiedenisOuder2));
}


public boolean ontkenningOuderschapDoorOuder1() {
// controleer dan op akte erkenning actueel en geschiedenis op E
// voorbereiding, zet alle aktenummers in een lijst
List<String> akteNummers = new ArrayList<>();
akteNummers.add(ouder1.getAktenummer());
if (geschiedenisOuder1 != null) {
for (GeschiedenisOuder1 p : geschiedenisOuder1) {
akteNummers.add(p.getAktenummer());
}
}
Set<Character> geldigeErkenningCodes = new HashSet<>(List.of(
TABEL_39_AKTEAANDUIDING_ONTKENNING_OUDERSCHAP));
// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(akteNummers, geldigeErkenningCodes);
return AktenummerAfleiding
.ontkenningOuderschapDoorOuder(ouder1, new ArrayList<>(geschiedenisOuder1));
}

public boolean ontkenningOuderschapDoorOuder2() {
// controleer dan op akte erkenning actueel en geschiedenis op E
// voorbereiding, zet alle aktenummers in een lijst
List<String> akteNummers = new ArrayList<>();
if (ouder2 != null) {
akteNummers.add(ouder2.getAktenummer());
for (GeschiedenisOuder2 p : geschiedenisOuder2) {
akteNummers.add(p.getAktenummer());
}
}
// controleer de lijst op de erkenningscodes uit de publieke tabel 39
Set<Character> geldigeErkenningCodes = new HashSet<>(List.of(
TABEL_39_AKTEAANDUIDING_ONTKENNING_OUDERSCHAP));
// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(akteNummers, geldigeErkenningCodes);
return AktenummerAfleiding
.ontkenningOuderschapDoorOuder(ouder2, new ArrayList<>(geschiedenisOuder2));
}

public boolean ongeborenVruchtErkend() {
// controleer dan persoon op akte erkenning actueel en geschiedenis op A
// voorbereiding, zet alle aktenummers in een lijst
var aktenummers = Stream.concat(
Stream.of(persoon.getAktenummer()),
geschiedenisPersoon.stream().map(GeschiedenisPersoon::getAktenummer)
).toList();
var geldigeErkenningCodes = Set.of(TABEL_39_AKTEAANDUIDING_GEBOORTE);

// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(aktenummers, geldigeErkenningCodes);
return AktenummerAfleiding
.ongeborenVruchtErkend(persoon, new ArrayList<>(geschiedenisPersoon));
}


public boolean ongeborenVruchtDoorOuder2ErkendOfGerechtelijkeVaststelling() {
// controleer dan op akte erkenning actueel en geschiedenis op B, C, J en V
// voorbereiding, zet alle aktenummers in een lijst
List<String> akteNummers = new ArrayList<>();
akteNummers.add(ouder2.getAktenummer());
if (geschiedenisOuder2 != null) {
for (GeschiedenisOuder2 p : geschiedenisOuder2) {
akteNummers.add(p.getAktenummer());
}
}
Set<Character> geldigeErkenningCodes = new HashSet<>(Arrays.asList(
TABEL_39_AKTEAANDUIDING_ERKENNING_BIJ_DE_GEBOORTE_AANGIFTE,
TABEL_39_AKTEAANDUIDING_ERKENNING_NA_DE_GEBOORTEAANGIFTE,
TABEL_39_AKTEAANDUIDING_NOTARIELE_AKTE_VAN_ERKENNING,
TABEL_39_AKTEAANDUIDING_GERECHTELIJKE_VASTSTELLING_OUDERSCHAP));
// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(akteNummers, geldigeErkenningCodes);
public boolean geadopteerdMetNlAkte() {
return AktenummerAfleiding
.geadopteerdMetNlAkte(persoon, new ArrayList<>(geschiedenisPersoon));
}

public boolean beideOudersHebbenEenBSN() {
Expand Down Expand Up @@ -391,18 +298,6 @@ public boolean adoptieNaIngangGeldigheidsdatum() {
return ouder1AdoptieNa || ouder2AdoptieNa;
}

public boolean geadopteerdMetNlAkte() {
var aktenummers = Stream.concat(
Stream.of(persoon.getAktenummer()),
geschiedenisPersoon.stream().map(GeschiedenisPersoon::getAktenummer)
).toList();

var geldigeErkenningCodes = Set.of(TABEL_39_AKTEAANDUIDING_ADOPTIE);

// controleer de lijst op de erkenningscodes uit de publieke tabel 39
return controleerAkteNummers(aktenummers, geldigeErkenningCodes);
}

public boolean heefIndicatieGezag() {
return gezagsverhouding != null
&& INDICATIE_GEZAG_CODES.contains(gezagsverhouding.getIndicatieGezagMinderjarige());
Expand Down
Loading

0 comments on commit 54cf92e

Please sign in to comment.