Compare commits

...

4 Commits

Author SHA1 Message Date
Michael Hoennig
d34e1f9e14 improve test coverage 2024-01-24 15:56:34 +01:00
Michael Hoennig
4ca89df6fd amendmends according to code review and rebasing aftermaths 2024-01-24 15:49:08 +01:00
Michael Hoennig
c16143acbd Merge remote-tracking branch 'origin/master' into memberNumberSuffix-and-partnerNumber
# Conflicts:
#	src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java
#	src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java
#	src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java
#	src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java
#	src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java
#	src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java
2024-01-24 15:19:46 +01:00
f150ea2091 more detailed person type (#12)
Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: #12
Reviewed-by: Michael Hierweck <michael.hierweck@hostsharing.net>
2024-01-24 15:18:44 +01:00
35 changed files with 234 additions and 159 deletions

View File

@ -60,7 +60,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUu
private int shareCount;
/**
* The ooking reference.
* The Booking reference.
*/
@Column(name = "reference")
private String reference;

View File

@ -35,7 +35,6 @@ public class HsOfficePersonEntity implements HasUuid, Stringifyable {
private UUID uuid;
@Column(name = "persontype")
@Enumerated(EnumType.STRING)
private HsOfficePersonType personType;
@Column(name = "tradename")

View File

@ -1,9 +1,21 @@
package net.hostsharing.hsadminng.hs.office.person;
public enum HsOfficePersonType {
UNKNOWN,
NATURAL,
LEGAL,
SOLE_REPRESENTATION,
JOINT_REPRESENTATION
UNKNOWN_PERSON_TYPE("??"),
NATURAL_PERSON("NP"), // a human being
LEGAL_PERSON("LP"), // incorporated legal entity like A/S, GmbH, e.K., eG, e.V.
INCORPORATED_FIRM("IF"), // registered business partnership like OHG, Partnerschaftsgesellschaft
UNINCORPORATED_FIRM("UF"), // unregistered partnership, association etc. like GbR, ARGE, community of heirs
PUBLIC_INSTITUTION("PI"); // entities under public law like government entities, KdöR, AöR
public final String shortName;
HsOfficePersonType(final String shortName) {
this.shortName = shortName;
}
@Override
public String toString() {
return shortName;
}
}

View File

@ -0,0 +1,29 @@
package net.hostsharing.hsadminng.hs.office.person;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.util.stream.Stream;
@Converter(autoApply = true)
public class HsOfficePersonTypeConverter implements AttributeConverter<HsOfficePersonType, String> {
@Override
public String convertToDatabaseColumn(HsOfficePersonType category) {
if (category == null) {
return null;
}
return category.shortName;
}
@Override
public HsOfficePersonType convertToEntityAttribute(String code) {
if (code == null) {
return null;
}
return Stream.of(HsOfficePersonType.values())
.filter(c -> c.shortName.equals(code))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}

View File

@ -6,10 +6,12 @@ components:
HsOfficePersonType:
type: string
enum:
- NATURAL # a human
- LEGAL # e.g. Corp., Inc., AG, GmbH, eG
- SOLE_REPRESENTATION # e.g. OHG, GbR
- JOINT_REPRESENTATION # e.g. community of heirs
- UNKNOWN_PERSON
- NATURAL_PERSON
- LEGAL_PERSON
- INCORPORATED_FIRM
- UNINCORPORATED_FIRM
- PUBLIC_INSTITUTION
HsOfficePerson:
type: object

View File

@ -770,8 +770,8 @@ do $$
if '${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}'='restricted' then
create role restricted;
grant all privileges on all tables in schema public to restricted;
end if;
-- grant all privileges on all tables in schema public to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
end $$
--//

View File

@ -4,7 +4,13 @@
--changeset hs-office-person-MAIN-TABLE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE TYPE HsOfficePersonType AS ENUM ('UNKNOWN', 'NATURAL', 'LEGAL', 'SOLE_REPRESENTATION', 'JOINT_REPRESENTATION');
CREATE TYPE HsOfficePersonType AS ENUM (
'??', -- unknown
'NP', -- natural person
'LP', -- legal person
'IF', -- incorporated firm
'UF', -- unincorporated firm
'PI'); -- public institution
CREATE CAST (character varying as HsOfficePersonType) WITH INOUT AS IMPLICIT;

View File

@ -59,14 +59,14 @@ end; $$;
do language plpgsql $$
begin
call createHsOfficePersonTestData('LEGAL', 'First GmbH');
call createHsOfficePersonTestData('NATURAL', null, 'Smith', 'Peter');
call createHsOfficePersonTestData('LEGAL', 'Second e.K.', 'Sandra', 'Miller');
call createHsOfficePersonTestData('SOLE_REPRESENTATION', 'Third OHG');
call createHsOfficePersonTestData('SOLE_REPRESENTATION', 'Fourth e.G.');
call createHsOfficePersonTestData('JOINT_REPRESENTATION', 'Erben Bessler', 'Mel', 'Bessler');
call createHsOfficePersonTestData('NATURAL', null, 'Bessler', 'Anita');
call createHsOfficePersonTestData('NATURAL', null, 'Winkler', 'Paul');
call createHsOfficePersonTestData('LP', 'First GmbH');
call createHsOfficePersonTestData('NP', null, 'Smith', 'Peter');
call createHsOfficePersonTestData('LP', 'Second e.K.', 'Sandra', 'Miller');
call createHsOfficePersonTestData('IF', 'Third OHG');
call createHsOfficePersonTestData('IF', 'Fourth e.G.');
call createHsOfficePersonTestData('UF', 'Erben Bessler', 'Mel', 'Bessler');
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Anita');
call createHsOfficePersonTestData('NP', null, 'Winkler', 'Paul');
end;
$$;
--//

View File

@ -179,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$
partnerNumber = new.partnerNumber,
personUuid = new.personUuid,
contactUuid = new.contactUuid
$updates$);

View File

@ -19,7 +19,6 @@ declare
relatedPerson hs_office_person;
relatedContact hs_office_contact;
relatedDetailsUuid uuid;
birthday date;
begin
idName := cleanIdentifier( personTradeOrFamilyName|| '-' || contactLabel);
currentTask := 'creating partner test-data ' || idName;
@ -33,18 +32,14 @@ begin
where c.label = contactLabel
into relatedContact;
if relatedPerson.persontype = 'NATURAL' then
birthday := '1987-10-31'::date;
end if;
raise notice 'creating test partner: %', idName;
raise notice '- using person (%): %', relatedPerson.uuid, relatedPerson;
raise notice '- using contact (%): %', relatedContact.uuid, relatedContact;
if relatedPerson.persontype = 'NATURAL' then
if relatedPerson.persontype = 'NP' then
insert
into hs_office_partner_details (uuid, birthName, birthday)
values (uuid_generate_v4(), 'Meyer', '1987-10-31')
into hs_office_partner_details (uuid, birthName, birthday, birthPlace)
values (uuid_generate_v4(), 'Meyer', '1987-10-31', 'Hamburg')
returning uuid into relatedDetailsUuid;
else
insert

View File

@ -17,7 +17,9 @@ create table if not exists hs_office_membership
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)
);
--//

View File

@ -72,7 +72,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest {
}
@Test
void globalAdmin_canFindCoopAssetsTransactionsByMemberNumberSuffix() {
void globalAdmin_canFindCoopAssetsTransactionsByMemberNumber() {
context.define("superuser-alex@hostsharing.net");
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202);
@ -114,7 +114,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest {
}
@Test
void globalAdmin_canFindCoopAssetsTransactionsByMemberNumberSuffixAndDateRange() {
void globalAdmin_canFindCoopAssetsTransactionsByMembershipUuidAndDateRange() {
context.define("superuser-alex@hostsharing.net");
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202);

View File

@ -72,7 +72,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest {
}
@Test
void globalAdmin_canFindCoopSharesTransactionsByMemberNumberSuffix() {
void globalAdmin_canFindCoopSharesTransactionsByMemberNumber() {
context.define("superuser-alex@hostsharing.net");
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000202);
@ -106,13 +106,14 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest {
}
@Test
void globalAdmin_canFindCoopSharesTransactionsByMemberNumberSuffixAndDateRange() {
void globalAdmin_canFindCoopSharesTransactionsByMembershipUuidAndDateRange() {
context.define("superuser-alex@hostsharing.net");
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",

View File

@ -83,7 +83,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
{
"debitorNumber": 1000111,
"debitorNumberSuffix": 11,
"partner": { "person": { "personType": "LEGAL" } },
"partner": { "person": { "personType": "LEGAL_PERSON" } },
"billingContact": { "label": "first contact" },
"vatId": null,
"vatCountryCode": null,

View File

@ -104,12 +104,6 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
HsOfficeDebitorEntity::setBillingContact,
newBillingContact(PATCHED_CONTACT_UUID))
.notNullable(),
new SimpleProperty<>(
"personType",
HsOfficeDebitorPatchResource::setBillable,
PATCHED_BILLABLE,
HsOfficeDebitorEntity::setBillable)
.notNullable(),
new SimpleProperty<>(
"billable",
HsOfficeDebitorPatchResource::setBillable,

View File

@ -17,7 +17,7 @@ class HsOfficeDebitorEntityUnitTest {
.debitorNumberSuffix((byte)67)
.partner(HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.build())
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
@ -29,7 +29,7 @@ class HsOfficeDebitorEntityUnitTest {
final var result = given.toString();
assertThat(result).isEqualTo("debitor(D-1234567: LEGAL some trade name: som)");
assertThat(result).isEqualTo("debitor(D-1234567: LP some trade name: som)");
}
@Test

View File

@ -211,9 +211,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// then
allTheseDebitorsAreReturned(
result,
"debitor(D-1000111: LEGAL First GmbH: fir)",
"debitor(D-1000212: LEGAL Second e.K.: sec)",
"debitor(D-1000313: SOLE_REPRESENTATION 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(D-1000111: LEGAL First GmbH: fir)",
"debitor(D-1000120: LEGAL 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(D-1000313: SOLE_REPRESENTATION 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(D-1000313: SOLE_REPRESENTATION Third OHG: thi)");
exactlyTheseDebitorsAreReturned(result, "debitor(D-1000313: IF Third OHG: thi)");
}
}

View File

@ -345,7 +345,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
assertThat(mandate.getPartner().toShortString()).isEqualTo("LP First GmbH");
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
@ -388,7 +388,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
assertThat(mandate.getPartner().toShortString()).isEqualTo("LP First GmbH");
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");

View File

@ -27,7 +27,7 @@ class HsOfficeMembershipEntityUnitTest {
@Test
void toStringContainsAllProps() {
final var result = givenMembership.toString();
assertThat(result).isEqualTo("Membership(M-1000101, LEGAL Test Ltd., D-1000100, [2020-01-01,))");
assertThat(result).isEqualTo("Membership(M-1000101, LP Test Ltd., D-1000100, [2020-01-01,))");
}
@Test

View File

@ -77,7 +77,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// when
final var result = attempt(em, () -> {
final var newMembership = toCleanup(HsOfficeMembershipEntity.builder()
.memberNumberSuffix("01")
.memberNumberSuffix("11")
.partner(givenPartner)
.mainDebitor(givenDebitor)
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
@ -184,9 +184,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseMembershipsAreReturned(
result,
"Membership(M-1000101, LEGAL First GmbH, D-1000111, [2022-10-01,), NONE)",
"Membership(M-1000202, LEGAL Second e.K., D-1000212, [2022-10-01,), NONE)",
"Membership(M-1000303, SOLE_REPRESENTATION Third OHG, D-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
@ -200,7 +200,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseMembershipsAreReturned(result,
"Membership(M-1000101, LEGAL First GmbH, D-1000111, [2022-10-01,), NONE)");
"Membership(M-1000101, LP First GmbH, D-1000111, [2022-10-01,), NONE)");
}
@Test
@ -215,7 +215,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
assertThat(result)
.isNotNull()
.extracting(Object::toString)
.isEqualTo("Membership(M-1000202, LEGAL Second e.K., D-1000212, [2022-10-01,), NONE)");
.isEqualTo("Membership(M-1000202, LP Second e.K., D-1000212, [2022-10-01,), NONE)");
}
}

View File

@ -208,9 +208,9 @@ public class ImportOfficeData extends ContextBasedTest {
assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace("""
{
17=partner(NATURAL Mellies, Michael: Herr Michael Mellies ),
20=partner(LEGAL JM GmbH: Herr Philip Meyer-Contract , JM GmbH),
22=partner(LEGAL Test PS: Petra Schmidt , Test PS)
17=partner(NP Mellies, Michael: Herr Michael Mellies ),
20=partner(LP JM GmbH: Herr Philip Meyer-Contract , JM GmbH),
22=partner(?? Test PS: Petra Schmidt , Test PS)
}
""");
assertThat(toFormattedString(contacts)).isEqualToIgnoringWhitespace("""
@ -225,39 +225,39 @@ public class ImportOfficeData extends ContextBasedTest {
""");
assertThat(toFormattedString(persons)).isEqualToIgnoringWhitespace("""
{
1101=person(personType='NATURAL', tradeName='', familyName='Mellies', givenName='Michael'),
1200=person(personType='LEGAL', tradeName='JM e.K.', familyName='', givenName=''),
1201=person(personType='LEGAL', tradeName='JM GmbH', familyName='Meyer-Billing', givenName='Jenny'),
1202=person(personType='LEGAL', tradeName='JM GmbH', familyName='Meyer-Operation', givenName='Andrew'),
1203=person(personType='LEGAL', tradeName='JM GmbH', familyName='Meyer-Contract', givenName='Philip'),
1301=person(personType='LEGAL', tradeName='Test PS', familyName='Schmidt', givenName='Petra')
1101=person(personType='NP', tradeName='', familyName='Mellies', givenName='Michael'),
1200=person(personType='LP', tradeName='JM e.K.', familyName='', givenName=''),
1201=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Billing', givenName='Jenny'),
1202=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Operation', givenName='Andrew'),
1203=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Contract', givenName='Philip'),
1301=person(personType='??', tradeName='Test PS', familyName='Schmidt', givenName='Petra')
}
""");
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
{
17=debitor(D-1001700: NATURAL Mellies, Michael: mih),
20=debitor(D-1002000: LEGAL JM GmbH: xyz),
22=debitor(D-1102200: LEGAL 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(M-1001700, NATURAL Mellies, Michael, D-1001700, [2000-12-06,), NONE),
20=Membership(M-1002000, LEGAL JM GmbH, D-1002000, [2000-12-06,2016-01-01), UNKNOWN),
22=Membership(M-1102200, LEGAL Test PS, D-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("""
{
2000000=rel(relAnchor='NATURAL Mellies, Michael', relType='OPERATIONS', relHolder='NATURAL Mellies, Michael', contact='Herr Michael Mellies '),
2000001=rel(relAnchor='LEGAL JM GmbH', relType='EX_PARTNER', relHolder='LEGAL JM e.K.', contact='JM e.K.'),
2000002=rel(relAnchor='LEGAL JM GmbH', relType='OPERATIONS', relHolder='LEGAL JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
2000003=rel(relAnchor='LEGAL JM GmbH', relType='VIP_CONTACT', relHolder='LEGAL JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
2000004=rel(relAnchor='LEGAL JM GmbH', relType='REPRESENTATIVE', relHolder='LEGAL JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
2000005=rel(relAnchor='LEGAL Test PS', relType='OPERATIONS', relHolder='LEGAL Test PS', contact='Petra Schmidt , Test PS'),
2000006=rel(relAnchor='LEGAL Test PS', relType='REPRESENTATIVE', relHolder='LEGAL Test PS', contact='Petra Schmidt , Test PS'),
2000007=rel(relAnchor='NATURAL Mellies, Michael', relType='REPRESENTATIVE', relHolder='NATURAL Mellies, Michael', contact='Herr Michael Mellies ')
}
2000000=rel(relAnchor='NP Mellies, Michael', relType='OPERATIONS', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
2000001=rel(relAnchor='LP JM GmbH', relType='EX_PARTNER', relHolder='LP JM e.K.', contact='JM e.K.'),
2000002=rel(relAnchor='LP JM GmbH', relType='OPERATIONS', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
2000003=rel(relAnchor='LP JM GmbH', relType='VIP_CONTACT', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
2000004=rel(relAnchor='LP JM GmbH', relType='REPRESENTATIVE', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
2000005=rel(relAnchor='?? Test PS', relType='OPERATIONS', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
2000006=rel(relAnchor='?? Test PS', relType='REPRESENTATIVE', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
2000007=rel(relAnchor='NP Mellies, Michael', relType='REPRESENTATIVE', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies ')
}
""");
}
@ -794,17 +794,22 @@ public class ImportOfficeData extends ContextBasedTest {
private static void determinePersonType(final HsOfficePersonEntity person, final String roles) {
if (person.getTradeName().isBlank()) {
person.setPersonType(HsOfficePersonType.NATURAL);
} else if (roles.contains("partner")) {
person.setPersonType(HsOfficePersonType.LEGAL);
} else if (roles.contains("contractual") &&
person.setPersonType(HsOfficePersonType.NATURAL_PERSON);
} else
// contractual && !partner with a firm and a natural person name
// should actually be split up into two persons
// but the legacy database consists such records
if (roles.contains("contractual") && !roles.contains("partner") &&
!person.getFamilyName().isBlank() && !person.getGivenName().isBlank()) {
person.setPersonType(HsOfficePersonType.NATURAL);
person.setPersonType(HsOfficePersonType.NATURAL_PERSON);
} else if ( endsWithWord(person.getTradeName(), "e.K.", "e.G.", "eG", "GmbH", "AG") ) {
person.setPersonType(HsOfficePersonType.LEGAL);
person.setPersonType(HsOfficePersonType.LEGAL_PERSON);
} else if ( endsWithWord(person.getTradeName(), "OHG") ) {
person.setPersonType(HsOfficePersonType.INCORPORATED_FIRM);
} else if ( endsWithWord(person.getTradeName(), "GbR") ) {
person.setPersonType(HsOfficePersonType.INCORPORATED_FIRM);
} else {
// TODO: detect the other person types as soon as we've switche to the new person types
person.setPersonType(HsOfficePersonType.UNKNOWN);
person.setPersonType(HsOfficePersonType.UNKNOWN_PERSON_TYPE);
}
}
@ -1030,10 +1035,7 @@ class OrderedDependedTestsExtension implements TestWatcher, BeforeEachCallback {
}
@Override
public void beforeEach(final ExtensionContext extensionContext) {
if (!previousTestsPassed) {
System.err.println("ignoring because previous fest has failed");
}
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
assumeThat(previousTestsPassed).isTrue();
}
}

View File

@ -97,7 +97,7 @@ class HsOfficePartnerControllerAcceptanceTest {
"details": { "registrationOffice": "Hamburg" }
},
{
"person": { "personType": "SOLE_REPRESENTATION" },
"person": { "personType": "INCORPORATED_FIRM" },
"contact": { "label": "forth contact" },
"details": { "registrationOffice": "Hamburg" }
}

View File

@ -13,7 +13,7 @@ class HsOfficePartnerEntityUnitTest {
void toStringContainsPersonAndContact() {
final var given = HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
@ -21,14 +21,14 @@ class HsOfficePartnerEntityUnitTest {
final var result = given.toString();
assertThat(result).isEqualTo("partner(LEGAL some trade name: some label)");
assertThat(result).isEqualTo("partner(LP some trade name: some label)");
}
@Test
void toShortStringContainsPersonAndContact() {
final var given = HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
@ -36,6 +36,6 @@ class HsOfficePartnerEntityUnitTest {
final var result = given.toShortString();
assertThat(result).isEqualTo("LEGAL some trade name");
assertThat(result).isEqualTo("LP some trade name");
}
}

View File

@ -177,9 +177,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
// then
allThesePartnersAreReturned(
result,
"partner(SOLE_REPRESENTATION Third OHG: third contact)",
"partner(LEGAL Second e.K.: second contact)",
"partner(LEGAL First GmbH: first contact)");
"partner(IF Third OHG: third contact)",
"partner(LP Second e.K.: second contact)",
"partner(LP First GmbH: first contact)");
}
@Test
@ -191,7 +191,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
// then:
exactlyThesePartnersAreReturned(result, "partner(LEGAL First GmbH: first contact)");
exactlyThesePartnersAreReturned(result, "partner(LP First GmbH: first contact)");
}
}
@ -207,7 +207,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
// then
exactlyThesePartnersAreReturned(result, "partner(SOLE_REPRESENTATION Third OHG: third contact)");
exactlyThesePartnersAreReturned(result, "partner(IF Third OHG: third contact)");
}
}
@ -226,7 +226,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
assertThat(result)
.isNotNull()
.extracting(Object::toString)
.isEqualTo("partner(LEGAL First GmbH: first contact)");
.isEqualTo("partner(LP First GmbH: first contact)");
}
}

View File

@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL;
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
public class TestHsOfficePartner {
@ -14,7 +14,7 @@ public class TestHsOfficePartner {
return HsOfficePartnerEntity.builder()
.partnerNumber(10001)
.person(HsOfficePersonEntity.builder()
.personType(LEGAL)
.personType(LEGAL_PERSON)
.tradeName(tradeName)
.build())
.contact(HsOfficeContactEntity.builder()

View File

@ -69,49 +69,49 @@ class HsOfficePersonControllerAcceptanceTest {
.body("", lenientlyEquals("""
[
{
"personType": "LEGAL",
"personType": "LEGAL_PERSON",
"tradeName": "First GmbH",
"givenName": null,
"familyName": null
},
{
"personType": "LEGAL",
"personType": "LEGAL_PERSON",
"tradeName": "Second e.K.",
"givenName": "Miller",
"familyName": "Sandra"
},
{
"personType": "SOLE_REPRESENTATION",
"personType": "INCORPORATED_FIRM",
"tradeName": "Third OHG",
"givenName": null,
"familyName": null
},
{
"personType": "SOLE_REPRESENTATION",
"personType": "INCORPORATED_FIRM",
"tradeName": "Fourth e.G.",
"givenName": null,
"familyName": null
},
{
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"tradeName": null,
"givenName": "Anita",
"familyName": "Bessler"
},
{
"personType": "JOINT_REPRESENTATION",
"personType": "UNINCORPORATED_FIRM",
"tradeName": "Erben Bessler",
"givenName": "Bessler",
"familyName": "Mel"
},
{
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"tradeName": null,
"givenName": "Peter",
"familyName": "Smith"
},
{
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"tradeName": null,
"givenName": "Paul",
"familyName": "Winkler"
@ -136,7 +136,7 @@ class HsOfficePersonControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("""
{
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"familyName": "Tester",
"givenName": "Temp Testi"
}
@ -148,7 +148,7 @@ class HsOfficePersonControllerAcceptanceTest {
.statusCode(201)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("personType", is("NATURAL"))
.body("personType", is("NATURAL_PERSON"))
.body("familyName", is("Tester"))
.body("givenName", is("Temp Testi"))
.header("Location", startsWith("http://localhost"))
@ -224,7 +224,7 @@ class HsOfficePersonControllerAcceptanceTest {
.contentType("application/json")
.body("", lenientlyEquals("""
{
"personType": "JOINT_REPRESENTATION",
"personType": "UNINCORPORATED_FIRM",
"tradeName": "Erben Bessler",
"givenName": "Bessler",
"familyName": "Mel"
@ -249,7 +249,7 @@ class HsOfficePersonControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("""
{
"personType": "JOINT_REPRESENTATION",
"personType": "UNINCORPORATED_FIRM",
"tradeName": "Temp Trade Name - patched",
"familyName": "Temp Family Name - patched",
"givenName": "Temp Given Name - patched"
@ -262,7 +262,7 @@ class HsOfficePersonControllerAcceptanceTest {
.statusCode(200)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("personType", is("JOINT_REPRESENTATION"))
.body("personType", is("UNINCORPORATED_FIRM"))
.body("tradeName", is("Temp Trade Name - patched"))
.body("familyName", is("Temp Family Name - patched"))
.body("givenName", is("Temp Given Name - patched"));
@ -272,7 +272,7 @@ class HsOfficePersonControllerAcceptanceTest {
context.define("superuser-alex@hostsharing.net");
assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get()
.matches(person -> {
assertThat(person.getPersonType()).isEqualTo(HsOfficePersonType.JOINT_REPRESENTATION);
assertThat(person.getPersonType()).isEqualTo(HsOfficePersonType.UNINCORPORATED_FIRM);
assertThat(person.getTradeName()).isEqualTo("Temp Trade Name - patched");
assertThat(person.getFamilyName()).isEqualTo("Temp Family Name - patched");
assertThat(person.getGivenName()).isEqualTo("Temp Given Name - patched");
@ -302,7 +302,7 @@ class HsOfficePersonControllerAcceptanceTest {
.statusCode(200)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("personType", is(givenPerson.getPersonType().toString()))
.body("personType", is(givenPerson.getPersonType().name()))
.body("tradeName", is(givenPerson.getTradeName()))
.body("familyName", is("Temp Family Name - patched"))
.body("givenName", is("Temp Given Name - patched"));
@ -389,7 +389,7 @@ class HsOfficePersonControllerAcceptanceTest {
context.define(creatingUser);
final var newPerson = HsOfficePersonEntity.builder()
.uuid(UUID.randomUUID())
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2))
.familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org")
.givenName("Temp Given Name " + RandomStringUtils.randomAlphabetic(10))

View File

@ -22,7 +22,7 @@ class HsOfficePersonEntityPatcherUnitTest extends PatchUnitTestBase<
protected HsOfficePersonEntity newInitialEntity() {
final var entity = new HsOfficePersonEntity();
entity.setUuid(INITIAL_PERSON_UUID);
entity.setPersonType(HsOfficePersonType.LEGAL);
entity.setPersonType(HsOfficePersonType.LEGAL_PERSON);
entity.setTradeName("initial@example.org");
entity.setFamilyName("initial postal address");
entity.setGivenName("+01 100 123456789");
@ -45,9 +45,9 @@ class HsOfficePersonEntityPatcherUnitTest extends PatchUnitTestBase<
new SimpleProperty<>(
"personType",
HsOfficePersonPatchResource::setPersonType,
HsOfficePersonTypeResource.SOLE_REPRESENTATION,
HsOfficePersonTypeResource.INCORPORATED_FIRM,
HsOfficePersonEntity::setPersonType,
HsOfficePersonType.SOLE_REPRESENTATION)
HsOfficePersonType.INCORPORATED_FIRM)
.notNullable(),
new JsonNullableProperty<>(
"tradeName",

View File

@ -11,32 +11,32 @@ class HsOfficePersonEntityUnitTest {
@Test
void getDisplayReturnsTradeNameIfAvailable() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
assertThat(actualDisplay).isEqualTo("LP some trade name");
}
@Test
void getDisplayReturnsFamilyAndGivenNameIfNoTradeNameAvailable() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.personType(HsOfficePersonType.NATURAL_PERSON)
.familyName("some family name")
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
assertThat(actualDisplay).isEqualTo("NP some family name, some given name");
}
@Test
void toShortStringWithTradeNameReturnsTradeName() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.familyName("some family name")
.givenName("some given name")
@ -44,27 +44,27 @@ class HsOfficePersonEntityUnitTest {
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
assertThat(actualDisplay).isEqualTo("LP some trade name");
}
@Test
void toShortStringWithoutTradeNameReturnsFamilyAndGivenName() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.personType(HsOfficePersonType.NATURAL_PERSON)
.familyName("some family name")
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
assertThat(actualDisplay).isEqualTo("NP some family name, some given name");
}
@Test
void toStringWithAllFieldsReturnsAllButUuid() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.uuid(UUID.randomUUID())
.personType(HsOfficePersonType.NATURAL)
.personType(HsOfficePersonType.NATURAL_PERSON)
.tradeName("some trade name")
.familyName("some family name")
.givenName("some given name")
@ -72,7 +72,7 @@ class HsOfficePersonEntityUnitTest {
final var actualDisplay = givenPersonEntity.toString();
assertThat(actualDisplay).isEqualTo("person(personType='NATURAL', tradeName='some trade name', familyName='some family name', givenName='some given name')");
assertThat(actualDisplay).isEqualTo("person(personType='NP', tradeName='some trade name', familyName='some family name', givenName='some given name')");
}
@Test

View File

@ -144,10 +144,10 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTest {
// then
allThesePersonsAreReturned(
result,
"NATURAL Smith, Peter",
"LEGAL Second e.K.",
"SOLE_REPRESENTATION Third OHG",
"JOINT_REPRESENTATION Erben Bessler");
"NP Smith, Peter",
"LP Second e.K.",
"IF Third OHG",
"UF Erben Bessler");
}
@Test

View File

@ -0,0 +1,34 @@
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;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
class HsOfficePersonTypeConverterUnitTest {
final HsOfficePersonTypeConverter converter = new HsOfficePersonTypeConverter();
@ParameterizedTest
@EnumSource(HsOfficePersonType.class)
void mapsToDatabaseValue(final HsOfficePersonType given) {
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);
}
}

View File

@ -7,7 +7,7 @@ public class TestHsOfficePerson {
static public HsOfficePersonEntity hsOfficePerson(final String tradeName) {
return HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.personType(HsOfficePersonType.NATURAL_PERSON)
.tradeName(tradeName)
.build();
}

View File

@ -83,11 +83,11 @@ class HsOfficeRelationshipControllerAcceptanceTest {
[
{
"relAnchor": {
"personType": "SOLE_REPRESENTATION",
"personType": "INCORPORATED_FIRM",
"tradeName": "Third OHG"
},
"relHolder": {
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"givenName": "Peter",
"familyName": "Smith"
},
@ -96,13 +96,13 @@ class HsOfficeRelationshipControllerAcceptanceTest {
},
{
"relAnchor": {
"personType": "LEGAL",
"personType": "LEGAL_PERSON",
"tradeName": "Second e.K.",
"givenName": "Miller",
"familyName": "Sandra"
},
"relHolder": {
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"givenName": "Peter",
"familyName": "Smith"
},
@ -111,11 +111,11 @@ class HsOfficeRelationshipControllerAcceptanceTest {
},
{
"relAnchor": {
"personType": "LEGAL",
"personType": "LEGAL_PERSON",
"tradeName": "First GmbH"
},
"relHolder": {
"personType": "NATURAL",
"personType": "NATURAL_PERSON",
"tradeName": null,
"givenName": "Peter",
"familyName": "Smith"

View File

@ -10,11 +10,11 @@ import static org.junit.jupiter.api.Assertions.*;
class HsOfficeRelationshipEntityUnitTest {
private HsOfficePersonEntity anchor = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.build();
private HsOfficePersonEntity holder = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.personType(HsOfficePersonType.NATURAL_PERSON)
.familyName("Meier")
.givenName("Mellie")
.build();
@ -27,6 +27,6 @@ class HsOfficeRelationshipEntityUnitTest {
.relHolder(holder)
.build();
assertThat(given.toShortString()).isEqualTo("rel(relAnchor='LEGAL some trade name', relType='REPRESENTATIVE', relHolder='NATURAL Meier, Mellie')");
assertThat(given.toShortString()).isEqualTo("rel(relAnchor='LP some trade name', relType='REPRESENTATIVE', relHolder='NP Meier, Mellie')");
}
}

View File

@ -159,9 +159,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then
allTheseRelationshipsAreReturned(
result,
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')",
"rel(relAnchor='SOLE_REPRESENTATION Third OHG', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='third contact')",
"rel(relAnchor='LEGAL Second e.K.', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='second contact')");
"rel(relAnchor='LP First GmbH', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='first contact')",
"rel(relAnchor='IF Third OHG', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='third contact')",
"rel(relAnchor='LP Second e.K.', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='second contact')");
}
@Test
@ -176,7 +176,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then:
exactlyTheseRelationshipsAreReturned(
result,
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')");
"rel(relAnchor='LP First GmbH', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='first contact')");
}
}

View File

@ -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(D-1000111: LEGAL 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(D-1000111: LEGAL 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)");