debitornumbersuffix-as-string #30

Merged
hsh-michaelhoennig merged 9 commits from debitornumbersuffix-as-string into master 2024-04-02 13:09:13 +02:00
11 changed files with 33 additions and 24 deletions

View File

@ -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<HsOfficeDebitorEntity> 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"))

View File

@ -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<HsOfficeMembershipEntity> 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")

View File

@ -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?

View File

@ -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$);
--//

View File

@ -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;
$$;
--//

View File

@ -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,

View File

@ -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++);
}
}

View File

@ -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();

View File

@ -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)

View File

@ -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)

View File

@ -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-", ""))