From 22953ba38efe12cdec09e5e2fce795003aba9622 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sat, 30 Mar 2024 13:25:28 +0100 Subject: [PATCH] debitorNumberSuffix as String --- .../hs/office/debitor/HsOfficeDebitorEntity.java | 11 +++++++---- .../office/membership/HsOfficeMembershipEntity.java | 3 +++ .../506-debitor/5060-hs-office-debitor.sql | 2 +- .../506-debitor/5063-hs-office-debitor-rbac.sql | 2 +- .../5078-hs-office-sepamandate-test-data.sql | 8 ++++---- .../510-membership/5100-hs-office-membership.sql | 3 +-- .../HsOfficeDebitorControllerAcceptanceTest.java | 6 +++++- .../office/debitor/HsOfficeDebitorEntityUnitTest.java | 10 +++++----- .../HsOfficeDebitorRepositoryIntegrationTest.java | 8 ++++---- .../hs/office/debitor/TestHsOfficeDebitor.java | 2 +- .../hs/office/migration/ImportOfficeData.java | 2 +- 11 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java index 1c784078..0a63d0b1 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java @@ -16,6 +16,7 @@ import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; import jakarta.persistence.*; +import jakarta.validation.constraints.Pattern; import java.io.IOException; import java.util.UUID; @@ -45,6 +46,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify; public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { public static final String DEBITOR_NUMBER_TAG = "D-"; + public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; private static Stringify stringify = stringify(HsOfficeDebitorEntity.class, "debitor") @@ -75,8 +77,9 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { @NotFound(action = NotFoundAction.IGNORE) private HsOfficePartnerEntity partner; - @Column(name = "debitornumbersuffix", columnDefinition = "numeric(2)") - private Byte debitorNumberSuffix; // TODO maybe rather as a formatted String? + @Column(name = "debitornumbersuffix", length = 2) + @Pattern(regexp = TWO_DECIMAL_DIGITS) + private String debitorNumberSuffix; @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false) @JoinColumn(name = "debitorreluuid", nullable = false) @@ -109,7 +112,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { .filter(partner -> debitorNumberSuffix != null) .map(HsOfficePartnerEntity::getPartnerNumber) .map(Object::toString) - .map(partnerNumber -> partnerNumber + String.format("%02d", debitorNumberSuffix)) + .map(partnerNumber -> partnerNumber + debitorNumberSuffix) .orElse(null); } @@ -138,7 +141,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { JOIN hs_office_relation debitorRel ON debitorRel.anchorUuid = partnerRel.holderUuid AND debitorRel.type = 'DEBITOR' WHERE debitorRel.uuid = debitor.debitorRelUuid) - || to_char(debitorNumberSuffix, 'fm00') as idName + || debitorNumberSuffix as idName FROM hs_office_debitor AS debitor """)) .withRestrictedViewOrderBy(SQL.projection("defaultPrefix")) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java index f21f5013..668d7cb9 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java @@ -14,6 +14,7 @@ import net.hostsharing.hsadminng.stringify.Stringifyable; import org.hibernate.annotations.Type; import jakarta.persistence.*; +import jakarta.validation.constraints.Pattern; import java.io.IOException; import java.time.LocalDate; import java.util.UUID; @@ -44,6 +45,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify; public class HsOfficeMembershipEntity implements HasUuid, Stringifyable { public static final String MEMBER_NUMBER_TAG = "M-"; + public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; private static Stringify stringify = stringify(HsOfficeMembershipEntity.class) .withProp(e -> MEMBER_NUMBER_TAG + e.getMemberNumber()) @@ -61,6 +63,7 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable { private HsOfficePartnerEntity partner; @Column(name = "membernumbersuffix", length = 2) + @Pattern(regexp = TWO_DECIMAL_DIGITS) private String memberNumberSuffix; @Column(name = "validity", columnDefinition = "daterange") diff --git a/src/main/resources/db/changelog/5-hs-office/506-debitor/5060-hs-office-debitor.sql b/src/main/resources/db/changelog/5-hs-office/506-debitor/5060-hs-office-debitor.sql index e2174eca..59ad01e0 100644 --- a/src/main/resources/db/changelog/5-hs-office/506-debitor/5060-hs-office-debitor.sql +++ b/src/main/resources/db/changelog/5-hs-office/506-debitor/5060-hs-office-debitor.sql @@ -7,7 +7,7 @@ create table hs_office_debitor ( uuid uuid unique references RbacObject (uuid) initially deferred, - debitorNumberSuffix numeric(2) not null, + debitorNumberSuffix char(2) not null check (debitorNumberSuffix::text ~ '^[0-9][0-9]$'), debitorRelUuid uuid not null references hs_office_relation(uuid), billable boolean not null default true, vatId varchar(24), -- TODO.spec: here or in person? diff --git a/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql b/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql index 152f980e..59ac43e8 100644 --- a/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql +++ b/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql @@ -201,7 +201,7 @@ create trigger hs_office_debitor_insert_permission_check_tg JOIN hs_office_relation debitorRel ON debitorRel.anchorUuid = partnerRel.holderUuid AND debitorRel.type = 'DEBITOR' WHERE debitorRel.uuid = debitor.debitorRelUuid) - || to_char(debitorNumberSuffix, 'fm00') as idName + || debitorNumberSuffix as idName FROM hs_office_debitor AS debitor $idName$); --// diff --git a/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5078-hs-office-sepamandate-test-data.sql b/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5078-hs-office-sepamandate-test-data.sql index 69d39165..e664d8c5 100644 --- a/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5078-hs-office-sepamandate-test-data.sql +++ b/src/main/resources/db/changelog/5-hs-office/507-sepamandate/5078-hs-office-sepamandate-test-data.sql @@ -10,7 +10,7 @@ */ create or replace procedure createHsOfficeSepaMandateTestData( forPartnerNumber numeric(5), - forDebitorSuffix numeric(2), + forDebitorSuffix char(2), forIban varchar, withReference varchar) language plpgsql as $$ @@ -48,9 +48,9 @@ end; $$; do language plpgsql $$ begin - call createHsOfficeSepaMandateTestData(10001, 11, 'DE02120300000000202051', 'ref-10001-11'); - call createHsOfficeSepaMandateTestData(10002, 12, 'DE02100500000054540402', 'ref-10002-12'); - call createHsOfficeSepaMandateTestData(10003, 13, 'DE02300209000106531065', 'ref-10003-13'); + call createHsOfficeSepaMandateTestData(10001, '11', 'DE02120300000000202051', 'ref-10001-11'); + call createHsOfficeSepaMandateTestData(10002, '12', 'DE02100500000054540402', 'ref-10002-12'); + call createHsOfficeSepaMandateTestData(10003, '13', 'DE02300209000106531065', 'ref-10003-13'); end; $$; --// diff --git a/src/main/resources/db/changelog/5-hs-office/510-membership/5100-hs-office-membership.sql b/src/main/resources/db/changelog/5-hs-office/510-membership/5100-hs-office-membership.sql index f2a560e2..28ec1249 100644 --- a/src/main/resources/db/changelog/5-hs-office/510-membership/5100-hs-office-membership.sql +++ b/src/main/resources/db/changelog/5-hs-office/510-membership/5100-hs-office-membership.sql @@ -12,8 +12,7 @@ create table if not exists hs_office_membership ( uuid uuid unique references RbacObject (uuid) initially deferred, partnerUuid uuid not null references hs_office_partner(uuid), - memberNumberSuffix char(2) not null check ( - memberNumberSuffix::text ~ '^[0-9][0-9]$'), + memberNumberSuffix char(2) not null check (memberNumberSuffix::text ~ '^[0-9][0-9]$'), validity daterange not null, reasonForTermination HsOfficeReasonForTermination not null default 'NONE', membershipFeeBillable boolean not null default true, diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java index c2e3fffd..07ecb5f5 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java @@ -722,7 +722,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0); final var newDebitor = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix(++nextDebitorSuffix) + .debitorNumberSuffix(nextDebitorSuffix()) .billable(true) .debitorRel( HsOfficeRelationEntity.builder() @@ -751,4 +751,8 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu System.out.printf("deleted %d entities%n", count); }); } + + private String nextDebitorSuffix() { + return String.format("%02d", nextDebitorSuffix++); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java index 3ad1c8ea..cb629b2b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java @@ -26,7 +26,7 @@ class HsOfficeDebitorEntityUnitTest { @Test void toStringContainsPartnerAndContact() { final var given = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte)67) + .debitorNumberSuffix("67") .debitorRel(givenDebitorRel) .defaultPrefix("som") .partner(HsOfficePartnerEntity.builder() @@ -43,7 +43,7 @@ class HsOfficeDebitorEntityUnitTest { void toShortStringContainsDebitorNumber() { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) - .debitorNumberSuffix((byte)67) + .debitorNumberSuffix("67") .partner(HsOfficePartnerEntity.builder() .partnerNumber(12345) .build()) @@ -58,7 +58,7 @@ class HsOfficeDebitorEntityUnitTest { void getDebitorNumberWithPartnerNumberAndDebitorNumberSuffix() { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) - .debitorNumberSuffix((byte)67) + .debitorNumberSuffix("67") .partner(HsOfficePartnerEntity.builder() .partnerNumber(12345) .build()) @@ -73,7 +73,7 @@ class HsOfficeDebitorEntityUnitTest { void getDebitorNumberWithoutPartnerReturnsNull() { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) - .debitorNumberSuffix((byte)67) + .debitorNumberSuffix("67") .partner(null) .build(); @@ -86,7 +86,7 @@ class HsOfficeDebitorEntityUnitTest { void getDebitorNumberWithoutPartnerNumberReturnsNull() { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) - .debitorNumberSuffix((byte)67) + .debitorNumberSuffix("67") .partner(HsOfficePartnerEntity.builder().build()) .build(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java index 7a3dfbb7..32f441af 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java @@ -89,7 +89,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // when final var result = attempt(em, () -> { final var newDebitor = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte)21) + .debitorNumberSuffix("21") .debitorRel(HsOfficeRelationEntity.builder() .type(HsOfficeRelationType.DEBITOR) .anchor(givenPartnerPerson) @@ -121,7 +121,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // when final var result = attempt(em, () -> { final var newDebitor = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte)21) + .debitorNumberSuffix("21") .debitorRel(HsOfficeRelationEntity.builder() .type(HsOfficeRelationType.DEBITOR) .anchor(givenPartnerPerson) @@ -156,7 +156,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean final var givenDebitorPerson = one(personRepo.findPersonByOptionalNameLike("Fourth eG")); final var givenContact = one(contactRepo.findContactByOptionalLabelLike("fourth contact")); final var newDebitor = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte)22) + .debitorNumberSuffix("22") .debitorRel(HsOfficeRelationEntity.builder() .type(HsOfficeRelationType.DEBITOR) .anchor(givenPartnerPerson) @@ -613,7 +613,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean final var givenBankAccount = bankAccountHolder != null ? one(bankAccountRepo.findByOptionalHolderLike(bankAccountHolder)) : null; final var newDebitor = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte)20) + .debitorNumberSuffix("20") .debitorRel(HsOfficeRelationEntity.builder() .type(HsOfficeRelationType.DEBITOR) .anchor(givenPartnerPerson) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java index 2970ea1b..4305b87a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java @@ -10,7 +10,7 @@ import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TE @UtilityClass public class TestHsOfficeDebitor { - public byte DEFAULT_DEBITOR_SUFFIX = 0; + public String DEFAULT_DEBITOR_SUFFIX = "00"; public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder() .debitorNumberSuffix(DEFAULT_DEBITOR_SUFFIX) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java index 4010167d..8da1f12f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java @@ -724,7 +724,7 @@ public class ImportOfficeData extends ContextBasedTest { relations.put(relationId++, debitorRel); final var debitor = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte) 0) + .debitorNumberSuffix("00") .partner(partner) .debitorRel(debitorRel) .defaultPrefix(rec.getString("member_code").replace("hsh00-", ""))