RBAC generator with conditional grants used for REPRESENTATIVE-Relation #33
@ -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"))
|
||||
|
@ -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")
|
||||
|
@ -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?
|
||||
|
@ -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$);
|
||||
--//
|
||||
|
@ -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;
|
||||
$$;
|
||||
--//
|
||||
|
@ -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,
|
||||
|
@ -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++);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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-", ""))
|
||||
|
Loading…
Reference in New Issue
Block a user