From fb974a3b438528c61ff6843931a921f57c405dd3 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 24 Jan 2024 15:57:16 +0100 Subject: [PATCH] memberNumber as partnerNumber+memberNumberSuffix (#13) Co-authored-by: Michael Hoennig Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/13 Reviewed-by: Michael Hierweck --- .aliases | 1 + .../HsOfficeCoopAssetsTransactionEntity.java | 15 +- ...OfficeCoopAssetsTransactionRepository.java | 2 +- .../HsOfficeCoopAssetsTransactionType.java | 47 ++- .../HsOfficeCoopSharesTransactionEntity.java | 17 +- ...OfficeCoopSharesTransactionRepository.java | 2 +- .../HsOfficeCoopSharesTransactionType.java | 17 +- .../office/debitor/HsOfficeDebitorEntity.java | 21 +- .../debitor/HsOfficeDebitorRepository.java | 4 +- .../HsOfficeMembershipController.java | 5 +- .../membership/HsOfficeMembershipEntity.java | 19 +- .../HsOfficeMembershipRepository.java | 29 +- .../office/partner/HsOfficePartnerEntity.java | 4 +- .../partner/HsOfficePartnerRepository.java | 1 + .../hs-office-membership-schemas.yaml | 15 +- .../hs-office/hs-office-memberships.yaml | 7 +- .../hs-office/hs-office-partner-schemas.yaml | 6 +- .../db/changelog/220-hs-office-partner.sql | 2 +- .../changelog/223-hs-office-partner-rbac.sql | 4 +- .../228-hs-office-partner-test-data.sql | 6 +- .../changelog/273-hs-office-debitor-rbac.sql | 2 +- .../db/changelog/300-hs-office-membership.sql | 7 +- .../303-hs-office-membership-rbac.sql | 6 +- .../308-hs-office-membership-test-data.sql | 32 +- .../318-hs-office-coopshares-test-data.sql | 28 +- .../328-hs-office-coopassets-test-data.sql | 28 +- ...tsTransactionControllerAcceptanceTest.java | 22 +- ...ceCoopAssetsTransactionEntityUnitTest.java | 6 +- ...sTransactionRepositoryIntegrationTest.java | 51 ++-- ...esTransactionControllerAcceptanceTest.java | 21 +- ...ceCoopSharesTransactionEntityUnitTest.java | 6 +- ...sTransactionRepositoryIntegrationTest.java | 51 ++-- .../HsOfficeDebitorEntityUnitTest.java | 66 ++++- ...fficeDebitorRepositoryIntegrationTest.java | 14 +- ...iceMembershipControllerAcceptanceTest.java | 127 +++++--- .../HsOfficeMembershipControllerRestTest.java | 273 +++++++++++------- .../HsOfficeMembershipEntityUnitTest.java | 43 ++- ...ceMembershipRepositoryIntegrationTest.java | 78 ++--- .../office/membership/TestHsMembership.java | 2 +- .../hs/office/migration/ImportOfficeData.java | 39 +-- ...OfficePartnerControllerAcceptanceTest.java | 8 +- ...fficePartnerRepositoryIntegrationTest.java | 25 +- .../office/partner/TestHsOfficePartner.java | 2 +- .../HsOfficePersonTypeConverterUnitTest.java | 10 + .../HsOfficeRelationshipEntityUnitTest.java | 32 ++ ...ceSepaMandateControllerAcceptanceTest.java | 4 +- .../RbacUserControllerAcceptanceTest.java | 5 - 47 files changed, 789 insertions(+), 423 deletions(-) create mode 100644 src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityUnitTest.java diff --git a/.aliases b/.aliases index c0b4e22d..f6673bcd 100644 --- a/.aliases +++ b/.aliases @@ -80,3 +80,4 @@ alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l' alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResources' alias gw-test='. .aliases; ./gradlew test' +alias gw-check='. .aliases; gw check -x pitest -x :dependencyCheckAnalyze' diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java index 69e26183..e91bc8bd 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java @@ -53,12 +53,25 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, HasUu @Column(name = "valuedate") private LocalDate valueDate; + /** + * The signed value which directly affects the booking balance. + * + *

This means, that a DEPOSIT is always positive, a DISBURSAL is always negative, + * but an ADJUSTMENT can bei either positive or negative. + * See {@link HsOfficeCoopAssetsTransactionType} for

more information. + */ @Column(name = "assetvalue") private BigDecimal assetValue; + /** + * The booking reference. + */ @Column(name = "reference") - private String reference; // TODO: what is this for? + private String reference; + /** + * An optional arbitrary comment. + */ @Column(name = "comment") private String comment; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepository.java index 256933b9..c606f476 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepository.java @@ -17,7 +17,7 @@ public interface HsOfficeCoopAssetsTransactionRepository extends Repository= :fromValueDate)) AND ( CAST(:toValueDate AS java.time.LocalDate)IS NULL OR (at.valueDate <= :toValueDate)) - ORDER BY at.membership.memberNumber, at.valueDate + ORDER BY at.membership.memberNumberSuffix, at.valueDate """) List findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange( UUID membershipUuid, LocalDate fromValueDate, LocalDate toValueDate); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionType.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionType.java index 2245f864..d7397622 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionType.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionType.java @@ -1,12 +1,43 @@ package net.hostsharing.hsadminng.hs.office.coopassets; public enum HsOfficeCoopAssetsTransactionType { - ADJUSTMENT, // correction of wrong bookings - DEPOSIT, // payment received from member after signing shares, >0 - DISBURSAL, // payment send to member after cancellation of shares, <0 - TRANSFER, // transferring shares to another member, <0 - ADOPTION, // receiving shares from another member, >0 - CLEARING, // settlement with members dept, <0 - LOSS, // assignment of balance sheet loss in case of cancellation of shares, <0 - LIMITATION // limitation period was reached after impossible disbursal, <0 + /** + * correction of wrong bookings, value can be positive or negative + */ + ADJUSTMENT, + + /** + * payment received from member after signing shares, value >0 + */ + DEPOSIT, + + /** + * payment send to member after cancellation of shares, value <0 + */ + DISBURSAL, + + /** + * transferring shares to another member, value <0 + */ + TRANSFER, + + /** + * receiving shares from another member, value >0 + */ + ADOPTION, + + /** + * settlement with members dept, value <0 + */ + CLEARING, + + /** + * assignment of balance sheet loss in case of cancellation of shares, value <0 + */ + LOSS, + + /** + * limitation period was reached after impossible disbursal, value <0 + */ + LIMITATION } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java index 6c47bbb8..f6a05bc4 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java @@ -46,15 +46,28 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUu @Enumerated(EnumType.STRING) private HsOfficeCoopSharesTransactionType transactionType; + /** + * The signed value which directly affects the booking balance. + * + *

This means, that a SUBSCRIPTION is always positive, a CANCELLATION is always negative, + * but an ADJUSTMENT can bei either positive or negative. + * See {@link HsOfficeCoopSharesTransactionType} for

more information. + */ @Column(name = "valuedate") private LocalDate valueDate; @Column(name = "sharecount") private int shareCount; + /** + * The Booking reference. + */ @Column(name = "reference") - private String reference; // TODO: what is this for? + private String reference; + /** + * An optional arbitrary comment. + */ @Column(name = "comment") private String comment; @@ -69,6 +82,6 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUu @Override public String toShortString() { - return "%s%+d".formatted(getMemberNumber(), shareCount); + return "M-%s%+d".formatted(getMemberNumber(), shareCount); } } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepository.java index 2e52b828..5c3e0af6 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepository.java @@ -17,7 +17,7 @@ public interface HsOfficeCoopSharesTransactionRepository extends Repository= :fromValueDate)) AND ( CAST(:toValueDate AS java.time.LocalDate)IS NULL OR (st.valueDate <= :toValueDate)) - ORDER BY st.membership.memberNumber, st.valueDate + ORDER BY st.membership.memberNumberSuffix, st.valueDate """) List findCoopSharesTransactionByOptionalMembershipUuidAndDateRange( UUID membershipUuid, LocalDate fromValueDate, LocalDate toValueDate); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionType.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionType.java index e18451f5..bcd46cb3 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionType.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionType.java @@ -1,7 +1,18 @@ package net.hostsharing.hsadminng.hs.office.coopshares; public enum HsOfficeCoopSharesTransactionType { - ADJUSTMENT, // correction of wrong bookings - SUBSCRIPTION, // shares signed, e.g. with the declaration of accession, >0 - CANCELLATION; // shares terminated, e.g. when a membership is resigned, <0 + /** + * correction of wrong bookings, with either positive or negative value + */ + ADJUSTMENT, + + /** + * shares signed, e.g. with the declaration of accession, value >0 + */ + SUBSCRIPTION, + + /** + * shares terminated, e.g. when a membership is resigned, value <0 + */ + CANCELLATION; } 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 332ea8dd..279f1d63 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 @@ -26,12 +26,14 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify; @DisplayName("Debitor") public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { + public static final String DEBITOR_NUMBER_TAG = "D-"; + // TODO: I would rather like to generate something matching this example: // debitor(1234500: Test AG, tes) // maybe remove withSepararator (always use ', ') and add withBusinessIdProp (with ': ' afterwards)? private static Stringify stringify = stringify(HsOfficeDebitorEntity.class, "debitor") - .withProp(HsOfficeDebitorEntity::getDebitorNumber) + .withProp(e -> DEBITOR_NUMBER_TAG + e.getDebitorNumber()) .withProp(HsOfficeDebitorEntity::getPartner) .withProp(HsOfficeDebitorEntity::getDefaultPrefix) .withSeparator(": ") @@ -75,18 +77,11 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { @Column(name = "defaultprefix", columnDefinition = "char(3) not null") private String defaultPrefix; - public String getDebitorNumberString() { - // TODO: refactor - if (partner.getDebitorNumberPrefix() == null ) { - if (debitorNumberSuffix == null) { - return null; - } - return String.format("%02d", debitorNumberSuffix); + private String getDebitorNumberString() { + if (partner == null || partner.getPartnerNumber() == null || debitorNumberSuffix == null ) { + return null; } - if (debitorNumberSuffix == null) { - return partner.getDebitorNumberPrefix() + "??"; - } - return partner.getDebitorNumberPrefix() + String.format("%02d", debitorNumberSuffix); + return partner.getPartnerNumber() + String.format("%02d", debitorNumberSuffix); } public Integer getDebitorNumber() { @@ -100,6 +95,6 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { @Override public String toShortString() { - return getDebitorNumberString(); + return DEBITOR_NUMBER_TAG + getDebitorNumberString(); } } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java index 5ca04719..64be98b1 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java @@ -13,10 +13,10 @@ public interface HsOfficeDebitorRepository extends Repository findDebitorByDebitorNumber(int debitorNumberPrefix, byte debitorNumberSuffix); + List findDebitorByDebitorNumber(int partnerNumber, byte debitorNumberSuffix); default List findDebitorByDebitorNumber(int debitorNumber) { return findDebitorByDebitorNumber( debitorNumber/100, (byte) (debitorNumber%100)); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java index 3553f616..e18fc183 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java @@ -44,8 +44,9 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { Integer memberNumber) { context.define(currentUser, assumedRoles); - final var entities = - membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(partnerUuid, memberNumber); + final var entities = ( memberNumber != null) + ? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber)) + : membershipRepo.findMembershipsByOptionalPartnerUuid(partnerUuid); final var resources = mapper.mapList(entities, HsOfficeMembershipResource.class, SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER); 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 b5846324..355b79a9 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 @@ -30,8 +30,10 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify; @DisplayName("Membership") public class HsOfficeMembershipEntity implements HasUuid, Stringifyable { + public static final String MEMBER_NUMBER_TAG = "M-"; + private static Stringify stringify = stringify(HsOfficeMembershipEntity.class) - .withProp(HsOfficeMembershipEntity::getMemberNumber) + .withProp(e -> MEMBER_NUMBER_TAG + e.getMemberNumber()) .withProp(e -> e.getPartner().toShortString()) .withProp(e -> e.getMainDebitor().toShortString()) .withProp(e -> e.getValidity().asString()) @@ -52,8 +54,8 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable { @JoinColumn(name = "maindebitoruuid") private HsOfficeDebitorEntity mainDebitor; - @Column(name = "membernumber") - private int memberNumber; // TODO: migrate to suffix, like debitorNumberSuffix + @Column(name = "membernumbersuffix", length = 2) + private String memberNumberSuffix; @Column(name = "validity", columnDefinition = "daterange") @Type(PostgreSQLRangeType.class) @@ -82,14 +84,19 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable { return upperInclusiveFromPostgresDateRange(getValidity()); } - public Range getValidity() { if (validity == null) { validity = Range.infinite(LocalDate.class); } - ; return validity; } + public Integer getMemberNumber() { + if (partner == null || partner.getPartnerNumber() == null || memberNumberSuffix == null ) { + return null; + } + + return getPartner().getPartnerNumber() * 100 + Integer.parseInt(memberNumberSuffix, 10); + } @Override public String toString() { @@ -98,7 +105,7 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable { @Override public String toShortString() { - return String.valueOf(memberNumber); + return "M-" + getMemberNumber(); } @PrePersist diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepository.java index 972c00ce..c61a863e 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepository.java @@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -11,16 +12,30 @@ public interface HsOfficeMembershipRepository extends Repository findByUuid(UUID id); + HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity); + + @Query(""" SELECT membership FROM HsOfficeMembershipEntity membership - WHERE (:memberNumber is null OR membership.memberNumber = :memberNumber) - AND ( CAST(:partnerUuid as org.hibernate.type.UUIDCharType) IS NULL - OR membership.partner.uuid = :partnerUuid ) - ORDER BY membership.memberNumber + WHERE ( CAST(:partnerUuid as org.hibernate.type.UUIDCharType) IS NULL + OR membership.partner.uuid = :partnerUuid ) + ORDER BY membership.partner.partnerNumber, membership.memberNumberSuffix """) - List findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(UUID partnerUuid, Integer memberNumber); - - HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity); + List findMembershipsByOptionalPartnerUuid(UUID partnerUuid); + @Query(""" + SELECT membership FROM HsOfficeMembershipEntity membership + WHERE (:partnerNumber = membership.partner.partnerNumber) + AND (membership.memberNumberSuffix = :suffix) + ORDER BY membership.memberNumberSuffix + """) + HsOfficeMembershipEntity findMembershipByPartnerNumberAndSuffix( + @NotNull Integer partnerNumber, + @NotNull String suffix); + default HsOfficeMembershipEntity findMembershipByMemberNumber(Integer memberNumber) { + final var partnerNumber = memberNumber / 100; + final var suffix = memberNumber % 100; + return findMembershipByPartnerNumberAndSuffix(partnerNumber, String.format("%02d", suffix)); + } long count(); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java index 95a30290..850b94db 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java @@ -36,8 +36,8 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid { @GeneratedValue private UUID uuid; - @Column(name = "debitornumberprefix", columnDefinition = "numeric(5) not null") - private Integer debitorNumberPrefix; + @Column(name = "partnernumber", columnDefinition = "numeric(5) not null") + private Integer partnerNumber; @ManyToOne @JoinColumn(name = "personuuid", nullable = false) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java index 6c7a158c..dfbd1667 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java @@ -23,6 +23,7 @@ public interface HsOfficePartnerRepository extends Repository findPartnerByOptionalNameLike(String name); + HsOfficePartnerEntity findPartnerByPartnerNumber(Integer partnerNumber); HsOfficePartnerEntity save(final HsOfficePartnerEntity entity); diff --git a/src/main/resources/api-definition/hs-office/hs-office-membership-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-membership-schemas.yaml index 74c8143b..163f6f34 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-membership-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-membership-schemas.yaml @@ -25,6 +25,13 @@ components: $ref: './hs-office-debitor-schemas.yaml#/components/schemas/HsOfficeDebitor' memberNumber: type: integer + minimum: 1000000 + maximum: 9999999 + memberNumberSuffix: + type: string + minLength: 2 + maxLength: 2 + pattern: '[0-9]+' validFrom: type: string format: date @@ -66,8 +73,11 @@ components: type: string format: uuid nullable: false - memberNumber: - type: integer + memberNumberSuffix: + type: string + minLength: 2 + maxLength: 2 + pattern: '[0-9]+' nullable: false validFrom: type: string @@ -84,6 +94,7 @@ components: type: boolean required: - partnerUuid + - memberNumberSuffix - mainDebitorUuid - validFrom - membershipFeeBillable diff --git a/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml b/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml index d4d60158..3833752b 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml @@ -1,6 +1,7 @@ get: summary: Returns a list of (optionally filtered) memberships. - description: Returns the list of (optionally filtered) memberships which are visible to the current user or any of it's assumed roles. + description: Returns the list of memberships which are visible to the current user or any of it's assumed roles. + The list can optionally be filtered by either the `partnerUuid` or the `memberNumber` - not both at the same time. tags: - hs-office-memberships operationId: listMemberships @@ -13,13 +14,13 @@ get: schema: type: string format: uuid - description: UUID of the business partner. + description: UUID of the business partner, exclusive to `memberNumber`. - name: memberNumber in: query required: false schema: type: integer - description: Member number. + description: Member number, exclusive to `partnerUuid`. responses: "200": description: OK diff --git a/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml index 6b044a27..a6a94f67 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml @@ -9,7 +9,7 @@ components: uuid: type: string format: uuid - debitorNumberPrefix: + partnerNumber: type: integer format: int8 minimum: 10000 @@ -91,7 +91,7 @@ components: HsOfficePartnerInsert: type: object properties: - debitorNumberPrefix: + partnerNumber: type: integer format: int8 minimum: 10000 @@ -105,7 +105,7 @@ components: details: $ref: '#/components/schemas/HsOfficePartnerDetailsInsert' required: - - debitorNumberPrefix + - partnerNumber - personUuid - contactUuid - details diff --git a/src/main/resources/db/changelog/220-hs-office-partner.sql b/src/main/resources/db/changelog/220-hs-office-partner.sql index 340c0455..c4491b0a 100644 --- a/src/main/resources/db/changelog/220-hs-office-partner.sql +++ b/src/main/resources/db/changelog/220-hs-office-partner.sql @@ -32,7 +32,7 @@ call create_journal('hs_office_partner_details'); create table hs_office_partner ( uuid uuid unique references RbacObject (uuid) initially deferred, - debitorNumberPrefix varchar(5), + partnerNumber numeric(5), personUuid uuid not null references hs_office_person(uuid), contactUuid uuid not null references hs_office_contact(uuid), detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade diff --git a/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql b/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql index db5db365..5757efc9 100644 --- a/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql +++ b/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql @@ -165,8 +165,7 @@ execute procedure hsOfficePartnerRbacRolesTrigger(); --changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- call generateRbacIdentityView('hs_office_partner', $idName$ - -- TODO: simplify by using just debitorNumberPrefix for the essential part - debitorNumberPrefix || ':' || + partnerNumber || ':' || (select idName from hs_office_person_iv p where p.uuid = target.personuuid) || '-' || (select idName from hs_office_contact_iv c where c.uuid = target.contactuuid) @@ -180,7 +179,6 @@ call generateRbacIdentityView('hs_office_partner', $idName$ call generateRbacRestrictedView('hs_office_partner', '(select idName from hs_office_person_iv p where p.uuid = target.personUuid)', $updates$ - debitorNumberPrefix = new.debitorNumberPrefix, personUuid = new.personUuid, contactUuid = new.contactUuid $updates$); diff --git a/src/main/resources/db/changelog/228-hs-office-partner-test-data.sql b/src/main/resources/db/changelog/228-hs-office-partner-test-data.sql index 11f02ffd..a4705002 100644 --- a/src/main/resources/db/changelog/228-hs-office-partner-test-data.sql +++ b/src/main/resources/db/changelog/228-hs-office-partner-test-data.sql @@ -9,7 +9,7 @@ Creates a single partner test record. */ create or replace procedure createHsOfficePartnerTestData( - debitorNumberPrefix numeric(5), + partnerNumber numeric(5), personTradeOrFamilyName varchar, contactLabel varchar ) language plpgsql as $$ @@ -49,8 +49,8 @@ begin end if; insert - into hs_office_partner (uuid, debitorNumberPrefix, personuuid, contactuuid, detailsUuid) - values (uuid_generate_v4(), debitorNumberPrefix, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid); + into hs_office_partner (uuid, partnerNumber, personuuid, contactuuid, detailsUuid) + values (uuid_generate_v4(), partnerNumber, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid); end; $$; --// diff --git a/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql b/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql index ab70aa27..e6572e55 100644 --- a/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql +++ b/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql @@ -173,7 +173,7 @@ execute procedure hsOfficeDebitorRbacRolesTrigger(); -- ---------------------------------------------------------------------------- call generateRbacIdentityView('hs_office_debitor', $idName$ '#' || - (select debitornumberprefix from hs_office_partner p where p.uuid = target.partnerUuid) || + (select partnerNumber from hs_office_partner p where p.uuid = target.partnerUuid) || to_char(debitorNumberSuffix, 'fm00') || ':' || (select split_part(idName, ':', 2) from hs_office_partner_iv pi where pi.uuid = target.partnerUuid) $idName$); diff --git a/src/main/resources/db/changelog/300-hs-office-membership.sql b/src/main/resources/db/changelog/300-hs-office-membership.sql index 12f2dd34..acc0651a 100644 --- a/src/main/resources/db/changelog/300-hs-office-membership.sql +++ b/src/main/resources/db/changelog/300-hs-office-membership.sql @@ -13,10 +13,13 @@ 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), mainDebitorUuid uuid not null references hs_office_debitor(uuid), - memberNumber numeric(5) not null unique, + 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 + membershipFeeBillable boolean not null default true, + + UNIQUE(partnerUuid, memberNumberSuffix) ); --// diff --git a/src/main/resources/db/changelog/303-hs-office-membership-rbac.sql b/src/main/resources/db/changelog/303-hs-office-membership-rbac.sql index 972021e7..8197cf09 100644 --- a/src/main/resources/db/changelog/303-hs-office-membership-rbac.sql +++ b/src/main/resources/db/changelog/303-hs-office-membership-rbac.sql @@ -92,7 +92,9 @@ execute procedure hsOfficeMembershipRbacRolesTrigger(); --changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- call generateRbacIdentityView('hs_office_membership', idNameExpression => $idName$ - target.memberNumber || + '#' || + (select partnerNumber from hs_office_partner p where p.uuid = target.partnerUuid) || + memberNumberSuffix || ':' || (select split_part(idName, ':', 2) from hs_office_partner_iv p where p.uuid = target.partnerUuid) $idName$); --// @@ -102,7 +104,7 @@ call generateRbacIdentityView('hs_office_membership', idNameExpression => $idNam --changeset hs-office-membership-rbac-RESTRICTED-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- call generateRbacRestrictedView('hs_office_membership', - orderby => 'target.memberNumber', + orderby => 'target.memberNumberSuffix', columnUpdates => $updates$ validity = new.validity, reasonForTermination = new.reasonForTermination, diff --git a/src/main/resources/db/changelog/308-hs-office-membership-test-data.sql b/src/main/resources/db/changelog/308-hs-office-membership-test-data.sql index 5a4adaa6..637c87ca 100644 --- a/src/main/resources/db/changelog/308-hs-office-membership-test-data.sql +++ b/src/main/resources/db/changelog/308-hs-office-membership-test-data.sql @@ -8,16 +8,18 @@ /* Creates a single membership test record. */ -create or replace procedure createHsOfficeMembershipTestData( forPartnerTradeName varchar, forMainDebitorNumber numeric ) +create or replace procedure createHsOfficeMembershipTestData( + forPartnerTradeName varchar, + forMainDebitorNumberSuffix numeric, + newMemberNumberSuffix char(2) ) language plpgsql as $$ declare - currentTask varchar; - idName varchar; - relatedPartner hs_office_partner; - relatedDebitor hs_office_debitor; - newMemberNumber numeric; + currentTask varchar; + idName varchar; + relatedPartner hs_office_partner; + relatedDebitor hs_office_debitor; begin - idName := cleanIdentifier( forPartnerTradeName || '#' || forMainDebitorNumber); + idName := cleanIdentifier( forPartnerTradeName || '#' || forMainDebitorNumberSuffix); currentTask := 'creating Membership test-data ' || idName; call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); execute format('set local hsadminng.currentTask to %L', currentTask); @@ -25,15 +27,17 @@ begin select partner.* from hs_office_partner partner join hs_office_person person on person.uuid = partner.personUuid where person.tradeName = forPartnerTradeName into relatedPartner; - select d.* from hs_office_debitor d where d.debitorNumberSuffix = forMainDebitorNumber into relatedDebitor; - select coalesce(max(memberNumber)+1, 10001) from hs_office_membership into newMemberNumber; + select d.* from hs_office_debitor d + where d.partneruuid = relatedPartner.uuid + and d.debitorNumberSuffix = forMainDebitorNumberSuffix + into relatedDebitor; raise notice 'creating test Membership: %', idName; raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner; raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor; insert - into hs_office_membership (uuid, partneruuid, maindebitoruuid, membernumber, validity, reasonfortermination) - values (uuid_generate_v4(), relatedPartner.uuid, relatedDebitor.uuid, newMemberNumber, daterange('20221001' , null, '[]'), 'NONE'); + into hs_office_membership (uuid, partneruuid, maindebitoruuid, memberNumberSuffix, validity, reasonfortermination) + values (uuid_generate_v4(), relatedPartner.uuid, relatedDebitor.uuid, newMemberNumberSuffix, daterange('20221001' , null, '[]'), 'NONE'); end; $$; --// @@ -44,9 +48,9 @@ end; $$; do language plpgsql $$ begin - call createHsOfficeMembershipTestData('First GmbH', 11); - call createHsOfficeMembershipTestData('Second e.K.', 12); - call createHsOfficeMembershipTestData('Third OHG', 13); + call createHsOfficeMembershipTestData('First GmbH', 11, '01'); + call createHsOfficeMembershipTestData('Second e.K.', 12, '02'); + call createHsOfficeMembershipTestData('Third OHG', 13, '03'); end; $$; --// diff --git a/src/main/resources/db/changelog/318-hs-office-coopshares-test-data.sql b/src/main/resources/db/changelog/318-hs-office-coopshares-test-data.sql index c9252568..c3d2bf98 100644 --- a/src/main/resources/db/changelog/318-hs-office-coopshares-test-data.sql +++ b/src/main/resources/db/changelog/318-hs-office-coopshares-test-data.sql @@ -8,25 +8,33 @@ /* Creates a single coopSharesTransaction test record. */ -create or replace procedure createHsOfficeCoopSharesTransactionTestData(givenMembershipNumber numeric) +create or replace procedure createHsOfficeCoopSharesTransactionTestData( + givenPartnerNumber numeric, + givenMemberNumberSuffix char(2) +) language plpgsql as $$ declare currentTask varchar; membership hs_office_membership; begin - currentTask = 'creating coopSharesTransaction test-data ' || givenMembershipNumber; + currentTask = 'creating coopSharesTransaction test-data ' || givenPartnerNumber::text || givenMemberNumberSuffix; execute format('set local hsadminng.currentTask to %L', currentTask); call defineContext(currentTask); - select m.uuid from hs_office_membership m where m.memberNumber = givenMembershipNumber into membership; + select m.uuid + from hs_office_membership m + join hs_office_partner p on p.uuid = m.partneruuid + where p.partnerNumber = givenPartnerNumber + and m.memberNumberSuffix = givenMemberNumberSuffix + into membership; - raise notice 'creating test coopSharesTransaction: %', givenMembershipNumber; + raise notice 'creating test coopSharesTransaction: %', givenPartnerNumber::text || givenMemberNumberSuffix; insert into hs_office_coopsharestransaction(uuid, membershipuuid, transactiontype, valuedate, sharecount, reference, comment) values - (uuid_generate_v4(), membership.uuid, 'SUBSCRIPTION', '2010-03-15', 4, 'ref '||givenMembershipNumber||'-1', 'initial subscription'), - (uuid_generate_v4(), membership.uuid, 'CANCELLATION', '2021-09-01', -2, 'ref '||givenMembershipNumber||'-2', 'cancelling some'), - (uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-20', 2, 'ref '||givenMembershipNumber||'-3', 'some adjustment'); + (uuid_generate_v4(), membership.uuid, 'SUBSCRIPTION', '2010-03-15', 4, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-1', 'initial subscription'), + (uuid_generate_v4(), membership.uuid, 'CANCELLATION', '2021-09-01', -2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-2', 'cancelling some'), + (uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-20', 2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-3', 'some adjustment'); end; $$; --// @@ -37,8 +45,8 @@ end; $$; do language plpgsql $$ begin - call createHsOfficeCoopSharesTransactionTestData(10001); - call createHsOfficeCoopSharesTransactionTestData(10002); - call createHsOfficeCoopSharesTransactionTestData(10003); + call createHsOfficeCoopSharesTransactionTestData(10001, '01'); + call createHsOfficeCoopSharesTransactionTestData(10002, '02'); + call createHsOfficeCoopSharesTransactionTestData(10003, '03'); end; $$; diff --git a/src/main/resources/db/changelog/328-hs-office-coopassets-test-data.sql b/src/main/resources/db/changelog/328-hs-office-coopassets-test-data.sql index 8259a7e3..d54e77ca 100644 --- a/src/main/resources/db/changelog/328-hs-office-coopassets-test-data.sql +++ b/src/main/resources/db/changelog/328-hs-office-coopassets-test-data.sql @@ -8,25 +8,33 @@ /* Creates a single coopAssetsTransaction test record. */ -create or replace procedure createHsOfficeCoopAssetsTransactionTestData(givenMembershipNumber numeric) +create or replace procedure createHsOfficeCoopAssetsTransactionTestData( + givenPartnerNumber numeric, + givenMemberNumberSuffix char(2) + ) language plpgsql as $$ declare currentTask varchar; membership hs_office_membership; begin - currentTask = 'creating coopAssetsTransaction test-data ' || givenMembershipNumber; + currentTask = 'creating coopAssetsTransaction test-data ' || givenPartnerNumber || givenMemberNumberSuffix; execute format('set local hsadminng.currentTask to %L', currentTask); call defineContext(currentTask); - select m.uuid from hs_office_membership m where m.memberNumber = givenMembershipNumber into membership; + select m.uuid + from hs_office_membership m + join hs_office_partner p on p.uuid = m.partneruuid + where p.partnerNumber = givenPartnerNumber + and m.memberNumberSuffix = givenMemberNumberSuffix + into membership; - raise notice 'creating test coopAssetsTransaction: %', givenMembershipNumber; + raise notice 'creating test coopAssetsTransaction: %', givenPartnerNumber || givenMemberNumberSuffix; insert into hs_office_coopassetstransaction(uuid, membershipuuid, transactiontype, valuedate, assetvalue, reference, comment) values - (uuid_generate_v4(), membership.uuid, 'DEPOSIT', '2010-03-15', 320.00, 'ref '||givenMembershipNumber||'-1', 'initial deposit'), - (uuid_generate_v4(), membership.uuid, 'DISBURSAL', '2021-09-01', -128.00, 'ref '||givenMembershipNumber||'-2', 'partial disbursal'), - (uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-20', 128.00, 'ref '||givenMembershipNumber||'-3', 'some adjustment'); + (uuid_generate_v4(), membership.uuid, 'DEPOSIT', '2010-03-15', 320.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-1', 'initial deposit'), + (uuid_generate_v4(), membership.uuid, 'DISBURSAL', '2021-09-01', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-2', 'partial disbursal'), + (uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-20', 128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some adjustment'); end; $$; --// @@ -37,8 +45,8 @@ end; $$; do language plpgsql $$ begin - call createHsOfficeCoopAssetsTransactionTestData(10001); - call createHsOfficeCoopAssetsTransactionTestData(10002); - call createHsOfficeCoopAssetsTransactionTestData(10003); + call createHsOfficeCoopAssetsTransactionTestData(10001, '01'); + call createHsOfficeCoopAssetsTransactionTestData(10002, '02'); + call createHsOfficeCoopAssetsTransactionTestData(10003, '03'); end; $$; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerAcceptanceTest.java index 292a947c..b5dfa429 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerAcceptanceTest.java @@ -75,8 +75,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest { void globalAdmin_canFindCoopAssetsTransactionsByMemberNumber() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); RestAssured // @formatter:off .given() @@ -93,21 +92,21 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest { "transactionType": "DEPOSIT", "assetValue": 320.00, "valueDate": "2010-03-15", - "reference": "ref 10002-1", + "reference": "ref 1000202-1", "comment": "initial deposit" }, { "transactionType": "DISBURSAL", "assetValue": -128.00, "valueDate": "2021-09-01", - "reference": "ref 10002-2", + "reference": "ref 1000202-2", "comment": "partial disbursal" }, { "transactionType": "ADJUSTMENT", "assetValue": 128.00, "valueDate": "2022-10-20", - "reference": "ref 10002-3", + "reference": "ref 1000202-3", "comment": "some adjustment" } ] @@ -115,11 +114,10 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest { } @Test - void globalAdmin_canFindCoopAssetsTransactionsByMemberNumberAndDateRange() { + void globalAdmin_canFindCoopAssetsTransactionsByMembershipUuidAndDateRange() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); RestAssured // @formatter:off .given() @@ -137,7 +135,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest { "transactionType": "DISBURSAL", "assetValue": -128.00, "valueDate": "2021-09-01", - "reference": "ref 10002-2", + "reference": "ref 1000202-2", "comment": "partial disbursal" } ] @@ -153,8 +151,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest { void globalAdmin_canAddCoopAssetsTransaction() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10001) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); final var location = RestAssured // @formatter:off .given() @@ -199,8 +196,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest { void globalAdmin_canNotCancelMoreAssetsThanCurrentlySubscribed() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10001) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); final var location = RestAssured // @formatter:off .given() diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java index 0cc2988a..d93aa90f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java @@ -23,14 +23,14 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest { void toStringContainsAlmostAllPropertiesAccount() { final var result = givenCoopAssetTransaction.toString(); - assertThat(result).isEqualTo("CoopAssetsTransaction(300001, 2020-01-01, DEPOSIT, 128.00, some-ref)"); + assertThat(result).isEqualTo("CoopAssetsTransaction(1000101, 2020-01-01, DEPOSIT, 128.00, some-ref)"); } @Test - void toShortStringContainsOnlyMemberNumberAndSharesCountOnly() { + void toShortStringContainsOnlyMemberNumberSuffixAndSharesCountOnly() { final var result = givenCoopAssetTransaction.toShortString(); - assertThat(result).isEqualTo("300001+128.00"); + assertThat(result).isEqualTo("1000101+128.00"); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java index 54c5bbb3..89f48402 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java @@ -62,8 +62,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // given context("superuser-alex@hostsharing.net"); final var count = coopAssetsTransactionRepo.count(); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10001) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); // when final var result = attempt(em, () -> { @@ -96,9 +95,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // when attempt(em, () -> { - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber( - null, - 10001).get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); final var newCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder() .membership(givenMembership) .transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT) @@ -117,7 +114,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase .map(s -> s.replace("hs_office_", "")) .containsExactlyInAnyOrder(Array.fromFormatted( initialGrantNames, - "{ grant perm view on coopassetstransaction#temprefB to role membership#10001:....tenant by system and assume }", + "{ grant perm view on coopassetstransaction#temprefB to role membership#1000101:....tenant by system and assume }", null)); } @@ -144,25 +141,24 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // then allTheseCoopAssetsTransactionsAreReturned( result, - "CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1, initial deposit)", - "CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2, partial disbursal)", - "CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3, some adjustment)", + "CoopAssetsTransaction(1000101, 2010-03-15, DEPOSIT, 320.00, ref 1000101-1, initial deposit)", + "CoopAssetsTransaction(1000101, 2021-09-01, DISBURSAL, -128.00, ref 1000101-2, partial disbursal)", + "CoopAssetsTransaction(1000101, 2022-10-20, ADJUSTMENT, 128.00, ref 1000101-3, some adjustment)", - "CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1, initial deposit)", - "CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)", - "CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3, some adjustment)", + "CoopAssetsTransaction(1000202, 2010-03-15, DEPOSIT, 320.00, ref 1000202-1, initial deposit)", + "CoopAssetsTransaction(1000202, 2021-09-01, DISBURSAL, -128.00, ref 1000202-2, partial disbursal)", + "CoopAssetsTransaction(1000202, 2022-10-20, ADJUSTMENT, 128.00, ref 1000202-3, some adjustment)", - "CoopAssetsTransaction(10003, 2010-03-15, DEPOSIT, 320.00, ref 10003-1, initial deposit)", - "CoopAssetsTransaction(10003, 2021-09-01, DISBURSAL, -128.00, ref 10003-2, partial disbursal)", - "CoopAssetsTransaction(10003, 2022-10-20, ADJUSTMENT, 128.00, ref 10003-3, some adjustment)"); + "CoopAssetsTransaction(1000303, 2010-03-15, DEPOSIT, 320.00, ref 1000303-1, initial deposit)", + "CoopAssetsTransaction(1000303, 2021-09-01, DISBURSAL, -128.00, ref 1000303-2, partial disbursal)", + "CoopAssetsTransaction(1000303, 2022-10-20, ADJUSTMENT, 128.00, ref 1000303-3, some adjustment)"); } @Test public void globalAdmin_canViewCoopAssetsTransactions_filteredByMembershipUuid() { // given context("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); // when final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange( @@ -173,17 +169,16 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // then allTheseCoopAssetsTransactionsAreReturned( result, - "CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1, initial deposit)", - "CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)", - "CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3, some adjustment)"); + "CoopAssetsTransaction(1000202, 2010-03-15, DEPOSIT, 320.00, ref 1000202-1, initial deposit)", + "CoopAssetsTransaction(1000202, 2021-09-01, DISBURSAL, -128.00, ref 1000202-2, partial disbursal)", + "CoopAssetsTransaction(1000202, 2022-10-20, ADJUSTMENT, 128.00, ref 1000202-3, some adjustment)"); } @Test public void globalAdmin_canViewCoopAssetsTransactions_filteredByMembershipUuidAndValueDateRange() { // given context("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); // when final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange( @@ -194,7 +189,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // then allTheseCoopAssetsTransactionsAreReturned( result, - "CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)"); + "CoopAssetsTransaction(1000202, 2021-09-01, DISBURSAL, -128.00, ref 1000202-2, partial disbursal)"); } @Test @@ -211,9 +206,9 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // then: exactlyTheseCoopAssetsTransactionsAreReturned( result, - "CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1, initial deposit)", - "CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2, partial disbursal)", - "CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3, some adjustment)"); + "CoopAssetsTransaction(1000101, 2010-03-15, DEPOSIT, 320.00, ref 1000101-1, initial deposit)", + "CoopAssetsTransaction(1000101, 2021-09-01, DISBURSAL, -128.00, ref 1000101-2, partial disbursal)", + "CoopAssetsTransaction(1000101, 2022-10-20, ADJUSTMENT, 128.00, ref 1000101-3, some adjustment)"); } } @@ -232,8 +227,8 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // then assertThat(customerLogEntries).map(Arrays::toString).contains( - "[creating coopAssetsTransaction test-data 10001, hs_office_coopassetstransaction, INSERT]", - "[creating coopAssetsTransaction test-data 10002, hs_office_coopassetstransaction, INSERT]"); + "[creating coopAssetsTransaction test-data 1000101, hs_office_coopassetstransaction, INSERT]", + "[creating coopAssetsTransaction test-data 1000202, hs_office_coopassetstransaction, INSERT]"); } @BeforeEach diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java index f3c6cc33..787fe467 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java @@ -75,7 +75,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest { void globalAdmin_canFindCoopSharesTransactionsByMemberNumber() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002).get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); RestAssured // @formatter:off .given().header("current-user", "superuser-alex@hostsharing.net").port(port).when().get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid()).then().log().all().assertThat().statusCode(200).contentType("application/json").body("", lenientlyEquals(""" @@ -84,21 +84,21 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest { "transactionType": "SUBSCRIPTION", "shareCount": 4, "valueDate": "2010-03-15", - "reference": "ref 10002-1", + "reference": "ref 1000202-1", "comment": "initial subscription" }, { "transactionType": "CANCELLATION", "shareCount": -2, "valueDate": "2021-09-01", - "reference": "ref 10002-2", + "reference": "ref 1000202-2", "comment": "cancelling some" }, { "transactionType": "ADJUSTMENT", "shareCount": 2, "valueDate": "2022-10-20", - "reference": "ref 10002-3", + "reference": "ref 1000202-3", "comment": "some adjustment" } ] @@ -106,19 +106,20 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest { } @Test - void globalAdmin_canFindCoopSharesTransactionsByMemberNumberAndDateRange() { + void globalAdmin_canFindCoopSharesTransactionsByMembershipUuidAndDateRange() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002).get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); RestAssured // @formatter:off - .given().header("current-user", "superuser-alex@hostsharing.net").port(port).when().get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid() + "&fromValueDate=2020-01-01&toValueDate=2021-12-31").then().log().all().assertThat().statusCode(200).contentType("application/json").body("", lenientlyEquals(""" + .given().header("current-user", "superuser-alex@hostsharing.net").port(port).when() + .get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid() + "&fromValueDate=2020-01-01&toValueDate=2021-12-31").then().log().all().assertThat().statusCode(200).contentType("application/json").body("", lenientlyEquals(""" [ { "transactionType": "CANCELLATION", "shareCount": -2, "valueDate": "2021-09-01", - "reference": "ref 10002-2", + "reference": "ref 1000202-2", "comment": "cancelling some" } ] @@ -134,7 +135,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest { void globalAdmin_canAddCoopSharesTransaction() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10001).get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); final var location = RestAssured // @formatter:off .given().header("current-user", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body(""" @@ -165,7 +166,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest { void globalAdmin_canNotCancelMoreSharesThanCurrentlySubscribed() { context.define("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10001).get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); final var location = RestAssured // @formatter:off .given().header("current-user", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body(""" diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java index 8dcfd133..0170e1d8 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java @@ -22,14 +22,14 @@ class HsOfficeCoopSharesTransactionEntityUnitTest { void toStringContainsAlmostAllPropertiesAccount() { final var result = givenCoopSharesTransaction.toString(); - assertThat(result).isEqualTo("CoopShareTransaction(300001, 2020-01-01, SUBSCRIPTION, 4, some-ref)"); + assertThat(result).isEqualTo("CoopShareTransaction(1000101, 2020-01-01, SUBSCRIPTION, 4, some-ref)"); } @Test void toShortStringContainsOnlyMemberNumberAndShareCountOnly() { final var result = givenCoopSharesTransaction.toShortString(); - assertThat(result).isEqualTo("300001+4"); + assertThat(result).isEqualTo("M-1000101+4"); } @Test @@ -43,6 +43,6 @@ class HsOfficeCoopSharesTransactionEntityUnitTest { void toShortStringEmptyTransactionDoesNotThrowException() { final var result = givenEmptyCoopSharesTransaction.toShortString(); - assertThat(result).isEqualTo("null+0"); + assertThat(result).isEqualTo("M-null+0"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java index 3e125770..78d0ac7d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java @@ -61,8 +61,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // given context("superuser-alex@hostsharing.net"); final var count = coopSharesTransactionRepo.count(); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10001) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); // when final var result = attempt(em, () -> { @@ -95,9 +94,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // when attempt(em, () -> { - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber( - null, - 10001).get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101); final var newCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder() .membership(givenMembership) .transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION) @@ -116,7 +113,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase .map(s -> s.replace("hs_office_", "")) .containsExactlyInAnyOrder(Array.fromFormatted( initialGrantNames, - "{ grant perm view on coopsharestransaction#temprefB to role membership#10001:....tenant by system and assume }", + "{ grant perm view on coopsharestransaction#temprefB to role membership#1000101:....tenant by system and assume }", null)); } @@ -143,25 +140,24 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // then allTheseCoopSharesTransactionsAreReturned( result, - "CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1, initial subscription)", - "CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2, cancelling some)", - "CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3, some adjustment)", + "CoopShareTransaction(1000101, 2010-03-15, SUBSCRIPTION, 4, ref 1000101-1, initial subscription)", + "CoopShareTransaction(1000101, 2021-09-01, CANCELLATION, -2, ref 1000101-2, cancelling some)", + "CoopShareTransaction(1000101, 2022-10-20, ADJUSTMENT, 2, ref 1000101-3, some adjustment)", - "CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1, initial subscription)", - "CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)", - "CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3, some adjustment)", + "CoopShareTransaction(1000202, 2010-03-15, SUBSCRIPTION, 4, ref 1000202-1, initial subscription)", + "CoopShareTransaction(1000202, 2021-09-01, CANCELLATION, -2, ref 1000202-2, cancelling some)", + "CoopShareTransaction(1000202, 2022-10-20, ADJUSTMENT, 2, ref 1000202-3, some adjustment)", - "CoopShareTransaction(10003, 2010-03-15, SUBSCRIPTION, 4, ref 10003-1, initial subscription)", - "CoopShareTransaction(10003, 2021-09-01, CANCELLATION, -2, ref 10003-2, cancelling some)", - "CoopShareTransaction(10003, 2022-10-20, ADJUSTMENT, 2, ref 10003-3, some adjustment)"); + "CoopShareTransaction(1000303, 2010-03-15, SUBSCRIPTION, 4, ref 1000303-1, initial subscription)", + "CoopShareTransaction(1000303, 2021-09-01, CANCELLATION, -2, ref 1000303-2, cancelling some)", + "CoopShareTransaction(1000303, 2022-10-20, ADJUSTMENT, 2, ref 1000303-3, some adjustment)"); } @Test public void globalAdmin_canViewCoopSharesTransactions_filteredByMembershipUuid() { // given context("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); // when final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange( @@ -172,17 +168,16 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // then allTheseCoopSharesTransactionsAreReturned( result, - "CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1, initial subscription)", - "CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)", - "CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3, some adjustment)"); + "CoopShareTransaction(1000202, 2010-03-15, SUBSCRIPTION, 4, ref 1000202-1, initial subscription)", + "CoopShareTransaction(1000202, 2021-09-01, CANCELLATION, -2, ref 1000202-2, cancelling some)", + "CoopShareTransaction(1000202, 2022-10-20, ADJUSTMENT, 2, ref 1000202-3, some adjustment)"); } @Test public void globalAdmin_canViewCoopSharesTransactions_filteredByMembershipUuidAndValueDateRange() { // given context("superuser-alex@hostsharing.net"); - final var givenMembership = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002) - .get(0); + final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202); // when final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange( @@ -193,7 +188,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // then allTheseCoopSharesTransactionsAreReturned( result, - "CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)"); + "CoopShareTransaction(1000202, 2021-09-01, CANCELLATION, -2, ref 1000202-2, cancelling some)"); } @Test @@ -210,9 +205,9 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // then: exactlyTheseCoopSharesTransactionsAreReturned( result, - "CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1, initial subscription)", - "CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2, cancelling some)", - "CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3, some adjustment)"); + "CoopShareTransaction(1000101, 2010-03-15, SUBSCRIPTION, 4, ref 1000101-1, initial subscription)", + "CoopShareTransaction(1000101, 2021-09-01, CANCELLATION, -2, ref 1000101-2, cancelling some)", + "CoopShareTransaction(1000101, 2022-10-20, ADJUSTMENT, 2, ref 1000101-3, some adjustment)"); } } @@ -231,8 +226,8 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // then assertThat(customerLogEntries).map(Arrays::toString).contains( - "[creating coopSharesTransaction test-data 10001, hs_office_coopsharestransaction, INSERT]", - "[creating coopSharesTransaction test-data 10002, hs_office_coopsharestransaction, INSERT]"); + "[creating coopSharesTransaction test-data 1000101, hs_office_coopsharestransaction, INSERT]", + "[creating coopSharesTransaction test-data 1000202, hs_office_coopsharestransaction, INSERT]"); } @BeforeEach 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 1e40cfd7..96f1ba13 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 @@ -21,7 +21,7 @@ class HsOfficeDebitorEntityUnitTest { .tradeName("some trade name") .build()) .details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build()) - .debitorNumberPrefix(12345) + .partnerNumber(12345) .build()) .billingContact(HsOfficeContactEntity.builder().label("some label").build()) .defaultPrefix("som") @@ -29,7 +29,7 @@ class HsOfficeDebitorEntityUnitTest { final var result = given.toString(); - assertThat(result).isEqualTo("debitor(1234567: LP some trade name: som)"); + assertThat(result).isEqualTo("debitor(D-1234567: LP some trade name: som)"); } @Test @@ -39,27 +39,81 @@ class HsOfficeDebitorEntityUnitTest { .partner(HsOfficePartnerEntity.builder() .person(null) .details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build()) - .debitorNumberPrefix(12345) + .partnerNumber(12345) .build()) .billingContact(HsOfficeContactEntity.builder().label("some label").build()) .build(); final var result = given.toString(); - assertThat(result).isEqualTo("debitor(1234567: )"); + assertThat(result).isEqualTo("debitor(D-1234567: )"); } @Test void toShortStringContainsDebitorNumber() { final var given = HsOfficeDebitorEntity.builder() .partner(HsOfficePartnerEntity.builder() - .debitorNumberPrefix(12345) + .partnerNumber(12345) .build()) .debitorNumberSuffix((byte)67) .build(); final var result = given.toShortString(); - assertThat(result).isEqualTo("1234567"); + assertThat(result).isEqualTo("D-1234567"); + } + + @Test + void getDebitorNumberWithPartnerNumberAndDebitorNumberSuffix() { + final var given = HsOfficeDebitorEntity.builder() + .partner(HsOfficePartnerEntity.builder() + .partnerNumber(12345) + .build()) + .debitorNumberSuffix((byte)67) + .build(); + + final var result = given.getDebitorNumber(); + + assertThat(result).isEqualTo(1234567); + } + + @Test + void getDebitorNumberWithoutPartnerReturnsNull() { + final var given = HsOfficeDebitorEntity.builder() + .partner(null) + .debitorNumberSuffix((byte)67) + .build(); + + final var result = given.getDebitorNumber(); + + assertThat(result).isNull(); + } + + @Test + void getDebitorNumberWithoutPartnerNumberReturnsNull() { + final var given = HsOfficeDebitorEntity.builder() + .partner(HsOfficePartnerEntity.builder() + .partnerNumber(null) + .build()) + .debitorNumberSuffix((byte)67) + .build(); + + final var result = given.getDebitorNumber(); + + assertThat(result).isNull(); + } + + @Test + void getDebitorNumberWithoutDebitorNumberSuffixReturnsNull() { + final var given = HsOfficeDebitorEntity.builder() + .partner(HsOfficePartnerEntity.builder() + .partnerNumber(12345) + .build()) + .debitorNumberSuffix(null) + .build(); + + final var result = given.getDebitorNumber(); + + assertThat(result).isNull(); } } 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 7b1ef4b2..1fff4dce 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 @@ -211,9 +211,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { // then allTheseDebitorsAreReturned( result, - "debitor(1000111: LP First GmbH: fir)", - "debitor(1000212: LP Second e.K.: sec)", - "debitor(1000313: IF Third OHG: thi)"); + "debitor(D-1000111: LP First GmbH: fir)", + "debitor(D-1000212: LP Second e.K.: sec)", + "debitor(D-1000313: IF Third OHG: thi)"); } @ParameterizedTest @@ -231,8 +231,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { // then: exactlyTheseDebitorsAreReturned(result, - "debitor(1000111: LP First GmbH: fir)", - "debitor(1000120: LP First GmbH: fif)"); + "debitor(D-1000111: LP First GmbH: fir)", + "debitor(D-1000120: LP First GmbH: fif)"); } @Test @@ -260,7 +260,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { final var result = debitorRepo.findDebitorByDebitorNumber(1000313); // then - exactlyTheseDebitorsAreReturned(result, "debitor(1000313: IF Third OHG: thi)"); + exactlyTheseDebitorsAreReturned(result, "debitor(D-1000313: IF Third OHG: thi)"); } } @@ -276,7 +276,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { final var result = debitorRepo.findDebitorByOptionalNameLike("third contact"); // then - exactlyTheseDebitorsAreReturned(result, "debitor(1000313: IF Third OHG: thi)"); + exactlyTheseDebitorsAreReturned(result, "debitor(D-1000313: IF Third OHG: thi)"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java index 07a441a5..7afafaff 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java @@ -11,7 +11,6 @@ import net.hostsharing.test.Accepts; import net.hostsharing.test.JpaAttempt; import org.json.JSONException; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -37,6 +36,8 @@ import static org.hamcrest.Matchers.*; @Transactional class HsOfficeMembershipControllerAcceptanceTest { + private static String TEMP_MEMBER_NUMBER_SUFFIX = "90"; + @LocalServerPort private Integer port; @@ -61,8 +62,6 @@ class HsOfficeMembershipControllerAcceptanceTest { @PersistenceContext EntityManager em; - private static int tempMemberNumber = 20010; - @Nested @Accepts({ "Membership:F(Find)" }) class ListMemberships { @@ -84,7 +83,8 @@ class HsOfficeMembershipControllerAcceptanceTest { { "partner": { "person": { "tradeName": "First GmbH" } }, "mainDebitor": { "debitorNumber": 1000111 }, - "memberNumber": 10001, + "memberNumber": 1000101, + "memberNumberSuffix": "01", "validFrom": "2022-10-01", "validTo": null, "reasonForTermination": "NONE" @@ -92,7 +92,8 @@ class HsOfficeMembershipControllerAcceptanceTest { { "partner": { "person": { "tradeName": "Second e.K." } }, "mainDebitor": { "debitorNumber": 1000212 }, - "memberNumber": 10002, + "memberNumber": 1000202, + "memberNumberSuffix": "02", "validFrom": "2022-10-01", "validTo": null, "reasonForTermination": "NONE" @@ -100,7 +101,8 @@ class HsOfficeMembershipControllerAcceptanceTest { { "partner": { "person": { "tradeName": "Third OHG" } }, "mainDebitor": { "debitorNumber": 1000313 }, - "memberNumber": 10003, + "memberNumber": 1000303, + "memberNumberSuffix": "03", "validFrom": "2022-10-01", "validTo": null, "reasonForTermination": "NONE" @@ -109,6 +111,67 @@ class HsOfficeMembershipControllerAcceptanceTest { """)); // @formatter:on } + + @Test + void globalAdmin_canViewMembershipsByPartnerUuid() throws JSONException { + + context.define("superuser-alex@hostsharing.net"); + final var partner = partnerRepo.findPartnerByPartnerNumber(10001); + + RestAssured // @formatter:off + .given() + .header("current-user", "superuser-alex@hostsharing.net") + .port(port) + .when() + .queryParam("partnerUuid", partner.getUuid() ) + .get("http://localhost/api/hs/office/memberships") + .then().log().all().assertThat() + .statusCode(200) + .contentType("application/json") + .body("", lenientlyEquals(""" + [ + { + "partner": { "person": { "tradeName": "First GmbH" } }, + "mainDebitor": { "debitorNumber": 1000111 }, + "memberNumber": 1000101, + "memberNumberSuffix": "01", + "validFrom": "2022-10-01", + "validTo": null, + "reasonForTermination": "NONE" + } + ] + """)); + // @formatter:on + } + + @Test + void globalAdmin_canViewMembershipsByMemberNumber() throws JSONException { + + RestAssured // @formatter:off + .given() + .header("current-user", "superuser-alex@hostsharing.net") + .port(port) + .when() + .queryParam("memberNumber", 1000202 ) + .get("http://localhost/api/hs/office/memberships") + .then().log().all().assertThat() + .statusCode(200) + .contentType("application/json") + .body("", lenientlyEquals(""" + [ + { + "partner": { "person": { "tradeName": "Second e.K." } }, + "mainDebitor": { "debitorNumber": 1000212 }, + "memberNumber": 1000202, + "memberNumberSuffix": "02", + "validFrom": "2022-10-01", + "validTo": null, + "reasonForTermination": "NONE" + } + ] + """)); + // @formatter:on + } } @Nested @@ -121,6 +184,8 @@ class HsOfficeMembershipControllerAcceptanceTest { context.define("superuser-alex@hostsharing.net"); final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Third").get(0); final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("Third").get(0); + final var givenMemberSuffix = TEMP_MEMBER_NUMBER_SUFFIX; + final var expectedMemberNumber = Integer.parseInt(givenPartner.getPartnerNumber() + TEMP_MEMBER_NUMBER_SUFFIX); final var location = RestAssured // @formatter:off .given() @@ -130,11 +195,11 @@ class HsOfficeMembershipControllerAcceptanceTest { { "partnerUuid": "%s", "mainDebitorUuid": "%s", - "memberNumber": 20001, + "memberNumberSuffix": "%s", "validFrom": "2022-10-13", "membershipFeeBillable": "true" } - """.formatted(givenPartner.getUuid(), givenDebitor.getUuid())) + """.formatted(givenPartner.getUuid(), givenDebitor.getUuid(), givenMemberSuffix)) .port(port) .when() .post("http://localhost/api/hs/office/memberships") @@ -145,7 +210,8 @@ class HsOfficeMembershipControllerAcceptanceTest { .body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumber())) .body("mainDebitor.debitorNumberSuffix", is((int) givenDebitor.getDebitorNumberSuffix())) .body("partner.person.tradeName", is("Third OHG")) - .body("memberNumber", is(20001)) + .body("memberNumber", is(expectedMemberNumber)) + .body("memberNumberSuffix", is(givenMemberSuffix)) .body("validFrom", is("2022-10-13")) .body("validTo", equalTo(null)) .header("Location", startsWith("http://localhost")) @@ -166,11 +232,7 @@ class HsOfficeMembershipControllerAcceptanceTest { @Test void globalAdmin_canGetArbitraryMembership() { context.define("superuser-alex@hostsharing.net"); - final var givenMembershipUuid = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber( - null, - 10001) - .get(0) - .getUuid(); + final var givenMembershipUuid = membershipRepo.findMembershipByMemberNumber(1000101).getUuid(); RestAssured // @formatter:off .given() @@ -185,7 +247,8 @@ class HsOfficeMembershipControllerAcceptanceTest { { "partner": { "person": { "tradeName": "First GmbH" } }, "mainDebitor": { "debitorNumber": 1000111 }, - "memberNumber": 10001, + "memberNumber": 1000101, + "memberNumberSuffix": "01", "validFrom": "2022-10-01", "validTo": null, "reasonForTermination": "NONE" @@ -197,11 +260,7 @@ class HsOfficeMembershipControllerAcceptanceTest { @Accepts({ "Membership:X(Access Control)" }) void normalUser_canNotGetUnrelatedMembership() { context.define("superuser-alex@hostsharing.net"); - final var givenMembershipUuid = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber( - null, - 10001) - .get(0) - .getUuid(); + final var givenMembershipUuid = membershipRepo.findMembershipByMemberNumber(1000101).getUuid(); RestAssured // @formatter:off .given() @@ -217,11 +276,7 @@ class HsOfficeMembershipControllerAcceptanceTest { @Accepts({ "Membership:X(Access Control)" }) void debitorAgentUser_canGetRelatedMembership() { context.define("superuser-alex@hostsharing.net"); - final var givenMembershipUuid = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber( - null, - 10003) - .get(0) - .getUuid(); + final var givenMembershipUuid = membershipRepo.findMembershipByMemberNumber(1000303).getUuid(); RestAssured // @formatter:off .given() @@ -240,7 +295,8 @@ class HsOfficeMembershipControllerAcceptanceTest { "debitorNumber": 1000313, "billingContact": { "label": "third contact" } }, - "memberNumber": 10003, + "memberNumber": 1000303, + "memberNumberSuffix": "03", "validFrom": "2022-10-01", "validTo": null, "reasonForTermination": "NONE" @@ -279,7 +335,8 @@ class HsOfficeMembershipControllerAcceptanceTest { .body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName())) .body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber())) .body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix())) - .body("memberNumber", is(givenMembership.getMemberNumber())) + .body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix())) + .body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix())) .body("validFrom", is("2022-11-01")) .body("validTo", is("2023-12-31")) .body("reasonForTermination", is("CANCELLATION")); @@ -290,7 +347,7 @@ class HsOfficeMembershipControllerAcceptanceTest { .matches(mandate -> { assertThat(mandate.getPartner().toShortString()).isEqualTo("LP First GmbH"); assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString()); - assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber()); + assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix()); assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)"); assertThat(mandate.getReasonForTermination()).isEqualTo(HsOfficeReasonForTermination.CANCELLATION); return true; @@ -322,7 +379,7 @@ class HsOfficeMembershipControllerAcceptanceTest { .body("uuid", isUuidValid()) .body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName())) .body("mainDebitor.debitorNumber", is(1000313)) - .body("memberNumber", is(givenMembership.getMemberNumber())) + .body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix())) .body("validFrom", is("2022-11-01")) .body("validTo", nullValue()) .body("reasonForTermination", is("NONE")); @@ -333,7 +390,7 @@ class HsOfficeMembershipControllerAcceptanceTest { .matches(mandate -> { assertThat(mandate.getPartner().toShortString()).isEqualTo("LP First GmbH"); assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString()); - assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber()); + assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix()); assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)"); assertThat(mandate.getReasonForTermination()).isEqualTo(NONE); return true; @@ -444,7 +501,7 @@ class HsOfficeMembershipControllerAcceptanceTest { .uuid(UUID.randomUUID()) .partner(givenPartner) .mainDebitor(givenDebitor) - .memberNumber(++tempMemberNumber) + .memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX) .validity(Range.closedInfinite(LocalDate.parse("2022-11-01"))) .reasonForTermination(NONE) .membershipFeeBillable(true) @@ -454,13 +511,15 @@ class HsOfficeMembershipControllerAcceptanceTest { }).assertSuccessful().returnedValue(); } - @BeforeEach @AfterEach void cleanup() { jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net", null); - final var query = em.createQuery("DELETE FROM HsOfficeMembershipEntity m WHERE m.memberNumber >= 20000"); + final var query = em.createQuery( + "DELETE FROM HsOfficeMembershipEntity m WHERE m.memberNumberSuffix >= '%s'" + .formatted(TEMP_MEMBER_NUMBER_SUFFIX) + ); query.executeUpdate(); - }); + }).assertSuccessful(); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java index 2f42cb58..63ea7306 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java @@ -6,7 +6,10 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.mapper.Mapper; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -22,6 +25,7 @@ import jakarta.persistence.SynchronizationType; import java.util.Map; import java.util.UUID; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -59,119 +63,166 @@ public class HsOfficeMembershipControllerRestTest { when(emf.createEntityManager(any(SynchronizationType.class), any(Map.class))).thenReturn(em); } - @Test - void respondBadRequest_ifPartnerUuidIsMissing() throws Exception { + @Nested + class AddMembership { + @Test + void respondBadRequest_ifPartnerUuidIsMissing() throws Exception { - // when - mockMvc.perform(MockMvcRequestBuilders - .post("/api/hs/office/memberships") - .header("current-user", "superuser-alex@hostsharing.net") - .contentType(MediaType.APPLICATION_JSON) - .content(""" - { - "partnerUuid": null, - "mainDebitorUuid": "%s", - "memberNumber": 20001, - "validFrom": "2022-10-13", - "membershipFeeBillable": "true" - } - """.formatted(UUID.randomUUID())) - .accept(MediaType.APPLICATION_JSON)) + // when + mockMvc.perform(MockMvcRequestBuilders + .post("/api/hs/office/memberships") + .header("current-user", "superuser-alex@hostsharing.net") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "partnerUuid": null, + "mainDebitorUuid": "%s", + "memberNumberSuffix": "01", + "validFrom": "2022-10-13", + "membershipFeeBillable": "true" + } + """.formatted(UUID.randomUUID())) + .accept(MediaType.APPLICATION_JSON)) - // then - .andExpect(status().is4xxClientError()) - .andExpect(jsonPath("statusCode", is(400))) - .andExpect(jsonPath("statusPhrase", is("Bad Request"))) - .andExpect(jsonPath("message", is("[partnerUuid must not be null but is \"null\"]"))); + // then + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("statusCode", is(400))) + .andExpect(jsonPath("statusPhrase", is("Bad Request"))) + .andExpect(jsonPath("message", is("[partnerUuid must not be null but is \"null\"]"))); + } + + @Test + void respondBadRequest_ifDebitorUuidIsMissing() throws Exception { + + // when + mockMvc.perform(MockMvcRequestBuilders + .post("/api/hs/office/memberships") + .header("current-user", "superuser-alex@hostsharing.net") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "partnerUuid": "%s", + "mainDebitorUuid": null, + "memberNumberSuffix": "01", + "validFrom": "2022-10-13", + "membershipFeeBillable": "true" + } + """.formatted(UUID.randomUUID())) + .accept(MediaType.APPLICATION_JSON)) + + // then + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("statusCode", is(400))) + .andExpect(jsonPath("statusPhrase", is("Bad Request"))) + .andExpect(jsonPath("message", is("[mainDebitorUuid must not be null but is \"null\"]"))); + } + + @Test + void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception { + + // given + final var givenPartnerUuid = UUID.randomUUID(); + final var givenMainDebitorUuid = UUID.randomUUID(); + when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null); + when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(mock(HsOfficeDebitorEntity.class)); + + // when + mockMvc.perform(MockMvcRequestBuilders + .post("/api/hs/office/memberships") + .header("current-user", "superuser-alex@hostsharing.net") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "partnerUuid": "%s", + "mainDebitorUuid": "%s", + "memberNumberSuffix": "01", + "validFrom": "2022-10-13", + "membershipFeeBillable": "true" + } + """.formatted(givenPartnerUuid, givenMainDebitorUuid)) + .accept(MediaType.APPLICATION_JSON)) + + // then + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("statusCode", is(400))) + .andExpect(jsonPath("statusPhrase", is("Bad Request"))) + .andExpect(jsonPath("message", is("Unable to find Partner with uuid " + givenPartnerUuid))); + } + + @Test + void respondBadRequest_ifAnyGivenDebitorUuidCannotBeFound() throws Exception { + + // given + final var givenPartnerUuid = UUID.randomUUID(); + final var givenMainDebitorUuid = UUID.randomUUID(); + when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(mock(HsOfficePartnerEntity.class)); + when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(null); + + // when + mockMvc.perform(MockMvcRequestBuilders + .post("/api/hs/office/memberships") + .header("current-user", "superuser-alex@hostsharing.net") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "partnerUuid": "%s", + "mainDebitorUuid": "%s", + "memberNumberSuffix": "01", + "validFrom": "2022-10-13", + "membershipFeeBillable": "true" + } + """.formatted(givenPartnerUuid, givenMainDebitorUuid)) + .accept(MediaType.APPLICATION_JSON)) + + // then + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("statusCode", is(400))) + .andExpect(jsonPath("statusPhrase", is("Bad Request"))) + .andExpect(jsonPath("message", is("Unable to find Debitor with uuid " + givenMainDebitorUuid))); + } + + @ParameterizedTest + @EnumSource(InvalidMemberSuffixVariants.class) + void respondBadRequest_ifMemberNumberSuffixIsInvalid(final InvalidMemberSuffixVariants testCase) throws Exception { + + // when + mockMvc.perform(MockMvcRequestBuilders + .post("/api/hs/office/memberships") + .header("current-user", "superuser-alex@hostsharing.net") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "partnerUuid": "%s", + "mainDebitorUuid": "%s", + %s + "validFrom": "2022-10-13", + "membershipFeeBillable": "true" + } + """.formatted(UUID.randomUUID(), UUID.randomUUID(), testCase.memberNumberSuffixEntry)) + .accept(MediaType.APPLICATION_JSON)) + + // then + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("statusCode", is(400))) + .andExpect(jsonPath("statusPhrase", is("Bad Request"))) + .andExpect(jsonPath("message", containsString(testCase.expectedErrorMessage))); + } + + public enum InvalidMemberSuffixVariants { + MISSING("", "[memberNumberSuffix must not be null but is \"null\"]"), + TOO_SMALL("\"memberNumberSuffix\": \"9\",", "memberNumberSuffix size must be between 2 and 2 but is \"9\""), + TOO_LARGE("\"memberNumberSuffix\": \"100\",", "memberNumberSuffix size must be between 2 and 2 but is \"100\""), + NOT_NUMERIC("\"memberNumberSuffix\": \"AA\",", "memberNumberSuffix must match \"[0-9]+\" but is \"AA\""), + EMPTY("\"memberNumberSuffix\": \"\",", "memberNumberSuffix size must be between 2 and 2 but is \"\""); + + private final String memberNumberSuffixEntry; + private final String expectedErrorMessage; + + InvalidMemberSuffixVariants(final String memberNumberSuffixEntry, final String expectedErrorMessage) { + this.memberNumberSuffixEntry = memberNumberSuffixEntry; + this.expectedErrorMessage = expectedErrorMessage; + } + } } - @Test - void respondBadRequest_ifDebitorUuidIsMissing() throws Exception { - - // when - mockMvc.perform(MockMvcRequestBuilders - .post("/api/hs/office/memberships") - .header("current-user", "superuser-alex@hostsharing.net") - .contentType(MediaType.APPLICATION_JSON) - .content(""" - { - "partnerUuid": "%s", - "mainDebitorUuid": null, - "memberNumber": 20001, - "validFrom": "2022-10-13", - "membershipFeeBillable": "true" - } - """.formatted(UUID.randomUUID())) - .accept(MediaType.APPLICATION_JSON)) - - // then - .andExpect(status().is4xxClientError()) - .andExpect(jsonPath("statusCode", is(400))) - .andExpect(jsonPath("statusPhrase", is("Bad Request"))) - .andExpect(jsonPath("message", is("[mainDebitorUuid must not be null but is \"null\"]"))); - } - - @Test - void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception { - - // given - final var givenPartnerUuid = UUID.randomUUID(); - final var givenMainDebitorUuid = UUID.randomUUID(); - when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null); - when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(mock(HsOfficeDebitorEntity.class)); - - // when - mockMvc.perform(MockMvcRequestBuilders - .post("/api/hs/office/memberships") - .header("current-user", "superuser-alex@hostsharing.net") - .contentType(MediaType.APPLICATION_JSON) - .content(""" - { - "partnerUuid": "%s", - "mainDebitorUuid": "%s", - "memberNumber": 20001, - "validFrom": "2022-10-13", - "membershipFeeBillable": "true" - } - """.formatted(givenPartnerUuid, givenMainDebitorUuid)) - .accept(MediaType.APPLICATION_JSON)) - - // then - .andExpect(status().is4xxClientError()) - .andExpect(jsonPath("statusCode", is(400))) - .andExpect(jsonPath("statusPhrase", is("Bad Request"))) - .andExpect(jsonPath("message", is("Unable to find Partner with uuid " + givenPartnerUuid))); - } - - @Test - void respondBadRequest_ifAnyGivenDebitorUuidCannotBeFound() throws Exception { - - // given - final var givenPartnerUuid = UUID.randomUUID(); - final var givenMainDebitorUuid = UUID.randomUUID(); - when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(mock(HsOfficePartnerEntity.class)); - when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(null); - - // when - mockMvc.perform(MockMvcRequestBuilders - .post("/api/hs/office/memberships") - .header("current-user", "superuser-alex@hostsharing.net") - .contentType(MediaType.APPLICATION_JSON) - .content(""" - { - "partnerUuid": "%s", - "mainDebitorUuid": "%s", - "memberNumber": 20001, - "validFrom": "2022-10-13", - "membershipFeeBillable": "true" - } - """.formatted(givenPartnerUuid, givenMainDebitorUuid)) - .accept(MediaType.APPLICATION_JSON)) - - // then - .andExpect(status().is4xxClientError()) - .andExpect(jsonPath("statusCode", is(400))) - .andExpect(jsonPath("statusPhrase", is("Bad Request"))) - .andExpect(jsonPath("message", is("Unable to find Debitor with uuid " + givenMainDebitorUuid))); - } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java index 52fabefa..b1815755 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java @@ -1,6 +1,7 @@ package net.hostsharing.hsadminng.hs.office.membership; import com.vladmihalcea.hibernate.type.range.Range; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import org.junit.jupiter.api.Test; import jakarta.persistence.PrePersist; @@ -17,7 +18,7 @@ class HsOfficeMembershipEntityUnitTest { public static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-01-01"); final HsOfficeMembershipEntity givenMembership = HsOfficeMembershipEntity.builder() - .memberNumber(10001) + .memberNumberSuffix("01") .partner(TEST_PARTNER) .mainDebitor(TEST_DEBITOR) .validity(Range.closedInfinite(GIVEN_VALID_FROM)) @@ -26,15 +27,47 @@ class HsOfficeMembershipEntityUnitTest { @Test void toStringContainsAllProps() { final var result = givenMembership.toString(); - - assertThat(result).isEqualTo("Membership(10001, LP Test Ltd., 1000100, [2020-01-01,))"); + assertThat(result).isEqualTo("Membership(M-1000101, LP Test Ltd., D-1000100, [2020-01-01,))"); } @Test - void toShortStringContainsMemberNumberOnly() { + void toShortStringContainsMemberNumberSuffixOnly() { final var result = givenMembership.toShortString(); + assertThat(result).isEqualTo("M-1000101"); + } - assertThat(result).isEqualTo("10001"); + @Test + void getMemberNumberWithPartnerAndSuffix() { + final var result = givenMembership.getMemberNumber(); + assertThat(result).isEqualTo(1000101); + } + + @Test + void getMemberNumberWithPartnerButWithoutSuffix() { + givenMembership.setMemberNumberSuffix(null); + final var result = givenMembership.getMemberNumber(); + assertThat(result).isEqualTo(null); + } + + @Test + void getMemberNumberWithoutPartnerButWithSuffix() { + givenMembership.setPartner(null); + final var result = givenMembership.getMemberNumber(); + assertThat(result).isEqualTo(null); + } + + @Test + void getMemberNumberWithoutPartnerNumberButWithSuffix() { + givenMembership.setPartner(HsOfficePartnerEntity.builder().build()); + final var result = givenMembership.getMemberNumber(); + assertThat(result).isEqualTo(null); + } + + @Test + void getValidtyIfNull() { + givenMembership.setValidity(null); + final var result = givenMembership.getValidity(); + assertThat(result).isEqualTo(Range.infinite(LocalDate.class)); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java index a010c67c..af62541c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java @@ -77,7 +77,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newMembership = toCleanup(HsOfficeMembershipEntity.builder() - .memberNumber(20001) + .memberNumberSuffix("11") .partner(givenPartner) .mainDebitor(givenDebitor) .validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) @@ -108,7 +108,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0); final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); final var newMembership = toCleanup(HsOfficeMembershipEntity.builder() - .memberNumber(20002) + .memberNumberSuffix("07") .partner(givenPartner) .mainDebitor(givenDebitor) .validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) @@ -121,11 +121,11 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { final var all = rawRoleRepo.findAll(); assertThat(roleNamesOf(all)).containsExactlyInAnyOrder(Array.from( initialRoleNames, - "hs_office_membership#20002:FirstGmbH-firstcontact.admin", - "hs_office_membership#20002:FirstGmbH-firstcontact.agent", - "hs_office_membership#20002:FirstGmbH-firstcontact.guest", - "hs_office_membership#20002:FirstGmbH-firstcontact.owner", - "hs_office_membership#20002:FirstGmbH-firstcontact.tenant")); + "hs_office_membership#1000107:FirstGmbH-firstcontact.admin", + "hs_office_membership#1000107:FirstGmbH-firstcontact.agent", + "hs_office_membership#1000107:FirstGmbH-firstcontact.guest", + "hs_office_membership#1000107:FirstGmbH-firstcontact.owner", + "hs_office_membership#1000107:FirstGmbH-firstcontact.tenant")); assertThat(grantDisplaysOf(rawGrantRepo.findAll())) .map(s -> s.replace("GmbH-firstcontact", "")) .map(s -> s.replace("hs_office_", "")) @@ -133,33 +133,33 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { initialGrantNames, // owner - "{ grant perm * on membership#20002:First to role membership#20002:First.owner by system and assume }", - "{ grant role membership#20002:First.owner to role global#global.admin by system and assume }", + "{ grant perm * on membership#1000107:First to role membership#1000107:First.owner by system and assume }", + "{ grant role membership#1000107:First.owner to role global#global.admin by system and assume }", // admin - "{ grant perm edit on membership#20002:First to role membership#20002:First.admin by system and assume }", - "{ grant role membership#20002:First.admin to role membership#20002:First.owner by system and assume }", + "{ grant perm edit on membership#1000107:First to role membership#1000107:First.admin by system and assume }", + "{ grant role membership#1000107:First.admin to role membership#1000107:First.owner by system and assume }", // agent - "{ grant role membership#20002:First.agent to role membership#20002:First.admin by system and assume }", - "{ grant role partner#10001:First.tenant to role membership#20002:First.agent by system and assume }", - "{ grant role membership#20002:First.agent to role debitor#1000111:First.admin by system and assume }", - "{ grant role membership#20002:First.agent to role partner#10001:First.admin by system and assume }", - "{ grant role debitor#1000111:First.tenant to role membership#20002:First.agent by system and assume }", + "{ grant role membership#1000107:First.agent to role membership#1000107:First.admin by system and assume }", + "{ grant role partner#10001:First.tenant to role membership#1000107:First.agent by system and assume }", + "{ grant role membership#1000107:First.agent to role debitor#1000111:First.admin by system and assume }", + "{ grant role membership#1000107:First.agent to role partner#10001:First.admin by system and assume }", + "{ grant role debitor#1000111:First.tenant to role membership#1000107:First.agent by system and assume }", // tenant - "{ grant role membership#20002:First.tenant to role membership#20002:First.agent by system and assume }", - "{ grant role partner#10001:First.guest to role membership#20002:First.tenant by system and assume }", - "{ grant role debitor#1000111:First.guest to role membership#20002:First.tenant by system and assume }", - "{ grant role membership#20002:First.tenant to role debitor#1000111:First.agent by system and assume }", + "{ grant role membership#1000107:First.tenant to role membership#1000107:First.agent by system and assume }", + "{ grant role partner#10001:First.guest to role membership#1000107:First.tenant by system and assume }", + "{ grant role debitor#1000111:First.guest to role membership#1000107:First.tenant by system and assume }", + "{ grant role membership#1000107:First.tenant to role debitor#1000111:First.agent by system and assume }", - "{ grant role membership#20002:First.tenant to role partner#10001:First.agent by system and assume }", + "{ grant role membership#1000107:First.tenant to role partner#10001:First.agent by system and assume }", // guest - "{ grant perm view on membership#20002:First to role membership#20002:First.guest by system and assume }", - "{ grant role membership#20002:First.guest to role membership#20002:First.tenant by system and assume }", - "{ grant role membership#20002:First.guest to role partner#10001:First.tenant by system and assume }", - "{ grant role membership#20002:First.guest to role debitor#1000111:First.tenant by system and assume }", + "{ grant perm view on membership#1000107:First to role membership#1000107:First.guest by system and assume }", + "{ grant role membership#1000107:First.guest to role membership#1000107:First.tenant by system and assume }", + "{ grant role membership#1000107:First.guest to role partner#10001:First.tenant by system and assume }", + "{ grant role membership#1000107:First.guest to role debitor#1000111:First.tenant by system and assume }", null)); } @@ -179,14 +179,14 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net"); // when - final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, null); + final var result = membershipRepo.findMembershipsByOptionalPartnerUuid(null); // then exactlyTheseMembershipsAreReturned( result, - "Membership(10001, LP First GmbH, 1000111, [2022-10-01,), NONE)", - "Membership(10002, LP Second e.K., 1000212, [2022-10-01,), NONE)", - "Membership(10003, IF Third OHG, 1000313, [2022-10-01,), NONE)"); + "Membership(M-1000101, LP First GmbH, D-1000111, [2022-10-01,), NONE)", + "Membership(M-1000202, LP Second e.K., D-1000212, [2022-10-01,), NONE)", + "Membership(M-1000303, IF Third OHG, D-1000313, [2022-10-01,), NONE)"); } @Test @@ -196,24 +196,26 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0); // when - final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber( - givenPartner.getUuid(), - null); + final var result = membershipRepo.findMembershipsByOptionalPartnerUuid(givenPartner.getUuid()); // then - exactlyTheseMembershipsAreReturned(result, "Membership(10001, LP First GmbH, 1000111, [2022-10-01,), NONE)"); + exactlyTheseMembershipsAreReturned(result, + "Membership(M-1000101, LP First GmbH, D-1000111, [2022-10-01,), NONE)"); } @Test - public void globalAdmin_withoutAssumedRole_canFindAllMembershipByMemberNumber() { + public void globalAdmin_withoutAssumedRole_canFindAllMemberships() { // given context("superuser-alex@hostsharing.net"); // when - final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002); + final var result = membershipRepo.findMembershipByMemberNumber(1000202); // then - exactlyTheseMembershipsAreReturned(result, "Membership(10002, LP Second e.K., 1000212, [2022-10-01,), NONE)"); + assertThat(result) + .isNotNull() + .extracting(Object::toString) + .isEqualTo("Membership(M-1000202, LP Second e.K., D-1000212, [2022-10-01,), NONE)"); } } @@ -401,7 +403,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { }); jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net", null); - em.createQuery("DELETE FROM HsOfficeMembershipEntity WHERE memberNumber >= 20000"); + em.createQuery("DELETE FROM HsOfficeMembershipEntity WHERE memberNumberSuffix >= '20'"); }); } @@ -411,7 +413,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerTradeName).get(0); final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike(debitorName).get(0); final var newMembership = HsOfficeMembershipEntity.builder() - .memberNumber(20002) + .memberNumberSuffix("02") .partner(givenPartner) .mainDebitor(givenDebitor) .validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java index d9245fc8..ff50eb58 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java @@ -11,7 +11,7 @@ public class TestHsMembership { public static final HsOfficeMembershipEntity TEST_MEMBERSHIP = HsOfficeMembershipEntity.builder() .partner(TEST_PARTNER) - .memberNumber(300001) + .memberNumberSuffix("01") .validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) .build(); } 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 16771953..ad1edb48 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 @@ -176,15 +176,15 @@ public class ImportOfficeData extends ContextBasedTest { assertThat(toFormattedString(contacts)).isEqualTo("{}"); assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace(""" { - 17=debitor(1001700: null null, null: mih), - 20=debitor(1002000: null null, null: xyz), - 22=debitor(1102200: null null, null: xxx)} + 17=debitor(D-1001700: null null, null: mih), + 20=debitor(D-1002000: null null, null: xyz), + 22=debitor(D-1102200: null null, null: xxx)} """); assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace(""" { - 17=Membership(10017, null null, null, 1001700, [2000-12-06,), NONE), - 20=Membership(10020, null null, null, 1002000, [2000-12-06,2016-01-01), UNKNOWN), - 22=Membership(11022, null null, null, 1102200, [2021-04-01,), NONE) + 17=Membership(M-1001700, null null, null, D-1001700, [2000-12-06,), NONE), + 20=Membership(M-1002000, null null, null, D-1002000, [2000-12-06,2016-01-01), UNKNOWN), + 22=Membership(M-1102200, null null, null, D-1102200, [2021-04-01,), NONE) } """); } @@ -235,16 +235,16 @@ public class ImportOfficeData extends ContextBasedTest { """); assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace(""" { - 17=debitor(1001700: NP Mellies, Michael: mih), - 20=debitor(1002000: LP JM GmbH: xyz), - 22=debitor(1102200: ?? Test PS: xxx) + 17=debitor(D-1001700: NP Mellies, Michael: mih), + 20=debitor(D-1002000: LP JM GmbH: xyz), + 22=debitor(D-1102200: ?? Test PS: xxx) } """); assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace(""" { - 17=Membership(10017, NP Mellies, Michael, 1001700, [2000-12-06,), NONE), - 20=Membership(10020, LP JM GmbH, 1002000, [2000-12-06,2016-01-01), UNKNOWN), - 22=Membership(11022, ?? Test PS, 1102200, [2021-04-01,), NONE) + 17=Membership(M-1001700, NP Mellies, Michael, D-1001700, [2000-12-06,), NONE), + 20=Membership(M-1002000, LP JM GmbH, D-1002000, [2000-12-06,2016-01-01), UNKNOWN), + 22=Membership(M-1102200, ?? Test PS, D-1102200, [2021-04-01,), NONE) } """); assertThat(toFormattedString(relationships)).isEqualToIgnoringWhitespace(""" @@ -312,10 +312,10 @@ public class ImportOfficeData extends ContextBasedTest { assertThat(toFormattedString(coopShares)).isEqualToIgnoringWhitespace(""" { - 33443=CoopShareTransaction(10017, 2000-12-06, SUBSCRIPTION, 20, initial share subscription), - 33451=CoopShareTransaction(10020, 2000-12-06, SUBSCRIPTION, 2, initial share subscription), - 33701=CoopShareTransaction(10017, 2005-01-10, SUBSCRIPTION, 40, increase), - 33810=CoopShareTransaction(10020, 2016-12-31, CANCELLATION, 22, membership ended) + 33443=CoopShareTransaction(M-1001700, 2000-12-06, SUBSCRIPTION, 20, initial share subscription), + 33451=CoopShareTransaction(M-1002000, 2000-12-06, SUBSCRIPTION, 2, initial share subscription), + 33701=CoopShareTransaction(M-1001700, 2005-01-10, SUBSCRIPTION, 40, increase), + 33810=CoopShareTransaction(M-1002000, 2016-12-31, CANCELLATION, 22, membership ended) } """); } @@ -549,7 +549,7 @@ public class ImportOfficeData extends ContextBasedTest { final var person = HsOfficePersonEntity.builder().build(); final var partner = HsOfficePartnerEntity.builder() - .debitorNumberPrefix(rec.getInteger("member_id")) + .partnerNumber(rec.getInteger("member_id")) .details(HsOfficePartnerDetailsEntity.builder().build()) .contact(null) // is set during contacts import depending on assigned roles .person(person) @@ -571,9 +571,10 @@ public class ImportOfficeData extends ContextBasedTest { partners.put(rec.getInteger("bp_id"), partner); if (isNotBlank(rec.getString("member_since"))) { + assertThat(rec.getInteger("member_id")).isEqualTo(partner.getPartnerNumber()); final var membership = HsOfficeMembershipEntity.builder() .partner(partner) - .memberNumber(rec.getInteger("member_id")) + .memberNumberSuffix("00") .validity(toPostgresDateRange( rec.getLocalDate("member_since"), rec.getLocalDate("member_until"))) @@ -610,7 +611,7 @@ public class ImportOfficeData extends ContextBasedTest { : HsOfficeCoopSharesTransactionType.ADJUSTMENT ) .shareCount(rec.getInteger("quantity")) - .comment(rec.getString("comment")) + .comment( rec.getString("comment")) .build(); coopShares.put(rec.getInteger("member_share_id"), shareTransaction); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java index 38700b2a..fe517ee6 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java @@ -125,7 +125,7 @@ class HsOfficePartnerControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "debitorNumberPrefix": "12345", + "partnerNumber": "12345", "contactUuid": "%s", "personUuid": "%s", "details": { @@ -167,7 +167,7 @@ class HsOfficePartnerControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "debitorNumberPrefix": "12345", + "partnerNumber": "12345", "contactUuid": "%s", "personUuid": "%s", "details": {} @@ -195,7 +195,7 @@ class HsOfficePartnerControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "debitorNumberPrefix": "12345", + "partnerNumber": "12345", "contactUuid": "%s", "personUuid": "%s", "details": {} @@ -297,7 +297,7 @@ class HsOfficePartnerControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "debitorNumberPrefix": "12345", + "debitorNumerPrefix": "12345", "contactUuid": "%s", "personUuid": "%s", "details": { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java index 701f2d81..f764163d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java @@ -105,7 +105,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); final var newPartner = toCleanup(HsOfficePartnerEntity.builder() - .debitorNumberPrefix(22222) + .partnerNumber(22222) .person(givenPerson) .contact(givenContact) .details(HsOfficePartnerDetailsEntity.builder().build()) @@ -211,6 +211,25 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { } } + @Nested + class FindByPartnerNumber { + + @Test + public void globalAdmin_withoutAssumedRole_canViewAllPartners() { + // given + context("superuser-alex@hostsharing.net"); + + // when + final var result = partnerRepo.findPartnerByPartnerNumber(10001); + + // then + assertThat(result) + .isNotNull() + .extracting(Object::toString) + .isEqualTo("partner(LP First GmbH: first contact)"); + } + } + @Nested class UpdatePartner { @@ -396,13 +415,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { } private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler( - final Integer debitorNumberPrefix, final String person, final String contact) { + final Integer partnerNumber, final String person, final String contact) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); final var givenPerson = personRepo.findPersonByOptionalNameLike(person).get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); final var newPartner = HsOfficePartnerEntity.builder() - .debitorNumberPrefix(debitorNumberPrefix) + .partnerNumber(partnerNumber) .person(givenPerson) .contact(givenContact) .details(HsOfficePartnerDetailsEntity.builder().build()) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java index 6f567076..abbb8e09 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java @@ -12,7 +12,7 @@ public class TestHsOfficePartner { static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) { return HsOfficePartnerEntity.builder() - .debitorNumberPrefix(10001) + .partnerNumber(10001) .person(HsOfficePersonEntity.builder() .personType(LEGAL_PERSON) .tradeName(tradeName) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonTypeConverterUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonTypeConverterUnitTest.java index 93283f2b..1077d462 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonTypeConverterUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonTypeConverterUnitTest.java @@ -1,5 +1,6 @@ package net.hostsharing.hsadminng.hs.office.person; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -15,10 +16,19 @@ class HsOfficePersonTypeConverterUnitTest { assertThat(converter.convertToDatabaseColumn(given)).isEqualTo(given.shortName); } + @Test + void mapsNullToDatabaseValue() { + assertThat(converter.convertToDatabaseColumn(null)).isEqualTo(null); + } @ParameterizedTest @EnumSource(HsOfficePersonType.class) void mapsFromDatabaseValue(final HsOfficePersonType given) { assertThat(converter.convertToEntityAttribute(given.shortName)).isEqualTo(given); } + + @Test + void mapsNullFromDatabaseValue() { + assertThat(converter.convertToEntityAttribute(null)).isEqualTo(null); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityUnitTest.java new file mode 100644 index 00000000..45049ef8 --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityUnitTest.java @@ -0,0 +1,32 @@ +package net.hostsharing.hsadminng.hs.office.relationship; + +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class HsOfficeRelationshipEntityUnitTest { + + private HsOfficePersonEntity anchor = HsOfficePersonEntity.builder() + .personType(HsOfficePersonType.LEGAL_PERSON) + .tradeName("some trade name") + .build(); + private HsOfficePersonEntity holder = HsOfficePersonEntity.builder() + .personType(HsOfficePersonType.NATURAL_PERSON) + .familyName("Meier") + .givenName("Mellie") + .build(); + + @Test + void toShortString() { + final var given = HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.REPRESENTATIVE) + .relAnchor(anchor) + .relHolder(holder) + .build(); + + assertThat(given.toShortString()).isEqualTo("rel(relAnchor='LP some trade name', relType='REPRESENTATIVE', relHolder='NP Meier, Mellie')"); + } +} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java index eca05c62..0cf0c887 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java @@ -376,7 +376,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { context.define("superuser-alex@hostsharing.net"); assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get() .matches(mandate -> { - assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LP First GmbH: fir)"); + assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(D-1000111: LP First GmbH: fir)"); assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH"); assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched"); assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05"); @@ -417,7 +417,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { // finally, the sepaMandate is actually updated assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get() .matches(mandate -> { - assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LP First GmbH: fir)"); + assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(D-1000111: LP First GmbH: fir)"); assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH"); assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z"); assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)"); diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java index 76d738ad..b13bcb76 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java @@ -13,8 +13,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -30,9 +28,6 @@ class RbacUserControllerAcceptanceTest { @LocalServerPort private Integer port; - @PersistenceContext - EntityManager em; - @Autowired JpaAttempt jpaAttempt;