diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java index b9b4f980..22cf712a 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java @@ -26,6 +26,7 @@ public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable { private static Stringify toString = stringify(HsOfficeRelationshipEntity.class, "rel") .withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor) .withProp(Fields.relType, HsOfficeRelationshipEntity::getRelType) + .withProp(Fields.relMark, HsOfficeRelationshipEntity::getRelMark) .withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder) .withProp(Fields.contact, HsOfficeRelationshipEntity::getContact); @@ -54,6 +55,9 @@ public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable { @Enumerated(EnumType.STRING) private HsOfficeRelationshipType relType; + @Column(name = "relmark") + private String relMark; + @Override public String toString() { return toString.apply(this); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipType.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipType.java index 18cd6c88..2b9fe60c 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipType.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipType.java @@ -7,5 +7,6 @@ public enum HsOfficeRelationshipType { REPRESENTATIVE, VIP_CONTACT, ACCOUNTING, - OPERATIONS + OPERATIONS, + SUBSCRIBER } diff --git a/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml index cb865205..8fb5abb2 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml @@ -12,6 +12,7 @@ components: - VIP_CONTACT - ACCOUNTING, - OPERATIONS + - SUBSCRIBER HsOfficeRelationship: type: object @@ -25,6 +26,9 @@ components: $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson' relType: type: string + relMark: + type: string + nullable: true contact: $ref: './hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact' @@ -48,6 +52,8 @@ components: relType: type: string nullable: true + relMark: + type: string contactUuid: type: string format: uuid diff --git a/src/main/resources/db/changelog/220-hs-office-relationship.sql b/src/main/resources/db/changelog/220-hs-office-relationship.sql index 782577f1..44f9e500 100644 --- a/src/main/resources/db/changelog/220-hs-office-relationship.sql +++ b/src/main/resources/db/changelog/220-hs-office-relationship.sql @@ -11,7 +11,8 @@ CREATE TYPE HsOfficeRelationshipType AS ENUM ( 'REPRESENTATIVE', 'VIP_CONTACT', 'ACCOUNTING', - 'OPERATIONS'); + 'OPERATIONS', + 'SUBSCRIBER'); CREATE CAST (character varying as HsOfficeRelationshipType) WITH INOUT AS IMPLICIT; @@ -21,7 +22,8 @@ create table if not exists hs_office_relationship relAnchorUuid uuid not null references hs_office_person(uuid), relHolderUuid uuid not null references hs_office_person(uuid), contactUuid uuid references hs_office_contact(uuid), - relType HsOfficeRelationshipType not null + relType HsOfficeRelationshipType not null, + relMark varchar(24) ); --// diff --git a/src/main/resources/db/changelog/228-hs-office-relationship-test-data.sql b/src/main/resources/db/changelog/228-hs-office-relationship-test-data.sql index 73b6d69b..f2315201 100644 --- a/src/main/resources/db/changelog/228-hs-office-relationship-test-data.sql +++ b/src/main/resources/db/changelog/228-hs-office-relationship-test-data.sql @@ -12,7 +12,8 @@ create or replace procedure createHsOfficeRelationshipTestData( holderPersonName varchar, relationshipType HsOfficeRelationshipType, anchorPersonTradeName varchar, - contactLabel varchar) + contactLabel varchar, + mark varchar default null) language plpgsql as $$ declare currentTask varchar; @@ -49,8 +50,8 @@ begin raise notice '- using holder person (%): %', holderPerson.uuid, holderPerson; raise notice '- using contact (%): %', contact.uuid, contact; insert - into hs_office_relationship (uuid, relanchoruuid, relholderuuid, reltype, contactUuid) - values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationshipType, contact.uuid); + into hs_office_relationship (uuid, relanchoruuid, relholderuuid, reltype, relmark, contactUuid) + values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationshipType, mark, contact.uuid); end; $$; --// @@ -98,6 +99,7 @@ do language plpgsql $$ call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact'); + call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'SUBSCRIBER', 'third contact', 'members-announce'); end; $$; --// 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 4ac6ff1a..774e0b62 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 @@ -22,6 +22,7 @@ import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEnti import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType; import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity; import net.hostsharing.test.JpaAttempt; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.BeforeEachCallback; @@ -113,6 +114,17 @@ import static org.assertj.core.api.Fail.fail; @ExtendWith(OrderedDependedTestsExtension.class) public class ImportOfficeData extends ContextBasedTest { + private static final String[] SUBSCRIBER_ROLES = new String[] { + "subscriber:operations-discussion", + "subscriber:operations-announce", + "subscriber:members-announce", + "subscriber:members-discussion", + "subscriber:customers-announce" + }; + private static final String[] KNOWN_ROLES = ArrayUtils.addAll( + new String[]{"partner", "vip-contact", "ex-partner", "billing", "contractual", "operation"}, + SUBSCRIBER_ROLES); + static int relationshipId = 2000000; @Value("${spring.datasource.url}") @@ -257,10 +269,13 @@ public class ImportOfficeData extends ContextBasedTest { 2000004=rel(relAnchor='LP JM GmbH', relType='EX_PARTNER', relHolder='LP JM e.K.', contact='JM e.K.'), 2000005=rel(relAnchor='LP JM GmbH', relType='OPERATIONS', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'), 2000006=rel(relAnchor='LP JM GmbH', relType='VIP_CONTACT', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'), - 2000007=rel(relAnchor='LP JM GmbH', relType='REPRESENTATIVE', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'), - 2000008=rel(relAnchor='?? Test PS', relType='OPERATIONS', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'), - 2000009=rel(relAnchor='?? Test PS', relType='REPRESENTATIVE', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'), - 2000010=rel(relAnchor='NP Mellies, Michael', relType='REPRESENTATIVE', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies ') + 2000007=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='operations-announce', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'), + 2000008=rel(relAnchor='LP JM GmbH', relType='REPRESENTATIVE', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'), + 2000009=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='members-announce', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'), + 2000010=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='customers-announce', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'), + 2000011=rel(relAnchor='?? Test PS', relType='OPERATIONS', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'), + 2000012=rel(relAnchor='?? Test PS', relType='REPRESENTATIVE', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'), + 2000013=rel(relAnchor='NP Mellies, Michael', relType='REPRESENTATIVE', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies ') } """); } @@ -316,10 +331,10 @@ public class ImportOfficeData extends ContextBasedTest { assertThat(toFormattedString(coopShares)).isEqualToIgnoringWhitespace(""" { - 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) + 33443=CoopShareTransaction(1001700, 2000-12-06, SUBSCRIPTION, 20, initial share subscription), + 33451=CoopShareTransaction(1002000, 2000-12-06, SUBSCRIPTION, 2, initial share subscription), + 33701=CoopShareTransaction(1001700, 2005-01-10, SUBSCRIPTION, 40, increase), + 33810=CoopShareTransaction(1002000, 2016-12-31, CANCELLATION, 22, membership ended) } """); } @@ -763,8 +778,14 @@ public class ImportOfficeData extends ContextBasedTest { if (containsRole(rec, "vip-contact")) { addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.VIP_CONTACT); } - verifyContainsOnly(rec.getString("roles"), - "partner", "vip-contact", "ex-partner", "billing", "contractual", "operation"); + for (String subscriberRole: SUBSCRIBER_ROLES) { + if (containsRole(rec, subscriberRole)) { + addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.SUBSCRIBER) + .setRelMark(subscriberRole.split(":")[1]) + ; + } + } + verifyContainsOnlyKnownRoles(rec.getString("roles")); }); optionallyAddMissingContractualRelationships(); @@ -788,7 +809,7 @@ public class ImportOfficeData extends ContextBasedTest { return containsRole(rec, "partner"); } - private static void addRelationship( + private static HsOfficeRelationshipEntity addRelationship( final HsOfficePersonEntity partnerPerson, final HsOfficePersonEntity contactPerson, final HsOfficeContactEntity contact, @@ -800,6 +821,7 @@ public class ImportOfficeData extends ContextBasedTest { .relType(representative) .build(); relationships.put(relationshipId++, rel); + return rel; } private HsOfficePersonEntity initPerson(final HsOfficePersonEntity person, final Record contactRecord) { @@ -844,9 +866,9 @@ public class ImportOfficeData extends ContextBasedTest { return false; } - private void verifyContainsOnly(final String roles, final String... allowedRoles) { + private void verifyContainsOnlyKnownRoles(final String roles) { + final var allowedRolesSet = stream(KNOWN_ROLES).collect(Collectors.toSet()); final var givenRolesSet = stream(roles.replace(" ", "").split(",")).collect(Collectors.toSet()); - final var allowedRolesSet = stream(allowedRoles).collect(Collectors.toSet()); final var unexpectedRolesSet = new HashSet<>(givenRolesSet); unexpectedRolesSet.removeAll(allowedRolesSet); assertThat(unexpectedRolesSet).isEmpty(); 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 index 45049ef8..59433fa2 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityUnitTest.java @@ -19,6 +19,18 @@ class HsOfficeRelationshipEntityUnitTest { .givenName("Mellie") .build(); + @Test + void toStringReturnsAllProperties() { + final var given = HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.SUBSCRIBER) + .relMark("members-announce") + .relAnchor(anchor) + .relHolder(holder) + .build(); + + assertThat(given.toString()).isEqualTo("rel(relAnchor='LP some trade name', relType='SUBSCRIBER', relMark='members-announce', relHolder='NP Meier, Mellie')"); + } + @Test void toShortString() { final var given = HsOfficeRelationshipEntity.builder() diff --git a/src/test/resources/migration/contacts.csv b/src/test/resources/migration/contacts.csv index af67bce3..3f185a50 100644 --- a/src/test/resources/migration/contacts.csv +++ b/src/test/resources/migration/contacts.csv @@ -6,8 +6,8 @@ contact_id; bp_id; salut; first_name; last_name; title; firma; co; street; zip # eine juristische Person mit drei separaten Ansprechpartnern, vip-contact und ex-partner 1200; 20;; ; ; ; JM e.K.;; Wiesenweg 15; 12335; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; jm-ex-partner@example.org; ex-partner 1201; 20; Frau; Jenny; Meyer-Billing; Dr.; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 7777777; +49 30 1111111; ; +49 30 2222222; jm-billing@example.org; billing -1202; 20; Herr; Andrew; Meyer-Operation; ; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 3333333; ; +49 30 4444444; am-operation@example.org; operation,vip-contact -1203; 20; Herr; Philip; Meyer-Contract; ; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; pm-partner@example.org; partner,contractual +1202; 20; Herr; Andrew; Meyer-Operation; ; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 3333333; ; +49 30 4444444; am-operation@example.org; operation,vip-contact,subscriber:operations-announce +1203; 20; Herr; Philip; Meyer-Contract; ; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; pm-partner@example.org; partner,contractual,subscriber:members-announce,subscriber:customers-announce # eine juristische Person mit nur einem Ansprechpartner und explizitem contractual 1301; 22; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; partner,billing,contractual,operation