import operational contact + allow multiple assignments of contacts
This commit is contained in:
parent
cd7ea891c2
commit
3a66a28a33
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -23,7 +24,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@AllArgsConstructor
|
||||
@FieldNameConstants
|
||||
@DisplayName("BankAccount")
|
||||
public class HsOfficeBankAccountEntity implements Stringifyable {
|
||||
public class HsOfficeBankAccountEntity implements HasUuid, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
|
||||
.withProp(Fields.holder, HsOfficeBankAccountEntity::getHolder)
|
||||
|
@ -4,6 +4,7 @@ import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
@ -23,7 +24,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("Debitor")
|
||||
public class HsOfficeDebitorEntity implements Stringifyable {
|
||||
public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
|
||||
// TODO: I would rather like to generate something matching this example:
|
||||
// debitor(1234500: Test AG, tes)
|
||||
|
@ -5,6 +5,7 @@ import com.vladmihalcea.hibernate.type.range.Range;
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
@ -27,7 +28,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("Membership")
|
||||
public class HsOfficeMembershipEntity implements Stringifyable {
|
||||
public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficeMembershipEntity> stringify = stringify(HsOfficeMembershipEntity.class)
|
||||
.withProp(HsOfficeMembershipEntity::getMemberNumber)
|
||||
|
@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -19,7 +20,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("PartnerDetails")
|
||||
public class HsOfficePartnerDetailsEntity implements Stringifyable {
|
||||
public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
|
||||
HsOfficePartnerDetailsEntity.class,
|
||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -21,7 +22,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@AllArgsConstructor
|
||||
@FieldNameConstants
|
||||
@DisplayName("Person")
|
||||
public class HsOfficePersonEntity implements Stringifyable {
|
||||
public class HsOfficePersonEntity implements HasUuid, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
|
||||
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType)
|
||||
|
@ -3,8 +3,10 @@ package net.hostsharing.hsadminng.hs.office.relationship;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.util.UUID;
|
||||
@ -19,7 +21,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@FieldNameConstants
|
||||
public class HsOfficeRelationshipEntity {
|
||||
public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficeRelationshipEntity> toString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
||||
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
||||
@ -27,6 +29,11 @@ public class HsOfficeRelationshipEntity {
|
||||
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder)
|
||||
.withProp(Fields.contact, HsOfficeRelationshipEntity::getContact);
|
||||
|
||||
private static Stringify<HsOfficeRelationshipEntity> toShortString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
||||
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
||||
.withProp(Fields.relType, HsOfficeRelationshipEntity::getRelType)
|
||||
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder);
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private UUID uuid;
|
||||
@ -51,4 +58,9 @@ public class HsOfficeRelationshipEntity {
|
||||
public String toString() {
|
||||
return toString.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return toShortString.apply(this);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||
import net.hostsharing.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.*;
|
||||
@ -48,6 +49,7 @@ import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateR
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Fail.fail;
|
||||
|
||||
/*
|
||||
* This 'test' includes the complete legacy 'office' data import.
|
||||
@ -118,6 +120,8 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
private static NavigableMap<Integer, HsOfficeCoopSharesTransactionEntity> coopShares = new TreeMap<>();
|
||||
private static NavigableMap<Integer, HsOfficeCoopAssetsTransactionEntity> coopAssets = new TreeMap<>();
|
||||
|
||||
private static int personId = 900000;
|
||||
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
@ -187,24 +191,24 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
assertThat(partners.toString()).isEqualToIgnoringWhitespace("""
|
||||
{
|
||||
7=partner(Mellies, Michael: Herr Michael Mellies ),
|
||||
10=partner(JM e.K.: Frau Dr. Jenny Meyer , JM e.K.),
|
||||
10=partner(JM e.K.: Herr Philip Meyer-Contract , JM e.K.),
|
||||
12=partner(Test PS: Petra Schmidt , Test PS)
|
||||
}
|
||||
""");
|
||||
assertThat(contacts.toString()).isEqualToIgnoringWhitespace("""
|
||||
{
|
||||
71=contact(label='Herr Michael Mellies ', emailAddresses='mih@example.org'),
|
||||
101=contact(label='Frau Dr. Jenny Meyer , JM e.K.', emailAddresses='jm-billing@example.org'),
|
||||
102=contact(label='Herr Andrew Meyer , JM e.K.', emailAddresses='am-operation@example.org'),
|
||||
103=contact(label='Herr Philip Meyer , JM e.K.', emailAddresses='pm-contractual@example.org'),
|
||||
101=contact(label='Frau Dr. Jenny Meyer-Billing , JM e.K.', emailAddresses='jm-billing@example.org'),
|
||||
102=contact(label='Herr Andrew Meyer-Operation , JM e.K.', emailAddresses='am-operation@example.org'),
|
||||
103=contact(label='Herr Philip Meyer-Contract , JM e.K.', emailAddresses='pm-contractual@example.org'),
|
||||
121=contact(label='Petra Schmidt , Test PS', emailAddresses='ps@example.com')
|
||||
}
|
||||
""");
|
||||
assertThat(persons.toString()).isEqualToIgnoringWhitespace("""
|
||||
{
|
||||
7=person(personType='UNKNOWN', tradeName='', familyName='Mellies', givenName='Michael'),
|
||||
10=person(personType='UNKNOWN', tradeName='JM e.K.', familyName='Meyer', givenName='Jenny'),
|
||||
12=person(personType='UNKNOWN', tradeName='Test PS', familyName='Schmidt', givenName='Petra')
|
||||
900000=person(personType='UNKNOWN', tradeName='', familyName='Mellies', givenName='Michael'),
|
||||
900001=person(personType='UNKNOWN', tradeName='JM e.K.', familyName='Meyer-Contract', givenName='Philip'),
|
||||
900002=person(personType='UNKNOWN', tradeName='Test PS', familyName='Schmidt', givenName='Petra')
|
||||
}
|
||||
""");
|
||||
assertThat(debitors.toString()).isEqualToIgnoringWhitespace("""
|
||||
@ -221,6 +225,13 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
12=Membership(11012, Test PS, 1101200, [2021-04-01,), NONE)
|
||||
}
|
||||
""");
|
||||
assertThat(relationships.toString()).isEqualToIgnoringWhitespace("""
|
||||
{
|
||||
71=rel(relAnchor='Mellies, Michael', relType='TECHNICAL_CONTACT', relHolder='Mellies, Michael', contact='Herr Michael Mellies '),
|
||||
102=rel(relAnchor='JM e.K.', relType='TECHNICAL_CONTACT', relHolder='JM e.K.', contact='Herr Andrew Meyer-Operation , JM e.K.'),
|
||||
121=rel(relAnchor='Test PS', relType='TECHNICAL_CONTACT', relHolder='Test PS', contact='Petra Schmidt , Test PS')
|
||||
}
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -318,60 +329,79 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
contacts.forEach((id, contact) -> em.persist(contact));
|
||||
contacts.forEach(this::persist);
|
||||
updateLegacyIds(contacts, "hs_office_contact_legacy_id", "contact_id");
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
persons.forEach((id, person) -> em.persist(person));
|
||||
persons.forEach(this::persist);
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
partners.forEach((id, partner) -> em.persist(partner));
|
||||
partners.forEach(this::persist);
|
||||
updateLegacyIds(partners, "hs_office_partner_legacy_id", "bp_id");
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
debitors.forEach((id, debitor) -> em.persist(debitor));
|
||||
debitors.forEach(this::persist);
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
memberships.forEach((id, membership) -> em.persist(membership));
|
||||
memberships.forEach(this::persist);
|
||||
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
bankAccounts.forEach((id, account) -> em.persist(account));
|
||||
relationships.forEach(this::persist);
|
||||
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
sepaMandates.forEach((id, mandate) -> em.persist(mandate));
|
||||
bankAccounts.forEach(this::persist);
|
||||
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
sepaMandates.forEach(this::persist);
|
||||
updateLegacyIds(sepaMandates, "hs_office_sepamandate_legacy_id", "sepa_mandate_id");
|
||||
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
coopShares.forEach((id, shareTransaction) -> em.persist(shareTransaction));
|
||||
coopShares.forEach(this::persist);
|
||||
updateLegacyIds(coopShares, "hs_office_coopsharestransaction_legacy_id", "member_share_id");
|
||||
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
coopAssets.forEach((id, assetTransaction) -> em.persist(assetTransaction));
|
||||
coopAssets.forEach(this::persist);
|
||||
updateLegacyIds(coopShares, "hs_office_coopassetstransaction_legacy_id", "member_asset_id");
|
||||
}).assertSuccessful();
|
||||
|
||||
}
|
||||
|
||||
private void persist(final Integer id, final HasUuid entity) {
|
||||
try {
|
||||
System.out.println("persisting #" + entity.hashCode() + ": " + entity.toString());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
System.out.println("persisted #" + entity.hashCode() + " as " + entity.getUuid());
|
||||
} catch (Exception x) {
|
||||
System.out.println("failed to persist: " + entity.toString());
|
||||
throw x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void deleteTestDataFromHsOfficeTables() {
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
@ -474,12 +504,13 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
final var person = HsOfficePersonEntity.builder()
|
||||
.personType(HsOfficePersonType.UNKNOWN) // TODO
|
||||
.build();
|
||||
persons.put(rec.getInteger("bp_id"), person);
|
||||
// persons.put(rec.getInteger("bp_id"), person);
|
||||
persons.put(personId++, person);
|
||||
|
||||
final var partner = HsOfficePartnerEntity.builder()
|
||||
.debitorNumberPrefix(rec.getInteger("member_id"))
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.contact(HsOfficeContactEntity.builder().build())
|
||||
.contact(null) // is set during contacts import depending on assigned roles
|
||||
.person(person)
|
||||
.build();
|
||||
partners.put(rec.getInteger("bp_id"), partner);
|
||||
@ -489,7 +520,6 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
.debitorNumberSuffix((byte) 0)
|
||||
.defaultPrefix(rec.getString("member_code").replace("hsh00-", ""))
|
||||
.partner(partner)
|
||||
.billingContact(partner.getContact()) // TODO falsch
|
||||
.billable(rec.isEmpty("free"))
|
||||
.vatReverseCharge(rec.getBoolean("exempt_vat"))
|
||||
.vatBusiness("GROSS".equals(rec.getString("indicator_vat"))) // TODO: remove
|
||||
@ -627,7 +657,8 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
.map(this::trimAll)
|
||||
.map(row -> new Record(columns, row))
|
||||
.forEach(rec -> {
|
||||
if (isNotBlank(rec.getString("roles")) && rec.getString("roles").contains("billing")) {
|
||||
if (isNotBlank(rec.getString("roles"))) {
|
||||
final var contactId = rec.getInteger("contact_id");
|
||||
|
||||
final var partner = partners.get(rec.getInteger("bp_id"));
|
||||
final var debitor = debitors.get(rec.getInteger("bp_id"));
|
||||
@ -638,22 +669,31 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
person.setGivenName(rec.getString("first_name"));
|
||||
person.setFamilyName(rec.getString("last_name"));
|
||||
|
||||
if (rec.getString("roles").contains("contractual")) {
|
||||
initContact(partner.getContact(), rec);
|
||||
} else if (rec.getString("roles").contains("billing")) {
|
||||
initContact(debitor.getBillingContact(), rec);
|
||||
} else if (rec.getString("roles").contains("operation")) {
|
||||
// TODO: technical contact initContact(debitor.getBillingContact(), rec);
|
||||
}
|
||||
final var contact = HsOfficeContactEntity.builder().build();
|
||||
contacts.put(contactId, initContact(contact, rec));
|
||||
|
||||
if (rec.getString("roles").contains("contractual")) {
|
||||
partner.setContact(contact);
|
||||
}
|
||||
if (rec.getString("roles").contains("billing")) {
|
||||
debitor.setBillingContact(contact);
|
||||
}
|
||||
if (rec.getString("roles").contains("operation")) {
|
||||
final var rel = HsOfficeRelationshipEntity.builder()
|
||||
.relAnchor(partner.getPerson())
|
||||
.relHolder(person)
|
||||
.contact(contact)
|
||||
.relType(HsOfficeRelationshipType.TECHNICAL_CONTACT)
|
||||
.build();
|
||||
relationships.put(contactId, rel);
|
||||
}
|
||||
} else {
|
||||
initContact(new HsOfficeContactEntity(), rec);
|
||||
// TODO: create relationship
|
||||
fail("contact without role: " + rec);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initContact(final HsOfficeContactEntity contact, final Record rec) {
|
||||
private HsOfficeContactEntity initContact(final HsOfficeContactEntity contact, final Record rec) {
|
||||
contacts.put(rec.getInteger("contact_id"), contact);
|
||||
|
||||
contact.setLabel(toLabel(
|
||||
@ -665,6 +705,7 @@ public class ImportOfficeTables extends ContextBasedTest {
|
||||
contact.setEmailAddresses(rec.getString("email"));
|
||||
contact.setPostalAddress(toAddress(rec));
|
||||
contact.setPhoneNumbers(toPhoneNumbers(rec));
|
||||
return contact;
|
||||
}
|
||||
|
||||
private String[] trimAll(final String[] record) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
contact_id; bp_id; salut; first_name; last_name; title; firma; co; street; zipcode;city; country; phone_private; phone_office; phone_mobile; fax; email; roles
|
||||
71; 7; Herr; Michael; Mellies; ; ; ; Kleine Freiheit 50; 26524; Hage; DE; ; +49 4931 123456; +49 1522 123456;; mih@example.org; contractual,billing,operation
|
||||
101; 10; Frau; Jenny; Meyer; Dr.; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 7777777; +49 30 1111111; ; +49 30 2222222; jm-billing@example.org; billing
|
||||
102; 10; Herr; Andrew; Meyer; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 3333333; ; +49 30 4444444; am-operation@example.org; operation
|
||||
103; 10; Herr; Philip; Meyer; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; pm-contractual@example.org; contractual
|
||||
101; 10; Frau; Jenny; Meyer-Billing; Dr.; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 7777777; +49 30 1111111; ; +49 30 2222222; jm-billing@example.org; billing
|
||||
102; 10; Herr; Andrew; Meyer-Operation; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 3333333; ; +49 30 4444444; am-operation@example.org; operation
|
||||
103; 10; Herr; Philip; Meyer-Contract; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; pm-contractual@example.org; contractual
|
||||
121; 12; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; billing,contractual,operation
|
||||
|
|
Loading…
Reference in New Issue
Block a user