1
0

initial data import for hs-office tables (db-migration #10)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Co-authored-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/10
Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-01-23 15:11:23 +01:00
parent e427bb1784
commit fd1bd897b1
98 changed files with 2278 additions and 471 deletions

View File

@@ -30,16 +30,17 @@ public class ArchitectureTest {
"..test.pac",
"..context",
"..generated..",
"..hs.office.person",
"..hs.office.partner",
"..hs.office.bankaccount",
"..hs.office.debitor",
"..hs.office.relationship",
"..hs.office.contact",
"..hs.office.sepamandate",
"..hs.office.coopassets",
"..hs.office.coopshares",
"..hs.office.debitor",
"..hs.office.membership",
"..hs.office.migration",
"..hs.office.partner",
"..hs.office.person",
"..hs.office.relationship",
"..hs.office.sepamandate",
"..errors",
"..mapper",
"..ping",
@@ -121,14 +122,19 @@ public class ArchitectureTest {
public static final ArchRule hsOfficeBankAccountPackageRule = classes()
.that().resideInAPackage("..hs.office.bankaccount..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.bankaccount..", "..hs.office.sepamandate..", "..hs.office.debitor..");
.resideInAnyPackage("..hs.office.bankaccount..",
"..hs.office.sepamandate..",
"..hs.office.debitor..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficeSepaMandatePackageRule = classes()
.that().resideInAPackage("..hs.office.sepamandate..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.sepamandate..", "..hs.office.debitor..");
.resideInAnyPackage("..hs.office.sepamandate..",
"..hs.office.debitor..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
@@ -136,7 +142,10 @@ public class ArchitectureTest {
.that().resideInAPackage("..hs.office.contact..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.contact..", "..hs.office.relationship..",
"..hs.office.partner..", "..hs.office.debitor..", "..hs.office.membership..");
"..hs.office.partner..",
"..hs.office.debitor..",
"..hs.office.membership..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
@@ -144,42 +153,63 @@ public class ArchitectureTest {
.that().resideInAPackage("..hs.office.person..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.person..", "..hs.office.relationship..",
"..hs.office.partner..", "..hs.office.debitor..", "..hs.office.membership..");
"..hs.office.partner..",
"..hs.office.debitor..",
"..hs.office.membership..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficeRelationshipPackageRule = classes()
.that().resideInAPackage("..hs.office.relationship..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.relationship..");
.resideInAnyPackage("..hs.office.relationship..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficePartnerPackageRule = classes()
.that().resideInAPackage("..hs.office.partner..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.partner..", "..hs.office.debitor..", "..hs.office.membership..");
.resideInAnyPackage("..hs.office.partner..",
"..hs.office.debitor..",
"..hs.office.membership..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficeMembershipPackageRule = classes()
.that().resideInAPackage("..hs.office.membership..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.membership..", "..hs.office.coopassets..", "..hs.office.coopshares..");
.resideInAnyPackage("..hs.office.membership..",
"..hs.office.coopassets..",
"..hs.office.coopshares..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficeCoopAssetsPackageRule = classes()
.that().resideInAPackage("..hs.office.coopassets..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.coopassets..");
.resideInAnyPackage(
"..hs.office.coopassets..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficeCoopSharesPackageRule = classes()
.that().resideInAPackage("..hs.office.coopshares..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.coopshares..");
.resideInAnyPackage(
"..hs.office.coopshares..",
"..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule hsOfficeMigrationPackageRule = classes()
.that().resideInAPackage("..hs.office.migration..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.migration..");
@ArchTest
@SuppressWarnings("unused")
@@ -197,7 +227,7 @@ public class ArchitectureTest {
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule doNotUsejakartaTransactionAnnotationAtClassLevel = noClasses()
public static final ArchRule doNotUseJakartaTransactionAnnotationAtClassLevel = noClasses()
.should().beAnnotatedWith(jakarta.transaction.Transactional.class.getName())
.as("Use @%s instead of @%s.".formatted(
org.springframework.transaction.annotation.Transactional.class.getName(),
@@ -205,7 +235,7 @@ public class ArchitectureTest {
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule doNotUsejakartaTransactionAnnotationAtMethodLevel = noMethods()
public static final ArchRule doNotUseJakartaTransactionAnnotationAtMethodLevel = noMethods()
.should().beAnnotatedWith(jakarta.transaction.Transactional.class)
.as("Use @%s instead of @%s.".formatted(
org.springframework.transaction.annotation.Transactional.class.getName(),

View File

@@ -17,6 +17,7 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest {
.transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT)
.assetValue(new BigDecimal("128.00"))
.build();
final HsOfficeCoopAssetsTransactionEntity givenEmptyCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder().build();
@Test
void toStringContainsAlmostAllPropertiesAccount() {
@@ -31,4 +32,18 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest {
assertThat(result).isEqualTo("300001+128.00");
}
@Test
void toStringWithEmptyTransactionDoesNotThrowException() {
final var result = givenEmptyCoopAssetsTransaction.toString();
assertThat(result).isEqualTo("CoopAssetsTransaction()");
}
@Test
void toShortStringEmptyTransactionDoesNotThrowException() {
final var result = givenEmptyCoopAssetsTransaction.toShortString();
assertThat(result).isEqualTo("nullnu");
}
}

View File

@@ -117,7 +117,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#10001:....tenant by system and assume }",
null));
}
@@ -144,17 +144,17 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
// then
allTheseCoopAssetsTransactionsAreReturned(
result,
"CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1)",
"CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2)",
"CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3)",
"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(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1)",
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2)",
"CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3)",
"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(10003, 2010-03-15, DEPOSIT, 320.00, ref 10003-1)",
"CoopAssetsTransaction(10003, 2021-09-01, DISBURSAL, -128.00, ref 10003-2)",
"CoopAssetsTransaction(10003, 2022-10-20, ADJUSTMENT, 128.00, ref 10003-3)");
"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)");
}
@Test
@@ -173,9 +173,9 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
// then
allTheseCoopAssetsTransactionsAreReturned(
result,
"CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1)",
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2)",
"CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3)");
"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)");
}
@Test
@@ -194,14 +194,13 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
// then
allTheseCoopAssetsTransactionsAreReturned(
result,
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2)");
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)");
}
@Test
public void normalUser_canViewOnlyRelatedCoopAssetsTransactions() {
// given:
context("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.admin");
// "hs_office_person#FirstGmbH.admin",
context("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.admin");
// when:
final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
@@ -212,9 +211,9 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
// then:
exactlyTheseCoopAssetsTransactionsAreReturned(
result,
"CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1)",
"CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2)",
"CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3)");
"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)");
}
}

View File

@@ -16,6 +16,7 @@ class HsOfficeCoopSharesTransactionEntityUnitTest {
.transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION)
.shareCount(4)
.build();
final HsOfficeCoopSharesTransactionEntity givenEmptyCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder().build();
@Test
void toStringContainsAlmostAllPropertiesAccount() {
@@ -25,9 +26,23 @@ class HsOfficeCoopSharesTransactionEntityUnitTest {
}
@Test
void toShortStringContainsOnlyMemberNumberAndshareCountOnly() {
void toShortStringContainsOnlyMemberNumberAndShareCountOnly() {
final var result = givenCoopSharesTransaction.toShortString();
assertThat(result).isEqualTo("300001+4");
}
@Test
void toStringEmptyTransactionDoesNotThrowException() {
final var result = givenEmptyCoopSharesTransaction.toString();
assertThat(result).isEqualTo("CoopShareTransaction(0)");
}
@Test
void toShortStringEmptyTransactionDoesNotThrowException() {
final var result = givenEmptyCoopSharesTransaction.toShortString();
assertThat(result).isEqualTo("null+0");
}
}

View File

@@ -116,7 +116,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#10001:....tenant by system and assume }",
null));
}
@@ -143,17 +143,17 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
// then
allTheseCoopSharesTransactionsAreReturned(
result,
"CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1)",
"CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2)",
"CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3)",
"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(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1)",
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2)",
"CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3)",
"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(10003, 2010-03-15, SUBSCRIPTION, 4, ref 10003-1)",
"CoopShareTransaction(10003, 2021-09-01, CANCELLATION, -2, ref 10003-2)",
"CoopShareTransaction(10003, 2022-10-20, ADJUSTMENT, 2, ref 10003-3)");
"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)");
}
@Test
@@ -172,9 +172,9 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
// then
allTheseCoopSharesTransactionsAreReturned(
result,
"CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1)",
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2)",
"CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3)");
"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)");
}
@Test
@@ -193,14 +193,13 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
// then
allTheseCoopSharesTransactionsAreReturned(
result,
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2)");
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)");
}
@Test
public void normalUser_canViewOnlyRelatedCoopSharesTransactions() {
// given:
context("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.admin");
// "hs_office_person#FirstGmbH.admin",
context("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.admin");
// when:
final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
@@ -211,9 +210,9 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
// then:
exactlyTheseCoopSharesTransactionsAreReturned(
result,
"CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1)",
"CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2)",
"CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3)");
"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)");
}
}

View File

@@ -35,8 +35,8 @@ import static org.hamcrest.Matchers.*;
@Transactional
class HsOfficeDebitorControllerAcceptanceTest {
private static final int LOWEST_TEMP_DEBITOR_NUMBER = 20000;
private static int nextDebitorNumber = LOWEST_TEMP_DEBITOR_NUMBER;
private static final int LOWEST_TEMP_DEBITOR_SUFFIX = 90;
private static byte nextDebitorSuffix = LOWEST_TEMP_DEBITOR_SUFFIX;
@LocalServerPort
private Integer port;
@@ -81,7 +81,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
.body("", lenientlyEquals("""
[
{
"debitorNumber": 10001,
"debitorNumber": 1000111,
"debitorNumberSuffix": 11,
"partner": { "person": { "personType": "LEGAL" } },
"billingContact": { "label": "first contact" },
"vatId": null,
@@ -90,7 +91,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
"refundBankAccount": { "holder": "First GmbH" }
},
{
"debitorNumber": 10002,
"debitorNumber": 1000212,
"debitorNumberSuffix": 12,
"partner": { "person": { "tradeName": "Second e.K." } },
"billingContact": { "label": "second contact" },
"vatId": null,
@@ -99,7 +101,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
"refundBankAccount": { "holder": "Second e.K." }
},
{
"debitorNumber": 10003,
"debitorNumber": 1000313,
"debitorNumberSuffix": 13,
"partner": { "person": { "tradeName": "Third OHG" } },
"billingContact": { "label": "third contact" },
"vatId": null,
@@ -120,14 +123,14 @@ class HsOfficeDebitorControllerAcceptanceTest {
.header("current-user", "superuser-alex@hostsharing.net")
.port(port)
.when()
.get("http://localhost/api/hs/office/debitors?debitorNumber=10002")
.get("http://localhost/api/hs/office/debitors?debitorNumber=1000212")
.then().log().all().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", lenientlyEquals("""
[
{
"debitorNumber": 10002,
"debitorNumber": 1000212,
"partner": { "person": { "tradeName": "Second e.K." } },
"billingContact": { "label": "second contact" },
"vatId": null,
@@ -160,13 +163,16 @@ class HsOfficeDebitorControllerAcceptanceTest {
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s",
"debitorNumberSuffix": "%s",
"billable": "true",
"vatId": "VAT123456",
"vatCountryCode": "DE",
"vatBusiness": true,
"refundBankAccountUuid": "%s"
"vatReverseCharge": "false",
"refundBankAccountUuid": "%s",
"defaultPrefix": "for"
}
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber, givenBankAccount.getUuid()))
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorSuffix, givenBankAccount.getUuid()))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
@@ -175,6 +181,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("vatId", is("VAT123456"))
.body("defaultPrefix", is("for"))
.body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName()))
.body("refundBankAccount.holder", is(givenBankAccount.getHolder()))
@@ -202,9 +209,12 @@ class HsOfficeDebitorControllerAcceptanceTest {
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s"
"debitorNumberSuffix": "%s",
"defaultPrefix": "for",
"billable": "true",
"vatReverseCharge": "false"
}
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber))
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorSuffix))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
@@ -218,6 +228,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
.body("vatCountryCode", equalTo(null))
.body("vatBusiness", equalTo(false))
.body("refundBankAccount", equalTo(null))
.body("defaultPrefix", equalTo("for"))
.header("Location", startsWith("http://localhost"))
.extract().header("Location"); // @formatter:on
@@ -242,12 +253,16 @@ class HsOfficeDebitorControllerAcceptanceTest {
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s",
"debitorNumberSuffix": "%s",
"billable": "true",
"vatId": "VAT123456",
"vatCountryCode": "DE",
"vatBusiness": true
"vatBusiness": true,
"vatReverseCharge": "false",
"defaultPrefix": "thi"
}
""".formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorNumber))
"""
.formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorSuffix))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
@@ -272,12 +287,15 @@ class HsOfficeDebitorControllerAcceptanceTest {
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s",
"debitorNumberSuffix": "%s",
"billable": "true",
"vatId": "VAT123456",
"vatCountryCode": "DE",
"vatBusiness": true
"vatBusiness": true,
"vatReverseCharge": "false",
"defaultPrefix": "for"
}
""".formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorNumber))
""".formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorSuffix))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
@@ -375,7 +393,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
"contactUuid": "%s",
"vatId": "VAT222222",
"vatCountryCode": "AA",
"vatBusiness": true
"vatBusiness": true,
"defaultPrefix": "for"
}
""".formatted(givenContact.getUuid()))
.port(port)
@@ -388,6 +407,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
.body("vatId", is("VAT222222"))
.body("vatCountryCode", is("AA"))
.body("vatBusiness", is(true))
.body("defaultPrefix", is("for"))
.body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName()));
// @formatter:on
@@ -522,9 +542,12 @@ class HsOfficeDebitorControllerAcceptanceTest {
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
final var newDebitor = HsOfficeDebitorEntity.builder()
.debitorNumber(++nextDebitorNumber)
.debitorNumberSuffix(++nextDebitorSuffix)
.billable(true)
.partner(givenPartner)
.billingContact(givenContact)
.defaultPrefix("abc")
.vatReverseCharge(false)
.build();
return debitorRepo.save(newDebitor);
@@ -537,7 +560,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var count = em.createQuery(
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumber > " + LOWEST_TEMP_DEBITOR_NUMBER)
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX)
.executeUpdate();
System.out.printf("deleted %d entities%n", count);
});

View File

@@ -1,5 +1,6 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
@@ -31,10 +32,20 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
private static final String PATCHED_DEFAULT_PREFIX = "xyz";
private static final String PATCHED_VAT_COUNTRY_CODE = "ZZ";
private static final boolean PATCHED_VAT_BUSINESS = false;
private static final boolean INITIAL_BILLABLE = false;
private static final boolean PATCHED_BILLABLE = true;
private static final boolean INITIAL_VAT_REVERSE_CHARGE = true;
private static final boolean PATCHED_VAT_REVERSE_CHARGE = false;
private static final UUID INITIAL_REFUND_BANK_ACCOUNT_UUID = UUID.randomUUID();
private static final UUID PATCHED_REFUND_BANK_ACCOUNT_UUID = UUID.randomUUID();
private final HsOfficePartnerEntity givenInitialPartner = HsOfficePartnerEntity.builder()
.uuid(INITIAL_PARTNER_UUID)
.build();
@@ -42,6 +53,10 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
private final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
.uuid(INITIAL_CONTACT_UUID)
.build();
private final HsOfficeBankAccountEntity givenInitialBankAccount = HsOfficeBankAccountEntity.builder()
.uuid(INITIAL_REFUND_BANK_ACCOUNT_UUID)
.build();
@Mock
private EntityManager em;
@@ -49,8 +64,8 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
void initMocks() {
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsOfficeBankAccountEntity.class), any())).thenAnswer(invocation ->
HsOfficeBankAccountEntity.builder().uuid(invocation.getArgument(1)).build());
}
@Override
@@ -59,9 +74,13 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
entity.setUuid(INITIAL_DEBITOR_UUID);
entity.setPartner(givenInitialPartner);
entity.setBillingContact(givenInitialContact);
entity.setBillable(INITIAL_BILLABLE);
entity.setVatId("initial VAT-ID");
entity.setVatCountryCode("AA");
entity.setVatBusiness(true);
entity.setVatReverseCharge(INITIAL_VAT_REVERSE_CHARGE);
entity.setDefaultPrefix("abc");
entity.setRefundBankAccount(givenInitialBankAccount);
return entity;
}
@@ -85,6 +104,12 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
HsOfficeDebitorEntity::setBillingContact,
newBillingContact(PATCHED_CONTACT_UUID))
.notNullable(),
new SimpleProperty<>(
"billable",
HsOfficeDebitorPatchResource::setBillable,
PATCHED_BILLABLE,
HsOfficeDebitorEntity::setBillable)
.notNullable(),
new JsonNullableProperty<>(
"vatId",
HsOfficeDebitorPatchResource::setVatId,
@@ -95,11 +120,30 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
HsOfficeDebitorPatchResource::setVatCountryCode,
PATCHED_VAT_COUNTRY_CODE,
HsOfficeDebitorEntity::setVatCountryCode),
new JsonNullableProperty<>(
new SimpleProperty<>(
"vatBusiness",
HsOfficeDebitorPatchResource::setVatBusiness,
PATCHED_VAT_BUSINESS,
HsOfficeDebitorEntity::setVatBusiness)
.notNullable(),
new SimpleProperty<>(
"vatReverseCharge",
HsOfficeDebitorPatchResource::setVatReverseCharge,
PATCHED_BILLABLE,
HsOfficeDebitorEntity::setVatReverseCharge)
.notNullable(),
new JsonNullableProperty<>(
"defaultPrefix",
HsOfficeDebitorPatchResource::setDefaultPrefix,
PATCHED_DEFAULT_PREFIX,
HsOfficeDebitorEntity::setDefaultPrefix)
.notNullable(),
new JsonNullableProperty<>(
"refundBankAccount",
HsOfficeDebitorPatchResource::setRefundBankAccountUuid,
PATCHED_REFUND_BANK_ACCOUNT_UUID,
HsOfficeDebitorEntity::setRefundBankAccount,
newBankAccount(PATCHED_REFUND_BANK_ACCOUNT_UUID))
.notNullable()
);
}
@@ -109,4 +153,10 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
newContact.setUuid(uuid);
return newContact;
}
private HsOfficeBankAccountEntity newBankAccount(final UUID uuid) {
final var newBankAccount = new HsOfficeBankAccountEntity();
newBankAccount.setUuid(uuid);
return newBankAccount;
}
}

View File

@@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
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 org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -13,30 +14,52 @@ class HsOfficeDebitorEntityUnitTest {
@Test
void toStringContainsPartnerAndContact() {
final var given = HsOfficeDebitorEntity.builder()
.debitorNumber(123456)
.debitorNumberSuffix((byte)67)
.partner(HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build())
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
.debitorNumberPrefix(12345)
.build())
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
.defaultPrefix("som")
.build();
final var result = given.toString();
assertThat(result).isEqualTo("debitor(1234567: LEGAL some trade name: som)");
}
@Test
void toStringWithoutPersonContainsDebitorNumber() {
final var given = HsOfficeDebitorEntity.builder()
.debitorNumberSuffix((byte)67)
.partner(HsOfficePartnerEntity.builder()
.person(null)
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
.debitorNumberPrefix(12345)
.build())
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toString();
assertThat(result).isEqualTo("debitor(123456: some trade name)");
assertThat(result).isEqualTo("debitor(1234567: <person=null>)");
}
@Test
void toShortStringContainsPartnerAndContact() {
void toShortStringContainsDebitorNumber() {
final var given = HsOfficeDebitorEntity.builder()
.debitorNumber(123456)
.partner(HsOfficePartnerEntity.builder()
.debitorNumberPrefix(12345)
.build())
.debitorNumberSuffix((byte)67)
.build();
final var result = given.toShortString();
assertThat(result).isEqualTo("123456");
assertThat(result).isEqualTo("1234567");
}
}

View File

@@ -9,8 +9,6 @@ import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
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.junit.jupiter.params.ParameterizedTest;
@@ -20,14 +18,13 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
@@ -65,8 +62,6 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
@MockBean
HttpServletRequest request;
Set<HsOfficeDebitorEntity> tempDebitors = new HashSet<>();
@Nested
class CreateDebitor {
@@ -81,9 +76,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// when
final var result = attempt(em, () -> {
final var newDebitor = HsOfficeDebitorEntity.builder()
.debitorNumber(20001)
.debitorNumberSuffix((byte)21)
.partner(givenPartner)
.billingContact(givenContact)
.defaultPrefix("abc")
.billable(false)
.build();
return debitorRepo.save(newDebitor);
});
@@ -95,14 +92,43 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
assertThat(debitorRepo.count()).isEqualTo(count + 1);
}
@ParameterizedTest
@ValueSource(strings = {"", "a", "ab", "a12", "123", "12a"})
@Transactional
public void canNotCreateNewDebitorWithInvalidDefaultPrefix(final String givenPrefix) {
// given
context("superuser-alex@hostsharing.net");
final var count = debitorRepo.count();
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First GmbH").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
// when
final var result = attempt(em, () -> {
final var newDebitor = HsOfficeDebitorEntity.builder()
.debitorNumberSuffix((byte)21)
.partner(givenPartner)
.billingContact(givenContact)
.billable(true)
.vatReverseCharge(false)
.vatBusiness(false)
.defaultPrefix(givenPrefix)
.build();
return debitorRepo.save(newDebitor);
});
// then
result.assertExceptionWithRootCauseMessage(org.hibernate.exception.ConstraintViolationException.class);
}
@Test
public void createsAndGrantsRoles() {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll()).stream()
// some search+replace to make the output fit into the screen width
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
.map(s -> s.replace("20002Fourthe.G.-forthcontact", "FeG"))
.map(s -> s.replace("22Fourthe.G.-forthcontact", "FeG"))
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
.map(s -> s.replace("forthcontact", "4th"))
.map(s -> s.replace("hs_office_", ""))
@@ -113,9 +139,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
final var newDebitor = HsOfficeDebitorEntity.builder()
.debitorNumber(20002)
.debitorNumberSuffix((byte)22)
.partner(givenPartner)
.billingContact(givenContact)
.defaultPrefix("abc")
.billable(false)
.build();
return debitorRepo.save(newDebitor);
}).assertSuccessful();
@@ -123,42 +151,42 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// then
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames,
"hs_office_debitor#20002Fourthe.G.-forthcontact.owner",
"hs_office_debitor#20002Fourthe.G.-forthcontact.admin",
"hs_office_debitor#20002Fourthe.G.-forthcontact.agent",
"hs_office_debitor#20002Fourthe.G.-forthcontact.tenant",
"hs_office_debitor#20002Fourthe.G.-forthcontact.guest"));
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.owner",
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.admin",
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.agent",
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.tenant",
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.guest"));
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
.map(s -> s.replace("20002Fourthe.G.-forthcontact", "FeG"))
.map(s -> s.replace("22Fourthe.G.-forthcontact", "FeG"))
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
.map(s -> s.replace("forthcontact", "4th"))
.map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames,
// owner
"{ grant perm * on debitor#FeG to role debitor#FeG.owner by system and assume }",
"{ grant role debitor#FeG.owner to role global#global.admin by system and assume }",
"{ grant role debitor#FeG.owner to user superuser-alex by global#global.admin and assume }",
"{ grant perm * on debitor#1000422:FeG to role debitor#1000422:FeG.owner by system and assume }",
"{ grant role debitor#1000422:FeG.owner to role global#global.admin by system and assume }",
"{ grant role debitor#1000422:FeG.owner to user superuser-alex by global#global.admin and assume }",
// admin
"{ grant perm edit on debitor#FeG to role debitor#FeG.admin by system and assume }",
"{ grant role debitor#FeG.admin to role debitor#FeG.owner by system and assume }",
"{ grant perm edit on debitor#1000422:FeG to role debitor#1000422:FeG.admin by system and assume }",
"{ grant role debitor#1000422:FeG.admin to role debitor#1000422:FeG.owner by system and assume }",
// agent
"{ grant role debitor#FeG.agent to role debitor#FeG.admin by system and assume }",
"{ grant role debitor#FeG.agent to role contact#4th.admin by system and assume }",
"{ grant role debitor#FeG.agent to role partner#FeG.admin by system and assume }",
"{ grant role debitor#1000422:FeG.agent to role debitor#1000422:FeG.admin by system and assume }",
"{ grant role debitor#1000422:FeG.agent to role contact#4th.admin by system and assume }",
"{ grant role debitor#1000422:FeG.agent to role partner#10004:FeG.admin by system and assume }",
// tenant
"{ grant role contact#4th.guest to role debitor#FeG.tenant by system and assume }",
"{ grant role debitor#FeG.tenant to role debitor#FeG.agent by system and assume }",
"{ grant role debitor#FeG.tenant to role partner#FeG.agent by system and assume }",
"{ grant role partner#FeG.tenant to role debitor#FeG.tenant by system and assume }",
"{ grant role contact#4th.guest to role debitor#1000422:FeG.tenant by system and assume }",
"{ grant role debitor#1000422:FeG.tenant to role debitor#1000422:FeG.agent by system and assume }",
"{ grant role debitor#1000422:FeG.tenant to role partner#10004:FeG.agent by system and assume }",
"{ grant role partner#10004:FeG.tenant to role debitor#1000422:FeG.tenant by system and assume }",
// guest
"{ grant perm view on debitor#FeG to role debitor#FeG.guest by system and assume }",
"{ grant role debitor#FeG.guest to role debitor#FeG.tenant by system and assume }",
"{ grant perm view on debitor#1000422:FeG to role debitor#1000422:FeG.guest by system and assume }",
"{ grant role debitor#1000422:FeG.guest to role debitor#1000422:FeG.tenant by system and assume }",
null));
}
@@ -183,14 +211,14 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// then
allTheseDebitorsAreReturned(
result,
"debitor(10001: First GmbH)",
"debitor(10002: Second e.K.)",
"debitor(10003: Third OHG)");
"debitor(1000111: LEGAL First GmbH: fir)",
"debitor(1000212: LEGAL Second e.K.: sec)",
"debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
}
@ParameterizedTest
@ValueSource(strings = {
"hs_office_partner#FirstGmbH-firstcontact.admin",
"hs_office_partner#10001:FirstGmbH-firstcontact.admin",
"hs_office_person#FirstGmbH.admin",
"hs_office_contact#firstcontact.admin",
})
@@ -202,7 +230,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
// then:
exactlyTheseDebitorsAreReturned(result, "debitor(10001: First GmbH)");
exactlyTheseDebitorsAreReturned(result,
"debitor(1000111: LEGAL First GmbH: fir)",
"debitor(1000120: LEGAL First GmbH: fif)");
}
@Test
@@ -227,10 +257,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
context("superuser-alex@hostsharing.net");
// when
final var result = debitorRepo.findDebitorByDebitorNumber(10003);
final var result = debitorRepo.findDebitorByDebitorNumber(1000313);
// then
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
}
}
@@ -246,7 +276,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
// then
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
}
}
@@ -257,10 +287,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void globalAdmin_canUpdateArbitraryDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fif");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_partner#Fourthe.G.-forthcontact.admin");
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
final var givenNewPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0);
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
@@ -290,10 +320,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// ... partner role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole(
result.returnedValue(),
"hs_office_partner#Fourthe.G.-forthcontact.agent");
"hs_office_partner#10004:Fourthe.G.-forthcontact.agent");
assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(),
"hs_office_partner#FirstGmbH-firstcontact.agent");
"hs_office_partner#10001:FirstGmbH-firstcontact.agent");
// ... contact role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole(
@@ -316,10 +346,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void globalAdmin_canUpdateNullRefundBankAccountToNotNullBankAccountForArbitraryDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null);
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fig");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_partner#Fourthe.G.-forthcontact.admin");
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0);
@@ -346,10 +376,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void globalAdmin_canUpdateRefundBankAccountToNullForArbitraryDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fih");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_partner#Fourthe.G.-forthcontact.admin");
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
// when
@@ -375,15 +405,15 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void partnerAdmin_canNotUpdateRelatedDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_partner#Fourthe.G.-forthcontact.admin");
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_partner#Fourthe.G.-forthcontact.admin");
context("superuser-alex@hostsharing.net", "hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
givenDebitor.setVatId("NEW-VAT-ID");
return debitorRepo.save(givenDebitor);
});
@@ -397,7 +427,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void contactAdmin_canNotUpdateRelatedDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth", "nin");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_contact#ninthcontact.admin");
@@ -448,7 +478,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void globalAdmin_canDeleteAnyDebitor() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth", "Fourth", "ten");
// when
final var result = jpaAttempt.transacted(() -> {
@@ -468,7 +498,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
public void relatedPerson_canNotDeleteTheirRelatedDebitor() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth", "ele");
// when
final var result = jpaAttempt.transacted(() -> {
@@ -494,7 +524,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth", "Fourth");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth", "Fourth", "twe");
assertThat(rawRoleRepo.findAll().size()).as("precondition failed: unexpected number of roles created")
.isEqualTo(initialRoleNames.length + 5);
assertThat(rawGrantRepo.findAll().size()).as("precondition failed: unexpected number of grants created")
@@ -536,7 +566,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
private HsOfficeDebitorEntity givenSomeTemporaryDebitor(
final String partner,
final String contact,
final String bankAccount) {
final String bankAccount,
final String defaultPrefix) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0);
@@ -544,23 +575,18 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
final var givenBankAccount =
bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null;
final var newDebitor = HsOfficeDebitorEntity.builder()
.debitorNumber(20000)
.debitorNumberSuffix((byte)20)
.partner(givenPartner)
.billingContact(givenContact)
.refundBankAccount(givenBankAccount)
.defaultPrefix(defaultPrefix)
.billable(true)
.build();
return debitorRepo.save(newDebitor);
}).assertSuccessful().returnedValue();
}
@BeforeEach
@AfterEach
void cleanup() {
context("superuser-alex@hostsharing.net");
em.createQuery("DELETE FROM HsOfficeDebitorEntity d where d.debitorNumber >= 20000").executeUpdate();
}
void exactlyTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
assertThat(actualResult)
.extracting(HsOfficeDebitorEntity::toString)

View File

@@ -9,8 +9,10 @@ import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TE
@UtilityClass
public class TestHsOfficeDebitor {
public byte DEFAULT_DEBITOR_SUFFIX = 0;
public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder()
.debitorNumber(10001)
.debitorNumberSuffix(DEFAULT_DEBITOR_SUFFIX)
.partner(TEST_PARTNER)
.billingContact(TEST_CONTACT)
.build();

View File

@@ -83,7 +83,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
[
{
"partner": { "person": { "tradeName": "First GmbH" } },
"mainDebitor": { "debitorNumber": 10001 },
"mainDebitor": { "debitorNumber": 1000111 },
"memberNumber": 10001,
"validFrom": "2022-10-01",
"validTo": null,
@@ -91,7 +91,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
},
{
"partner": { "person": { "tradeName": "Second e.K." } },
"mainDebitor": { "debitorNumber": 10002 },
"mainDebitor": { "debitorNumber": 1000212 },
"memberNumber": 10002,
"validFrom": "2022-10-01",
"validTo": null,
@@ -99,7 +99,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
},
{
"partner": { "person": { "tradeName": "Third OHG" } },
"mainDebitor": { "debitorNumber": 10003 },
"mainDebitor": { "debitorNumber": 1000313 },
"memberNumber": 10003,
"validFrom": "2022-10-01",
"validTo": null,
@@ -131,7 +131,8 @@ class HsOfficeMembershipControllerAcceptanceTest {
"partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumber": 20001,
"validFrom": "2022-10-13"
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(givenPartner.getUuid(), givenDebitor.getUuid()))
.port(port)
@@ -142,6 +143,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.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("validFrom", is("2022-10-13"))
@@ -182,7 +184,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
.body("", lenientlyEquals("""
{
"partner": { "person": { "tradeName": "First GmbH" } },
"mainDebitor": { "debitorNumber": 10001 },
"mainDebitor": { "debitorNumber": 1000111 },
"memberNumber": 10001,
"validFrom": "2022-10-01",
"validTo": null,
@@ -224,7 +226,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_debitor#10003ThirdOHG-thirdcontact.agent")
.header("assumed-roles", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.agent")
.port(port)
.when()
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
@@ -235,7 +237,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
{
"partner": { "person": { "tradeName": "Third OHG" } },
"mainDebitor": {
"debitorNumber": 10003,
"debitorNumber": 1000313,
"billingContact": { "label": "third contact" }
},
"memberNumber": 10003,
@@ -276,6 +278,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
.body("uuid", isUuidValid())
.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("validFrom", is("2022-11-01"))
.body("validTo", is("2023-12-31"))
@@ -285,7 +288,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("First GmbH");
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
@@ -299,7 +302,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
context.define("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembershipBessler();
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(10003).get(0);
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(1000313).get(0);
RestAssured // @formatter:off
.given()
@@ -318,7 +321,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
.body("mainDebitor.debitorNumber", is(10003))
.body("mainDebitor.debitorNumber", is(1000313))
.body("memberNumber", is(givenMembership.getMemberNumber()))
.body("validFrom", is("2022-11-01"))
.body("validTo", nullValue())
@@ -328,7 +331,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("First GmbH");
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");
@@ -340,13 +343,13 @@ class HsOfficeMembershipControllerAcceptanceTest {
@Test
void partnerAgent_canViewButNotPatchValidityOfRelatedMembership() {
context.define("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.agent");
context.define("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.agent");
final var givenMembership = givenSomeTemporaryMembershipBessler();
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_partner#FirstGmbH-firstcontact.agent")
.header("assumed-roles", "hs_office_partner#10001:FirstGmbH-firstcontact.agent")
.contentType(ContentType.JSON)
.body("""
{
@@ -444,6 +447,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
.memberNumber(++tempMemberNumber)
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
.reasonForTermination(NONE)
.membershipFeeBillable(true)
.build();
return membershipRepo.save(newMembership);

View File

@@ -72,7 +72,8 @@ public class HsOfficeMembershipControllerRestTest {
"partnerUuid": null,
"mainDebitorUuid": "%s",
"memberNumber": 20001,
"validFrom": "2022-10-13"
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(UUID.randomUUID()))
.accept(MediaType.APPLICATION_JSON))
@@ -97,7 +98,8 @@ public class HsOfficeMembershipControllerRestTest {
"partnerUuid": "%s",
"mainDebitorUuid": null,
"memberNumber": 20001,
"validFrom": "2022-10-13"
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(UUID.randomUUID()))
.accept(MediaType.APPLICATION_JSON))
@@ -128,7 +130,8 @@ public class HsOfficeMembershipControllerRestTest {
"partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumber": 20001,
"validFrom": "2022-10-13"
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
.accept(MediaType.APPLICATION_JSON))
@@ -159,7 +162,8 @@ public class HsOfficeMembershipControllerRestTest {
"partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumber": 20001,
"validFrom": "2022-10-13"
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
.accept(MediaType.APPLICATION_JSON))

View File

@@ -36,6 +36,9 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
private static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-04-15");
private static final LocalDate PATCHED_VALID_TO = LocalDate.parse("2022-12-31");
private static final Boolean GIVEN_MEMBERSHIP_FEE_BILLABLE = true;
private static final Boolean PATCHED_MEMBERSHIP_FEE_BILLABLE = false;
@Mock
private EntityManager em;
@@ -56,6 +59,7 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
entity.setMainDebitor(TEST_DEBITOR);
entity.setPartner(TEST_PARTNER);
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
entity.setMembershipFeeBillable(GIVEN_MEMBERSHIP_FEE_BILLABLE);
return entity;
}
@@ -90,7 +94,12 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
HsOfficeReasonForTerminationResource.CANCELLATION,
HsOfficeMembershipEntity::setReasonForTermination,
HsOfficeReasonForTermination.CANCELLATION)
.notNullable()
.notNullable(),
new JsonNullableProperty<>(
"membershipFeeBillable",
HsOfficeMembershipPatchResource::setMembershipFeeBillable,
PATCHED_MEMBERSHIP_FEE_BILLABLE,
HsOfficeMembershipEntity::setMembershipFeeBillable)
);
}
@@ -99,10 +108,4 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
newDebitor.setUuid(uuid);
return newDebitor;
}
private HsOfficeMembershipEntity newMembership(final UUID uuid) {
final var newMembership = new HsOfficeMembershipEntity();
newMembership.setUuid(uuid);
return newMembership;
}
}

View File

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

View File

@@ -81,6 +81,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
.partner(givenPartner)
.mainDebitor(givenDebitor)
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
.membershipFeeBillable(true)
.build());
return membershipRepo.save(newMembership);
});
@@ -111,6 +112,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
.partner(givenPartner)
.mainDebitor(givenDebitor)
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
.membershipFeeBillable(true)
.build());
return membershipRepo.save(newMembership);
});
@@ -119,11 +121,11 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
final var all = rawRoleRepo.findAll();
assertThat(roleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
initialRoleNames,
"hs_office_membership#20002FirstGmbH-firstcontact.admin",
"hs_office_membership#20002FirstGmbH-firstcontact.agent",
"hs_office_membership#20002FirstGmbH-firstcontact.guest",
"hs_office_membership#20002FirstGmbH-firstcontact.owner",
"hs_office_membership#20002FirstGmbH-firstcontact.tenant"));
"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"));
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("GmbH-firstcontact", ""))
.map(s -> s.replace("hs_office_", ""))
@@ -131,32 +133,33 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
initialGrantNames,
// owner
"{ grant perm * on membership#20002First to role membership#20002First.owner by system and assume }",
"{ grant role membership#20002First.owner to role global#global.admin by system and assume }",
"{ 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 }",
// admin
"{ grant perm edit on membership#20002First to role membership#20002First.admin by system and assume }",
"{ grant role membership#20002First.admin to role membership#20002First.owner by system and assume }",
"{ 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 }",
// agent
"{ grant role membership#20002First.agent to role membership#20002First.admin by system and assume }",
"{ grant role partner#First.tenant to role membership#20002First.agent by system and assume }",
"{ grant role membership#20002First.agent to role debitor#10001First.admin by system and assume }",
"{ grant role membership#20002First.agent to role partner#First.admin by system and assume }",
"{ grant role debitor#10001First.tenant to role membership#20002First.agent by system and assume }",
"{ 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 }",
// tenant
"{ grant role membership#20002First.tenant to role membership#20002First.agent by system and assume }",
"{ grant role partner#First.guest to role membership#20002First.tenant by system and assume }",
"{ grant role debitor#10001First.guest to role membership#20002First.tenant by system and assume }",
"{ grant role membership#20002First.tenant to role debitor#10001First.agent by system and assume }",
"{ grant role membership#20002First.tenant to role partner#First.agent by system and assume }",
"{ 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#20002:First.tenant to role partner#10001:First.agent by system and assume }",
// guest
"{ grant perm view on membership#20002First to role membership#20002First.guest by system and assume }",
"{ grant role membership#20002First.guest to role membership#20002First.tenant by system and assume }",
"{ grant role membership#20002First.guest to role partner#First.tenant by system and assume }",
"{ grant role membership#20002First.guest to role debitor#10001First.tenant by system and assume }",
"{ 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 }",
null));
}
@@ -181,9 +184,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseMembershipsAreReturned(
result,
"Membership(10001, First GmbH, 10001, [2022-10-01,), NONE)",
"Membership(10002, Second e.K., 10002, [2022-10-01,), NONE)",
"Membership(10003, Third OHG, 10003, [2022-10-01,), NONE)");
"Membership(10001, LEGAL First GmbH, 1000111, [2022-10-01,), NONE)",
"Membership(10002, LEGAL Second e.K., 1000212, [2022-10-01,), NONE)",
"Membership(10003, SOLE_REPRESENTATION Third OHG, 1000313, [2022-10-01,), NONE)");
}
@Test
@@ -198,7 +201,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
null);
// then
exactlyTheseMembershipsAreReturned(result, "Membership(10001, First GmbH, 10001, [2022-10-01,), NONE)");
exactlyTheseMembershipsAreReturned(result, "Membership(10001, LEGAL First GmbH, 1000111, [2022-10-01,), NONE)");
}
@Test
@@ -210,7 +213,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002);
// then
exactlyTheseMembershipsAreReturned(result, "Membership(10002, Second e.K., 10002, [2022-10-01,), NONE)");
exactlyTheseMembershipsAreReturned(result, "Membership(10002, LEGAL Second e.K., 1000212, [2022-10-01,), NONE)");
}
}
@@ -224,7 +227,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
final var givenMembership = givenSomeTemporaryMembership("First", "First");
assertThatMembershipIsVisibleForUserWithRole(
givenMembership,
"hs_office_debitor#10001FirstGmbH-firstcontact.admin");
"hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
final var newValidityEnd = LocalDate.now();
@@ -251,13 +254,13 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
final var givenMembership = givenSomeTemporaryMembership("First", "First");
assertThatMembershipIsVisibleForUserWithRole(
givenMembership,
"hs_office_debitor#10001FirstGmbH-firstcontact.admin");
"hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
final var newValidityEnd = LocalDate.now();
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_debitor#10001FirstGmbH-firstcontact.admin");
context("superuser-alex@hostsharing.net", "hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
givenMembership.setValidity(Range.closedOpen(
givenMembership.getValidity().lower(), newValidityEnd));
return membershipRepo.save(givenMembership);
@@ -325,7 +328,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_debitor#10003ThirdOHG-thirdcontact.admin");
context("superuser-alex@hostsharing.net", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.admin");
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
membershipRepo.deleteByUuid(givenMembership.getUuid());
@@ -382,8 +385,8 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// then
assertThat(customerLogEntries).map(Arrays::toString).contains(
"[creating Membership test-data FirstGmbH10001, hs_office_membership, INSERT]",
"[creating Membership test-data Seconde.K.10002, hs_office_membership, INSERT]");
"[creating Membership test-data FirstGmbH11, hs_office_membership, INSERT]",
"[creating Membership test-data Seconde.K.12, hs_office_membership, INSERT]");
}
@BeforeEach
@@ -412,6 +415,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
.partner(givenPartner)
.mainDebitor(givenDebitor)
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
.membershipFeeBillable(true)
.build();
toCleanup(newMembership);

File diff suppressed because it is too large Load Diff

View File

@@ -125,6 +125,7 @@ class HsOfficePartnerControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("""
{
"debitorNumberPrefix": "12345",
"contactUuid": "%s",
"personUuid": "%s",
"details": {
@@ -166,6 +167,7 @@ class HsOfficePartnerControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("""
{
"debitorNumberPrefix": "12345",
"contactUuid": "%s",
"personUuid": "%s",
"details": {}
@@ -193,6 +195,7 @@ class HsOfficePartnerControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("""
{
"debitorNumberPrefix": "12345",
"contactUuid": "%s",
"personUuid": "%s",
"details": {}
@@ -294,6 +297,7 @@ class HsOfficePartnerControllerAcceptanceTest {
.contentType(ContentType.JSON)
.body("""
{
"debitorNumberPrefix": "12345",
"contactUuid": "%s",
"personUuid": "%s",
"details": {

View File

@@ -28,8 +28,9 @@ class HsOfficePartnerDetailsEntityPatcherUnitTest extends PatchUnitTestBase<
> {
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID();
private static final String INITIAL_BIRTHPLACE = null;
private static final String PATCHED_BIRTHPLACE = "Essen (Ruhr)";
private static final LocalDate INITIAL_BIRTHDAY = LocalDate.parse("1900-01-01");
private static final LocalDate PATCHED_BIRTHDAY = LocalDate.parse("1990-12-31");
@@ -54,6 +55,7 @@ class HsOfficePartnerDetailsEntityPatcherUnitTest extends PatchUnitTestBase<
entity.setUuid(INITIAL_PARTNER_UUID);
entity.setRegistrationOffice("initial Reg-Office");
entity.setRegistrationNumber("initial Reg-Number");
entity.setBirthPlace(INITIAL_BIRTHPLACE);
entity.setBirthday(INITIAL_BIRTHDAY);
entity.setBirthName("initial birth name");
entity.setDateOfDeath(INITIAL_DAY_OF_DEATH);
@@ -78,6 +80,16 @@ class HsOfficePartnerDetailsEntityPatcherUnitTest extends PatchUnitTestBase<
HsOfficePartnerDetailsPatchResource::setRegistrationOffice,
"patched Reg-Office",
HsOfficePartnerDetailsEntity::setRegistrationOffice),
new JsonNullableProperty<>(
"birthplace",
HsOfficePartnerDetailsPatchResource::setBirthPlace,
PATCHED_BIRTHPLACE,
HsOfficePartnerDetailsEntity::setBirthPlace),
new JsonNullableProperty<>(
"birthname",
HsOfficePartnerDetailsPatchResource::setBirthName,
"patched birth name",
HsOfficePartnerDetailsEntity::setBirthName),
new JsonNullableProperty<>(
"birthday",
HsOfficePartnerDetailsPatchResource::setBirthday,

View File

@@ -21,7 +21,8 @@ class HsOfficePartnerDetailsEntityUnitTest {
final var result = given.toString();
assertThat(result).isEqualTo("partnerDetails(Hamburg, 12345, 2002-01-15, 2002-01-15, 2081-12-21)");
assertThat(result).isEqualTo(
"partnerDetails(Hamburg, 12345, 2002-01-15, Melly Miller, 2081-12-21)");
}
@Test

View File

@@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
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;
@@ -11,24 +12,30 @@ class HsOfficePartnerEntityUnitTest {
@Test
void toStringContainsPersonAndContact() {
final var given = HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder().tradeName("some trade name").build())
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toString();
assertThat(result).isEqualTo("partner(some trade name: some label)");
assertThat(result).isEqualTo("partner(LEGAL some trade name: some label)");
}
@Test
void toShortStringContainsPersonAndContact() {
final var given = HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder().tradeName("some trade name").build())
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toShortString();
assertThat(result).isEqualTo("some trade name");
assertThat(result).isEqualTo("LEGAL some trade name");
}
}

View File

@@ -105,6 +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)
.person(givenPerson)
.contact(givenContact)
.details(HsOfficePartnerDetailsEntity.builder().build())
@@ -115,11 +116,11 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
// then
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames,
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.admin",
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.agent",
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.owner",
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.tenant",
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.guest"));
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.admin",
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.agent",
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.owner",
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.tenant",
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.guest"));
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("ErbenBesslerMelBessler", "EBess"))
.map(s -> s.replace("forthcontact", "4th"))
@@ -127,31 +128,31 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
.containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames,
// owner
"{ grant perm * on partner#EBess-4th to role partner#EBess-4th.owner by system and assume }",
"{ grant perm * on partner_details#EBess-4th-details to role partner#EBess-4th.owner by system and assume }",
"{ grant role partner#EBess-4th.owner to role global#global.admin by system and assume }",
"{ grant perm * on partner#22222:EBess-4th to role partner#22222:EBess-4th.owner by system and assume }",
"{ grant perm * on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.owner by system and assume }",
"{ grant role partner#22222:EBess-4th.owner to role global#global.admin by system and assume }",
// admin
"{ grant perm edit on partner#EBess-4th to role partner#EBess-4th.admin by system and assume }",
"{ grant perm edit on partner_details#EBess-4th-details to role partner#EBess-4th.admin by system and assume }",
"{ grant role partner#EBess-4th.admin to role partner#EBess-4th.owner by system and assume }",
"{ grant role person#EBess.tenant to role partner#EBess-4th.admin by system and assume }",
"{ grant role contact#4th.tenant to role partner#EBess-4th.admin by system and assume }",
"{ grant perm edit on partner#22222:EBess-4th to role partner#22222:EBess-4th.admin by system and assume }",
"{ grant perm edit on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.admin by system and assume }",
"{ grant role partner#22222:EBess-4th.admin to role partner#22222:EBess-4th.owner by system and assume }",
"{ grant role person#EBess.tenant to role partner#22222:EBess-4th.admin by system and assume }",
"{ grant role contact#4th.tenant to role partner#22222:EBess-4th.admin by system and assume }",
// agent
"{ grant perm view on partner_details#EBess-4th-details to role partner#EBess-4th.agent by system and assume }",
"{ grant role partner#EBess-4th.agent to role partner#EBess-4th.admin by system and assume }",
"{ grant role partner#EBess-4th.agent to role person#EBess.admin by system and assume }",
"{ grant role partner#EBess-4th.agent to role contact#4th.admin by system and assume }",
"{ grant perm view on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.agent by system and assume }",
"{ grant role partner#22222:EBess-4th.agent to role partner#22222:EBess-4th.admin by system and assume }",
"{ grant role partner#22222:EBess-4th.agent to role person#EBess.admin by system and assume }",
"{ grant role partner#22222:EBess-4th.agent to role contact#4th.admin by system and assume }",
// tenant
"{ grant role partner#EBess-4th.tenant to role partner#EBess-4th.agent by system and assume }",
"{ grant role person#EBess.guest to role partner#EBess-4th.tenant by system and assume }",
"{ grant role contact#4th.guest to role partner#EBess-4th.tenant by system and assume }",
"{ grant role partner#22222:EBess-4th.tenant to role partner#22222:EBess-4th.agent by system and assume }",
"{ grant role person#EBess.guest to role partner#22222:EBess-4th.tenant by system and assume }",
"{ grant role contact#4th.guest to role partner#22222:EBess-4th.tenant by system and assume }",
// guest
"{ grant perm view on partner#EBess-4th to role partner#EBess-4th.guest by system and assume }",
"{ grant role partner#EBess-4th.guest to role partner#EBess-4th.tenant by system and assume }",
"{ grant perm view on partner#22222:EBess-4th to role partner#22222:EBess-4th.guest by system and assume }",
"{ grant role partner#22222:EBess-4th.guest to role partner#22222:EBess-4th.tenant by system and assume }",
null));
}
@@ -176,9 +177,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
// then
allThesePartnersAreReturned(
result,
"partner(Third OHG: third contact)",
"partner(Second e.K.: second contact)",
"partner(First GmbH: first contact)");
"partner(SOLE_REPRESENTATION Third OHG: third contact)",
"partner(LEGAL Second e.K.: second contact)",
"partner(LEGAL First GmbH: first contact)");
}
@Test
@@ -190,7 +191,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
// then:
exactlyThesePartnersAreReturned(result, "partner(First GmbH: first contact)");
exactlyThesePartnersAreReturned(result, "partner(LEGAL First GmbH: first contact)");
}
}
@@ -206,7 +207,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
// then
exactlyThesePartnersAreReturned(result, "partner(Third OHG: third contact)");
exactlyThesePartnersAreReturned(result, "partner(SOLE_REPRESENTATION Third OHG: third contact)");
}
}
@@ -217,10 +218,10 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryPartner() {
// given
context("superuser-alex@hostsharing.net");
final var givenPartner = givenSomeTemporaryPartnerBessler("fifth contact");
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "fifth contact");
assertThatPartnerIsVisibleForUserWithRole(
givenPartner,
"hs_office_person#ErbenBesslerMelBessler.admin");
"hs_office_partner#22222:ErbenBesslerMelBessler-fifthcontact.admin");
assertThatPartnerActuallyInDatabase(givenPartner);
context("superuser-alex@hostsharing.net");
final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0);
@@ -253,16 +254,16 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
public void partnerAgent_canNotUpdateRelatedPartner() {
// given
context("superuser-alex@hostsharing.net");
final var givenPartner = givenSomeTemporaryPartnerBessler("ninth");
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "ninth");
assertThatPartnerIsVisibleForUserWithRole(
givenPartner,
"hs_office_partner#ErbenBesslerMelBessler-ninthcontact.agent");
"hs_office_partner#22222:ErbenBesslerMelBessler-ninthcontact.agent");
assertThatPartnerActuallyInDatabase(givenPartner);
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("tenth").get(0);
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_partner#ErbenBesslerMelBessler-ninthcontact.agent");
context("superuser-alex@hostsharing.net",
"hs_office_partner#22222:ErbenBesslerMelBessler-ninthcontact.agent");
givenPartner.getDetails().setBirthName("new birthname");
return partnerRepo.save(givenPartner);
});
@@ -304,7 +305,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenPartner = givenSomeTemporaryPartnerBessler("tenth");
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "tenth");
// when
final var result = jpaAttempt.transacted(() -> {
@@ -324,7 +325,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenPartner = givenSomeTemporaryPartnerBessler("eleventh");
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "eleventh");
// when
final var result = jpaAttempt.transacted(() -> {
@@ -350,7 +351,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
final var givenPartner = givenSomeTemporaryPartnerBessler("twelfth");
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "twelfth");
// when
final var result = jpaAttempt.transacted(() -> {
@@ -394,12 +395,14 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
});
}
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final String contact) {
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(
final Integer debitorNumberPrefix, final String person, final String contact) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
final var givenPerson = personRepo.findPersonByOptionalNameLike(person).get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
final var newPartner = HsOfficePartnerEntity.builder()
.debitorNumberPrefix(debitorNumberPrefix)
.person(givenPerson)
.contact(givenContact)
.details(HsOfficePartnerDetailsEntity.builder().build())

View File

@@ -8,10 +8,11 @@ import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGA
public class TestHsOfficePartner {
public static final HsOfficePartnerEntity TEST_PARTNER = HsOfficePartnerWithLegalPerson("Test Ltd.");
public static final HsOfficePartnerEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
static public HsOfficePartnerEntity HsOfficePartnerWithLegalPerson(final String tradeName) {
static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
return HsOfficePartnerEntity.builder()
.debitorNumberPrefix(10001)
.person(HsOfficePersonEntity.builder()
.personType(LEGAL)
.tradeName(tradeName)

View File

@@ -11,29 +11,32 @@ class HsOfficePersonEntityUnitTest {
@Test
void getDisplayReturnsTradeNameIfAvailable() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some trade name");
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
}
@Test
void getDisplayReturnsFamilyAndGivenNameIfNoTradeNameAvailable() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.familyName("some family name")
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some family name, some given name");
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
}
@Test
void toShortStringWithTradeNameReturnsTradeName() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.familyName("some family name")
.givenName("some given name")
@@ -41,19 +44,20 @@ class HsOfficePersonEntityUnitTest {
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some trade name");
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
}
@Test
void toShortStringWithoutTradeNameReturnsFamilyAndGivenName() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.familyName("some family name")
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some family name, some given name");
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
}
@Test

View File

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

View File

@@ -75,7 +75,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
.port(port)
.when()
.get("http://localhost/api/hs/office/relationships?personUuid=%s&relationshipType=%s"
.formatted(givenPerson.getUuid(), HsOfficeRelationshipTypeResource.SOLE_AGENT))
.formatted(givenPerson.getUuid(), HsOfficeRelationshipTypeResource.REPRESENTATIVE))
.then().log().all().assertThat()
.statusCode(200)
.contentType("application/json")
@@ -91,7 +91,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"givenName": "Peter",
"familyName": "Smith"
},
"relType": "SOLE_AGENT",
"relType": "REPRESENTATIVE",
"contact": { "label": "third contact" }
},
{
@@ -106,7 +106,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"givenName": "Peter",
"familyName": "Smith"
},
"relType": "SOLE_AGENT",
"relType": "REPRESENTATIVE",
"contact": { "label": "second contact" }
},
{
@@ -120,7 +120,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"givenName": "Peter",
"familyName": "Smith"
},
"relType": "SOLE_AGENT",
"relType": "REPRESENTATIVE",
"contact": { "label": "first contact" }
}
]
@@ -153,7 +153,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"contactUuid": "%s"
}
""".formatted(
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
HsOfficeRelationshipTypeResource.ACCOUNTING,
givenAnchorPerson.getUuid(),
givenHolderPerson.getUuid(),
givenContact.getUuid()))
@@ -164,7 +164,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
.statusCode(201)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("relType", is("ACCOUNTING_CONTACT"))
.body("relType", is("ACCOUNTING"))
.body("relAnchor.tradeName", is("Third OHG"))
.body("relHolder.givenName", is("Paul"))
.body("contact.label", is("forth contact"))
@@ -197,7 +197,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"contactUuid": "%s"
}
""".formatted(
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
HsOfficeRelationshipTypeResource.ACCOUNTING,
givenAnchorPersonUuid,
givenHolderPerson.getUuid(),
givenContact.getUuid()))
@@ -230,7 +230,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"contactUuid": "%s"
}
""".formatted(
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
HsOfficeRelationshipTypeResource.ACCOUNTING,
givenAnchorPerson.getUuid(),
givenHolderPersonUuid,
givenContact.getUuid()))
@@ -263,7 +263,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
"contactUuid": "%s"
}
""".formatted(
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
HsOfficeRelationshipTypeResource.ACCOUNTING,
givenAnchorPerson.getUuid(),
givenHolderPerson.getUuid(),
givenContactUuid))
@@ -387,7 +387,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
.statusCode(200)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("relType", is("JOINT_AGENT"))
.body("relType", is("REPRESENTATIVE"))
.body("relAnchor.tradeName", is("Erben Bessler"))
.body("relHolder.familyName", is("Winkler"))
.body("contact.label", is("forth contact"));
@@ -400,7 +400,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
assertThat(rel.getRelAnchor().getTradeName()).contains("Bessler");
assertThat(rel.getRelHolder().getFamilyName()).contains("Winkler");
assertThat(rel.getContact().getLabel()).isEqualTo("forth contact");
assertThat(rel.getRelType()).isEqualTo(HsOfficeRelationshipType.JOINT_AGENT);
assertThat(rel.getRelType()).isEqualTo(HsOfficeRelationshipType.REPRESENTATIVE);
return true;
});
}
@@ -477,7 +477,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
final var newRelationship = HsOfficeRelationshipEntity.builder()
.uuid(UUID.randomUUID())
.relType(HsOfficeRelationshipType.JOINT_AGENT)
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
.relAnchor(givenAnchorPerson)
.relHolder(givenHolderPerson)
.contact(givenContact)

View File

@@ -52,7 +52,7 @@ class HsOfficeRelationshipEntityPatcherUnitTest extends PatchUnitTestBase<
protected HsOfficeRelationshipEntity newInitialEntity() {
final var entity = new HsOfficeRelationshipEntity();
entity.setUuid(INITIAL_RELATIONSHIP_UUID);
entity.setRelType(HsOfficeRelationshipType.SOLE_AGENT);
entity.setRelType(HsOfficeRelationshipType.REPRESENTATIVE);
entity.setRelAnchor(givenInitialAnchorPerson);
entity.setRelHolder(givenInitialHolderPerson);
entity.setContact(givenInitialContact);

View File

@@ -77,7 +77,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder()
.relAnchor(givenAnchorPerson)
.relHolder(givenHolderPerson)
.relType(HsOfficeRelationshipType.JOINT_AGENT)
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
.contact(givenContact)
.build());
return relationshipRepo.save(newRelationship);
@@ -105,7 +105,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder()
.relAnchor(givenAnchorPerson)
.relHolder(givenHolderPerson)
.relType(HsOfficeRelationshipType.JOINT_AGENT)
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
.contact(givenContact)
.build());
return relationshipRepo.save(newRelationship);
@@ -114,26 +114,26 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames,
"hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin",
"hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner",
"hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant"));
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin",
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner",
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant"));
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames,
"{ grant perm * on hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner to role global#global.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
"{ grant perm * on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role global#global.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
"{ grant perm edit on hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner by system and assume }",
"{ grant perm edit on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
"{ grant perm view on hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant to role hs_office_contact#forthcontact.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
"{ grant perm view on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_contact#forthcontact.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin by system and assume }",
"{ grant role hs_office_contact#forthcontact.tenant to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
"{ grant role hs_office_contact#forthcontact.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
null)
);
}
@@ -159,9 +159,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then
allTheseRelationshipsAreReturned(
result,
"rel(relAnchor='First GmbH', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='first contact')",
"rel(relAnchor='Third OHG', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='third contact')",
"rel(relAnchor='Second e.K.', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='second contact')");
"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')");
}
@Test
@@ -176,7 +176,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then:
exactlyTheseRelationshipsAreReturned(
result,
"rel(relAnchor='First GmbH', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='first contact')");
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')");
}
}
@@ -392,7 +392,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
final var newRelationship = HsOfficeRelationshipEntity.builder()
.relType(HsOfficeRelationshipType.JOINT_AGENT)
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
.relAnchor(givenAnchorPerson)
.relHolder(givenHolderPerson)
.contact(givenContact)

View File

@@ -80,7 +80,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
[
{
"debitor": {
"debitorNumber": 10002,
"debitorNumber": 1000212,
"billingContact": { "label": "second contact" }
},
"bankAccount": { "holder": "Second e.K." },
@@ -90,7 +90,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
},
{
"debitor": {
"debitorNumber": 10001,
"debitorNumber": 1000111,
"billingContact": { "label": "first contact" }
},
"bankAccount": { "holder": "First GmbH" },
@@ -100,7 +100,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
},
{
"debitor": {
"debitorNumber": 10003,
"debitorNumber": 1000313,
"billingContact": { "label": "third contact" }
},
"bankAccount": { "holder": "Third OHG" },
@@ -269,7 +269,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
.body("", lenientlyEquals("""
{
"debitor": {
"debitorNumber": 10001,
"debitorNumber": 1000111,
"billingContact": { "label": "first contact" }
},
"bankAccount": {
@@ -321,7 +321,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
.body("", lenientlyEquals("""
{
"debitor": {
"debitorNumber": 10001,
"debitorNumber": 1000111,
"billingContact": { "label": "first contact" }
},
"bankAccount": {
@@ -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(10001: First GmbH)");
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LEGAL 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(10001: First GmbH)");
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LEGAL 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)");

View File

@@ -134,24 +134,24 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest {
initialGrantNames,
// owner
"{ grant perm * on sepamandate#temprefB to role sepamandate#temprefB.owner by system and assume }",
"{ grant role sepamandate#temprefB.owner to role global#global.admin by system and assume }",
"{ grant perm * on sepamandate#temprefB to role sepamandate#temprefB.owner by system and assume }",
"{ grant role sepamandate#temprefB.owner to role global#global.admin by system and assume }",
// admin
"{ grant perm edit on sepamandate#temprefB to role sepamandate#temprefB.admin by system and assume }",
"{ grant role sepamandate#temprefB.admin to role sepamandate#temprefB.owner by system and assume }",
"{ grant role bankaccount#Paul....tenant to role sepamandate#temprefB.admin by system and assume }",
"{ grant perm edit on sepamandate#temprefB to role sepamandate#temprefB.admin by system and assume }",
"{ grant role sepamandate#temprefB.admin to role sepamandate#temprefB.owner by system and assume }",
"{ grant role bankaccount#Paul....tenant to role sepamandate#temprefB.admin by system and assume }",
// agent
"{ grant role sepamandate#temprefB.agent to role sepamandate#temprefB.admin by system and assume }",
"{ grant role debitor#10001FirstGmbH-....tenant to role sepamandate#temprefB.agent by system and assume }",
"{ grant role sepamandate#temprefB.agent to role bankaccount#Paul....admin by system and assume }",
"{ grant role sepamandate#temprefB.agent to role debitor#10001FirstGmbH-....admin by system and assume }",
"{ grant role sepamandate#temprefB.agent to role sepamandate#temprefB.admin by system and assume }",
"{ grant role debitor#1000111:FirstGmbH-....tenant to role sepamandate#temprefB.agent by system and assume }",
"{ grant role sepamandate#temprefB.agent to role bankaccount#Paul....admin by system and assume }",
"{ grant role sepamandate#temprefB.agent to role debitor#1000111:FirstGmbH-....admin by system and assume }",
// tenant
"{ grant role sepamandate#temprefB.tenant to role sepamandate#temprefB.agent by system and assume }",
"{ grant role debitor#10001FirstGmbH-....guest to role sepamandate#temprefB.tenant by system and assume }",
"{ grant role bankaccount#Paul....guest to role sepamandate#temprefB.tenant by system and assume }",
"{ grant role sepamandate#temprefB.tenant to role sepamandate#temprefB.agent by system and assume }",
"{ grant role debitor#1000111:FirstGmbH-....guest to role sepamandate#temprefB.tenant by system and assume }",
"{ grant role bankaccount#Paul....guest to role sepamandate#temprefB.tenant by system and assume }",
// guest
"{ grant perm view on sepamandate#temprefB to role sepamandate#temprefB.guest by system and assume }",

View File

@@ -22,7 +22,7 @@ class PostgresArrayIntegrationTest {
em.createNativeQuery("""
create or replace function returnEmptyArray()
returns text[]
stable leakproof
stable -- leakproof
language plpgsql as $$
declare
emptyArray text[] = '{}';
@@ -42,7 +42,7 @@ class PostgresArrayIntegrationTest {
em.createNativeQuery("""
create or replace function returnStringArray()
returns varchar(63)[]
stable leakproof
stable -- leakproof
language plpgsql as $$
declare
text1 text = 'one';
@@ -65,7 +65,7 @@ class PostgresArrayIntegrationTest {
em.createNativeQuery("""
create or replace function returnUuidArray()
returns uuid[]
stable leakproof
stable -- leakproof
language plpgsql as $$
declare
uuid1 UUID = 'f47ac10b-58cc-4372-a567-0e02b2c3d479';

View File

@@ -10,9 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import static org.hamcrest.Matchers.*;
@SpringBootTest(
@@ -25,9 +22,6 @@ class RbacRoleControllerAcceptanceTest {
@LocalServerPort
private Integer port;
@PersistenceContext
EntityManager em;
@Autowired
Context context;

View File

@@ -1,5 +1,6 @@
package net.hostsharing.test;
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import org.junit.jupiter.api.Named;
import org.junit.jupiter.api.Test;
@@ -232,7 +233,7 @@ public abstract class PatchUnitTestBase<R, E> {
}
}
protected static class JsonNullableProperty<R, RV, E, EV> extends Property<R, RV, E, EV> {
protected static class JsonNullableProperty<R, RV, E extends HasUuid, EV> extends Property<R, RV, E, EV> {
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
public final RV givenPatchValue;

View File

@@ -0,0 +1,9 @@
member_asset_id; bp_id; date; action; amount; comment
30000; 17; 2000-12-06; PAYMENT; 1280.00; for subscription A
31000; 20; 2000-12-06; PAYMENT; 128.00; for subscription B
32000; 17; 2005-01-10; PAYMENT; 2560.00; for subscription C
33001; 17; 2005-01-10; HANDOVER; -512.00; for transfer to 10
33002; 20; 2005-01-10; ADOPTION; 512.00; for transfer from 7
34001; 20; 2016-12-31; CLEARING; -8.00; for cancellation D
34002; 20; 2016-12-31; PAYBACK; -100.00; for cancellation D
34003; 20; 2016-12-31; LOSS; -20.00; for cancellation D
1 member_asset_id bp_id date action amount comment
2 30000 17 2000-12-06 PAYMENT 1280.00 for subscription A
3 31000 20 2000-12-06 PAYMENT 128.00 for subscription B
4 32000 17 2005-01-10 PAYMENT 2560.00 for subscription C
5 33001 17 2005-01-10 HANDOVER -512.00 for transfer to 10
6 33002 20 2005-01-10 ADOPTION 512.00 for transfer from 7
7 34001 20 2016-12-31 CLEARING -8.00 for cancellation D
8 34002 20 2016-12-31 PAYBACK -100.00 for cancellation D
9 34003 20 2016-12-31 LOSS -20.00 for cancellation D

View File

@@ -0,0 +1,4 @@
bp_id;member_id;member_code;member_since;member_until;member_role;author_contract;nondisc_contract;free;exempt_vat;indicator_vat;uid_vat
17;10017;hsh00-mih;2000-12-06;;Aufsichtsrat;2006-10-15;2001-10-15;false;false;NET;DE-VAT-007
20;10020;hsh00-xyz;2000-12-06;2015-12-31;;;;false;false;GROSS;
22;11022;hsh00-xxx;2021-04-01;;;;;true;true;GROSS;
1 bp_id member_id member_code member_since member_until member_role author_contract nondisc_contract free exempt_vat indicator_vat uid_vat
2 17 10017 hsh00-mih 2000-12-06 Aufsichtsrat 2006-10-15 2001-10-15 false false NET DE-VAT-007
3 20 10020 hsh00-xyz 2000-12-06 2015-12-31 false false GROSS
4 22 11022 hsh00-xxx 2021-04-01 true true GROSS

View File

@@ -0,0 +1,13 @@
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
# eine natürliche Person, implizites contractual
1101; 17; Herr; Michael; Mellies; ; ; ; Kleine Freiheit 50; 26524; Hage; DE; ; +49 4931 123456; +49 1522 123456;; mih@example.org; partner,billing,operation
# 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
# eine juristische Person mit nur einem Ansprechpartner und explizitem contractual
1301; 22; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; partner,billing,contractual,operation
1 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
2 # eine natürliche Person, implizites contractual
3 1101; 17; Herr; Michael; Mellies; ; ; ; Kleine Freiheit 50; 26524; Hage; DE; ; +49 4931 123456; +49 1522 123456;; mih@example.org; partner,billing,operation
4 # eine juristische Person mit drei separaten Ansprechpartnern, vip-contact und ex-partner
5 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
6 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
7 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
8 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
9 # eine juristische Person mit nur einem Ansprechpartner und explizitem contractual
10 1301; 22; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; partner,billing,contractual,operation

View File

@@ -0,0 +1,43 @@
#!/bin/sh
host="127.0.0.1"
port="5432"
dbname="hsh02_hsdb"
username="hsh02_hsdb_readonly"
target="/tmp"
dump() {
sql="copy ($1) to stdout with csv header delimiter ';' quote '\"'"
file="${target}/${2}"
psql --host ${host} --port ${port} --user ${username} --command "${sql}" ${dbname} >"${file}"
}
dump "select bp_id, member_id, member_code, member_since, member_until, member_role, author_contract, nondisc_contract, free, exempt_vat, indicator_vat, uid_vat
from business_partner
order by bp_id" \
"business-partners.csv"
dump "select contact_id, bp_id, salut, first_name, last_name, title, firma, co, street, zipcode, city, country, phone_private, phone_office, phone_mobile, fax, email, array_to_string(array_agg(role), ',') as roles
from contact
left join contactrole_ref using(contact_id)
group by contact_id
order by contact_id" \
"contacts.csv"
dump "select sepa_mandat_id, bp_id, bank_customer, bank_name, bank_iban, bank_bic, mandat_ref, mandat_signed, mandat_since, mandat_until, mandat_used
from sepa_mandat
order by sepa_mandat_id" \
"sepa-mandates.csv"
dump "select member_asset_id, bp_id, date, action, amount, comment
from member_asset
WHERE bp_id NOT IN (511912)
order by member_asset_id" \
"asset-transactions.csv"
dump "select member_share_id, bp_id, date, action, quantity, comment
from member_share
WHERE bp_id NOT IN (511912)
order by member_share_id" \
"share-transactions.csv"

View File

@@ -0,0 +1,4 @@
sepa_mandat_id; bp_id; bank_customer; bank_name; bank_iban; bank_bic; mandat_ref; mandat_signed; mandat_since; mandat_until; mandat_used
234234; 17; Michael Mellies; ING Bank AG; DE37500105177419788228; INGDDEFFXXX; MH12345; 2004-06-12; 2004-06-15; ; 2022-10-20
235600; 20; JM e.K.; Targobank AG; DE02300209000106531065; CMCIDEDD; JM33344; 2004-01-15; 2004-01-20;2005-06-27 ;2016-01-18
235662; 20; JM GmbH; ING Bank AG; DE49500105174516484892; INGDDEFFXXX; JM33344; 2005-06-28; 2005-07-01; ; 2016-01-18
1 sepa_mandat_id bp_id bank_customer bank_name bank_iban bank_bic mandat_ref mandat_signed mandat_since mandat_until mandat_used
2 234234 17 Michael Mellies ING Bank AG DE37500105177419788228 INGDDEFFXXX MH12345 2004-06-12 2004-06-15 2022-10-20
3 235600 20 JM e.K. Targobank AG DE02300209000106531065 CMCIDEDD JM33344 2004-01-15 2004-01-20 2005-06-27 2016-01-18
4 235662 20 JM GmbH ING Bank AG DE49500105174516484892 INGDDEFFXXX JM33344 2005-06-28 2005-07-01 2016-01-18

View File

@@ -0,0 +1,5 @@
member_share_id;bp_id; date; action; quantity; comment
33443; 17; 2000-12-06; SUBSCRIPTION; 20; initial share subscription
33451; 20; 2000-12-06; SUBSCRIPTION; 2; initial share subscription
33701; 17; 2005-01-10; SUBSCRIPTION; 40; increase
33810; 20; 2016-12-31; UNSUBSCRIPTION; 22; membership ended
1 member_share_id bp_id date action quantity comment
2 33443 17 2000-12-06 SUBSCRIPTION 20 initial share subscription
3 33451 20 2000-12-06 SUBSCRIPTION 2 initial share subscription
4 33701 17 2005-01-10 SUBSCRIPTION 40 increase
5 33810 20 2016-12-31 UNSUBSCRIPTION 22 membership ended