99 files modified
7 files added
1022 ■■■■■ changed files
README.md 4 ●●●● patch | view | raw | blame | history
build.gradle 36 ●●●●● patch | view | raw | blame | history
etc/allowed-licenses.json 6 ●●●● patch | view | raw | blame | history
gradle.properties 4 ●●● patch | view | raw | blame | history
settings.gradle 9 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/config/PostgresCustomDialect.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/context/Context.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/context/HttpServletRequestBodyCache.java 4 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/context/HttpServletRequestBodyCachingFilter.java 8 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/context/HttpServletRequestWithCachedBody.java 6 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java 21 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountController.java 6 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java 10 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepository.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactEntity.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java 9 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionController.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java 9 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorController.java 4 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcher.java 6 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java 6 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java 29 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcher.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntity.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntityPatcher.java 4 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcher.java 6 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java 9 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipController.java 4 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java 9 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityPatcher.java 6 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepository.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateController.java 22 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java 33 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityPatcher.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/mapper/PostgresDateRange.java 27 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantController.java 4 ●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleEntity.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/stringify/Stringify.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerEntity.java 2 ●●● patch | view | raw | blame | history
src/main/java/net/hostsharing/hsadminng/test/pac/TestPackageEntity.java 2 ●●● patch | view | raw | blame | history
src/main/resources/api-definition/hs-office/api-mappings.yaml 2 ●●● patch | view | raw | blame | history
src/main/resources/api-definition/hs-office/hs-office-sepamandate-schemas.yaml 20 ●●●●● patch | view | raw | blame | history
src/main/resources/db/changelog/250-hs-office-sepamandate.sql 1 ●●●● patch | view | raw | blame | history
src/main/resources/db/changelog/253-hs-office-sepamandate-rbac.sql 1 ●●●● patch | view | raw | blame | history
src/main/resources/db/changelog/258-hs-office-sepamandate-test-data.sql 4 ●●●● patch | view | raw | blame | history
src/main/resources/db/changelog/273-hs-office-debitor-rbac.md 1 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java 14 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/context/ContextIntegrationTests.java 8 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/context/ContextUnitTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java 32 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerAcceptanceTest.java 8 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepositoryIntegrationTest.java 18 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactControllerAcceptanceTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRepositoryIntegrationTest.java 9 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerAcceptanceTest.java 53 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java 10 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java 9 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcherUnitTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java 13 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java 11 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java 3 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java 15 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java 13 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntityPatcherUnitTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcherUnitTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java 13 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonControllerAcceptanceTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRepositoryIntegrationTest.java 8 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityPatcherUnitTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java 11 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java 10 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityPatcherUnitTest.java 98 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityUnitTest.java 21 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java 25 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RawRbacGrantEntity.java 5 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantControllerAcceptanceTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantRepositoryIntegrationTest.java 10 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RawRbacRoleEntity.java 2 ●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerAcceptanceTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerRestTest.java 7 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleRepositoryIntegrationTest.java 6 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepositoryIntegrationTest.java 8 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java 4 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepositoryIntegrationTest.java 8 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageRepositoryIntegrationTest.java 9 ●●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/test/JpaAttempt.java 2 ●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/test/MapperUnitTest.java 6 ●●●● patch | view | raw | blame | history
src/test/java/net/hostsharing/test/StringTemplater.java 4 ●●●● patch | view | raw | blame | history
src/test/resources/migration/asset-transactions.csv 5 ●●●●● patch | view | raw | blame | history
src/test/resources/migration/business_partners.csv 4 ●●●● patch | view | raw | blame | history
src/test/resources/migration/contacts.csv 5 ●●●●● patch | view | raw | blame | history
src/test/resources/migration/sepa-mandates.csv 3 ●●●●● patch | view | raw | blame | history
src/test/resources/migration/share-transactions.csv 5 ●●●●● patch | view | raw | blame | history
README.md
@@ -718,11 +718,11 @@
These interfaces have to be implemented by subclasses named `*Controller`.
All gradle tasks which need the generated interfaces depend on the Gradle task  `processSpring` which controls the code generation.
All gradle tasks which need the generated interfaces depend on the Gradle task  `openApiGenerate` which controls the code generation.
It can also be executed directly:
```shell
gw processSpring
gw openApiGenerate
```
### How to Generate Database Table Diagrams?
build.gradle
@@ -1,8 +1,8 @@
plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.5'
    id 'io.openapiprocessor.openapi-processor' version '2022.2'
    id 'org.springframework.boot' version '3.0.0-SNAPSHOT'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'io.openapiprocessor.openapi-processor' version '2022.2'
    id 'com.github.jk1.dependency-license-report' version '2.1'
    id "org.owasp.dependencycheck" version "7.3.0"
    id "com.diffplug.spotless" version "6.11.0"
@@ -36,6 +36,8 @@
repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
    maven { url 'https://repo.spring.io/snapshot' }
}
java {
@@ -57,11 +59,12 @@
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.8.1'
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.12'
    implementation 'org.springdoc:springdoc-openapi:2.0.0-M7'
    implementation 'org.liquibase:liquibase-core'
    implementation 'com.vladmihalcea:hibernate-types-55:2.20.0'
    implementation 'com.vladmihalcea:hibernate-types-60:2.20.0'
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4'
    implementation 'org.openapitools:jackson-databind-nullable:0.2.3'
    implementation 'org.openapitools:jackson-databind-nullable:0.2.4'
    implementation 'org.apache.commons:commons-text:1.10.0'
    implementation 'org.modelmapper:modelmapper:3.1.0'
    implementation 'org.iban4j:iban4j:3.2.3-RELEASE'
@@ -112,7 +115,7 @@
        processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
        apiPath "$projectDir/src/main/resources/api-definition.yaml"
        mapping "$projectDir/src/main/resources/api-mappings.yaml"
        targetDir "$projectDir/build/generated/sources/openapi"
        targetDir "$projectDir/build/generated/sources/openapi-javax"
        showWarnings true
        openApiNullable true
    }
@@ -121,7 +124,7 @@
        processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
        apiPath "$projectDir/src/main/resources/api-definition/rbac/rbac.yaml"
        mapping "$projectDir/src/main/resources/api-definition/rbac/api-mappings.yaml"
        targetDir "$projectDir/build/generated/sources/openapi"
        targetDir "$projectDir/build/generated/sources/openapi-javax"
        showWarnings true
        openApiNullable true
    }
@@ -130,7 +133,7 @@
        processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
        apiPath "$projectDir/src/main/resources/api-definition/test/test.yaml"
        mapping "$projectDir/src/main/resources/api-definition/test/api-mappings.yaml"
        targetDir "$projectDir/build/generated/sources/openapi"
        targetDir "$projectDir/build/generated/sources/openapi-javax"
        showWarnings true
        openApiNullable true
    }
@@ -139,7 +142,7 @@
        processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
        apiPath "$projectDir/src/main/resources/api-definition/hs-office/hs-office.yaml"
        mapping "$projectDir/src/main/resources/api-definition/hs-office/api-mappings.yaml"
        targetDir "$projectDir/build/generated/sources/openapi"
        targetDir "$projectDir/build/generated/sources/openapi-javax"
        showWarnings true
        openApiNullable true
    }
@@ -152,6 +155,17 @@
}
project.tasks.processResources.dependsOn processSpring
project.tasks.compileJava.dependsOn processSpring
// Rename javax to jakarta in OpenApi generated java files because
// io.openapiprocessor.openapi-processor 2022.2 does not yet support the openapiprocessor useSpringBoot3 config option.
task openApiGenerate(type: Copy) {
    from "$buildDir/generated/sources/openapi-javax"
    into "$buildDir/generated/sources/openapi"
    filter { line -> line.replaceAll('javax', 'jakarta') }
}
compileJava.source "$buildDir/generated/sources/openapi"
compileJava.dependsOn openApiGenerate
openApiGenerate.dependsOn processSpring
// Spotless Code Formatting
spotless {
@@ -271,8 +285,8 @@
    targetTests = ['net.hostsharing.hsadminng.**.*UnitTest', 'net.hostsharing.hsadminng.**.*RestTest']
    excludedTestClasses = ['**AcceptanceTest*', '**IntegrationTest*']
    pitestVersion = '1.9.0'
    junit5PluginVersion = '1.0.0'
    pitestVersion = '1.9.9'
    junit5PluginVersion = '1.1.0'
    threads = 4
etc/allowed-licenses.json
@@ -1,12 +1,14 @@
{
    "allowedLicenses": [
        { "moduleLicense": "Apache 2.0" },
        { "moduleLicense": "Apache 2" },
        { "moduleLicense": "Apache License 2.0" },
        { "moduleLicense": "Apache License, Version 2.0" },
        { "moduleLicense": "The Apache Software License, Version 2.0" },
        { "moduleLicense": "BSD License" },
        { "moduleLicense": "BSD-2-Clause" },
        { "moduleLicense": "The BSD License" },
        { "moduleLicense": "CDDL 1.1" },
        { "moduleLicense": "CDDL/GPLv2+CE" },
@@ -29,6 +31,8 @@
        { "moduleLicense": "MIT License" },
        { "moduleLicense": "MIT" },
        { "moduleLicense": "The MIT License (MIT)" },
        { "moduleLicense": "The MIT License" }
        { "moduleLicense": "The MIT License" },
        { "moduleName": "org.springdoc:springdoc-openapi" }
    ]
}
gradle.properties
@@ -1,8 +1,6 @@
# Spring BOM overrides
postgresql.version = 42.4.1
snakeyaml.version = 1.32
jackson-databind = 2.13.4
# currently none necessary
# TODO: can be removed if all dependencies are JDK 16 compliant, check with `gw clean check`
# and check output for "cannot access class ... because module jdk.compiler does not export ..."
settings.gradle
@@ -1 +1,10 @@
pluginManagement {
    repositories {
        maven { url 'https://repo.spring.io/milestone' }
        maven { url 'https://repo.spring.io/snapshot' }
        gradlePluginPortal()
        mavenCentral()
    }
}
rootProject.name = 'hsadmin-ng'
src/main/java/net/hostsharing/hsadminng/config/PostgresCustomDialect.java
@@ -1,15 +1,14 @@
package net.hostsharing.hsadminng.config;
import org.hibernate.dialect.PostgreSQL95Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import java.sql.Types;
import static org.hibernate.dialect.DatabaseVersion.make;
@SuppressWarnings("unused") // configured in application.yml
public class PostgresCustomDialect extends PostgreSQL95Dialect {
public class PostgresCustomDialect extends PostgreSQLDialect {
    public PostgresCustomDialect() {
        this.registerHibernateType(Types.OTHER, "pg-uuid");
        this.registerHibernateType(Types.ARRAY, "array");
        super(make(13, 7));
    }
}
src/main/java/net/hostsharing/hsadminng/context/Context.java
@@ -1,7 +1,5 @@
package net.hostsharing.hsadminng.context;
import com.vladmihalcea.hibernate.type.array.StringArrayType;
import com.vladmihalcea.hibernate.type.array.UUIDArrayType;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
@@ -10,9 +8,9 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
@@ -79,21 +77,15 @@
    }
    public UUID getCurrentUserUUid() {
        return (UUID) em.createNativeQuery("select currentUserUUid()").getSingleResult();
        return (UUID) em.createNativeQuery("select currentUserUUid()", UUID.class).getSingleResult();
    }
    public String[] getAssumedRoles() {
        return (String[]) em.createNativeQuery("select assumedRoles() as roles")
                .unwrap(org.hibernate.query.NativeQuery.class)
                .addScalar("roles", StringArrayType.INSTANCE)
                .getSingleResult();
        return (String[]) em.createNativeQuery("select assumedRoles() as roles", String[].class).getSingleResult();
    }
    public UUID[] currentSubjectsUuids() {
        return (UUID[]) em.createNativeQuery("select currentSubjectsUuids() as uuids")
                .unwrap(org.hibernate.query.NativeQuery.class)
                .addScalar("uuids", UUIDArrayType.INSTANCE) // TODO.blog
                .getSingleResult();
        return (UUID[]) em.createNativeQuery("select currentSubjectsUuids() as uuids", UUID[].class).getSingleResult();
    }
    public static String getCallerMethodNameFromStackFrame(final int skipFrames) {
@@ -105,7 +97,7 @@
                                .filter(c -> c.getDeclaringClass()
                                        .getPackageName()
                                        .startsWith("net.hostsharing.hsadminng"))
                                .filter(c -> !c.getDeclaringClass().getName().contains("BySpringCGLIB$$"))
                                .filter(c -> !c.getDeclaringClass().getName().contains("$$SpringCGLIB$$"))
                                .findFirst());
        return caller.map(
                        c -> c.getDeclaringClass().getSimpleName() + "." + c.getMethodName())
src/main/java/net/hostsharing/hsadminng/context/HttpServletRequestBodyCache.java
@@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.context;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
src/main/java/net/hostsharing/hsadminng/context/HttpServletRequestBodyCachingFilter.java
@@ -3,10 +3,10 @@
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
src/main/java/net/hostsharing/hsadminng/context/HttpServletRequestWithCachedBody.java
@@ -2,9 +2,9 @@
import org.springframework.util.StreamUtils;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java
@@ -5,7 +5,9 @@
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.lang.Nullable;
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException;
import org.springframework.orm.jpa.JpaSystemException;
@@ -15,8 +17,8 @@
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import javax.persistence.EntityNotFoundException;
import javax.validation.ValidationException;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.ValidationException;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.regex.Pattern;
@@ -79,11 +81,18 @@
    @Override
    @SuppressWarnings("unchecked,rawtypes")
    protected ResponseEntity handleExceptionInternal(
            Exception exc, @Nullable Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
            Exception exc, @Nullable Object body, HttpHeaders headers, HttpStatusCode statusCode, WebRequest request) {
        final var response = super.handleExceptionInternal(exc, body, headers, status, request);
        return errorResponse(request, response.getStatusCode(),
        final var response = super.handleExceptionInternal(exc, body, headers, statusCode, request);
        return errorResponse(request, HttpStatus.valueOf(statusCode.value()),
                Optional.ofNullable(response.getBody()).map(Object::toString).orElse(firstMessageLine(exc)));
    }
    @Override
    @SuppressWarnings("unchecked,rawtypes")
    protected ResponseEntity handleHttpMessageNotReadable(
            HttpMessageNotReadableException exc, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
        final var message = line(exc.getMessage(), 0);
        return errorResponse(request, HttpStatus.BAD_REQUEST, message);
    }
    @Override
@@ -91,7 +100,7 @@
    protected ResponseEntity handleMethodArgumentNotValid(
            MethodArgumentNotValidException exc,
            HttpHeaders headers,
            HttpStatus status,
            HttpStatusCode statusCode,
            WebRequest request) {
        final var errorList = exc
                .getBindingResult()
src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountController.java
@@ -1,10 +1,10 @@
package net.hostsharing.hsadminng.hs.office.bankaccount;
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeBankAccountsApi;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountInsertResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountResource;
import net.hostsharing.hsadminng.mapper.Mapper;
import org.iban4j.BicUtil;
import org.iban4j.IbanUtil;
import org.springframework.beans.factory.annotation.Autowired;
@@ -57,7 +57,11 @@
        final var entityToSave = mapper.map(body, HsOfficeBankAccountEntity.class);
        final var saved = bankAccountRepo.save(entityToSave);
//        em.persist(entityToSave);
//        final var saved = entityToSave;
//        em.flush();
        final var uri =
                MvcUriComponentsBuilder.fromController(getClass())
src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java
@@ -5,12 +5,11 @@
import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.UUID;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@@ -34,6 +33,7 @@
    @Id
    @GeneratedValue
    private UUID uuid;
    private String holder;
    private String iban;
src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepository.java
@@ -21,7 +21,7 @@
    List<HsOfficeBankAccountEntity> findByIbanOrderByIban(String iban);
    HsOfficeBankAccountEntity save(final HsOfficeBankAccountEntity entity);
    <S extends HsOfficeBankAccountEntity> S save(S entity);
    int deleteByUuid(final UUID uuid);
src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactEntity.java
@@ -7,7 +7,7 @@
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java
@@ -4,7 +4,6 @@
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopAssetsApi;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionInsertResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource;
import net.hostsharing.hsadminng.mapper.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
@@ -14,8 +13,8 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.validation.Valid;
import javax.validation.ValidationException;
import jakarta.validation.Valid;
import jakarta.validation.ValidationException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java
@@ -8,9 +8,8 @@
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
@@ -20,10 +19,6 @@
@Entity
@Table(name = "hs_office_coopassetstransaction_rv")
@TypeDef(
        name = "pgsql_enum",
        typeClass = PostgreSQLEnumType.class
)
@Getter
@Setter
@Builder
@@ -52,7 +47,7 @@
    @Column(name = "transactiontype")
    @Enumerated(EnumType.STRING)
    @Type( type = "pgsql_enum" )
    @Type(PostgreSQLEnumType.class)
    private HsOfficeCoopAssetsTransactionType transactionType;
    @Column(name = "valuedate")
src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionController.java
@@ -1,11 +1,10 @@
package net.hostsharing.hsadminng.hs.office.coopshares;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactResource;
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource;
import net.hostsharing.hsadminng.mapper.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
@@ -14,8 +13,8 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.validation.Valid;
import javax.validation.ValidationException;
import jakarta.validation.Valid;
import jakarta.validation.ValidationException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java
@@ -7,9 +7,8 @@
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.UUID;
@@ -17,10 +16,6 @@
@Entity
@Table(name = "hs_office_coopsharestransaction_rv")
@TypeDef(
        name = "pgsql_enum",
        typeClass = PostgreSQLEnumType.class
)
@Getter
@Setter
@Builder
@@ -48,7 +43,7 @@
    @Column(name = "transactiontype")
    @Enumerated(EnumType.STRING)
    @Type(type = "pgsql_enum")
    @Type(PostgreSQLEnumType.class)
    private HsOfficeCoopSharesTransactionType transactionType;
    @Column(name = "valuedate")
src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorController.java
@@ -12,8 +12,8 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java
@@ -9,7 +9,7 @@
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcher.java
@@ -1,11 +1,11 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
class HsOfficeDebitorEntityPatcher implements EntityPatcher<HsOfficeDebitorPatchResource> {
src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java
@@ -12,9 +12,9 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.validation.Valid;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java
@@ -12,31 +12,22 @@
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.UUID;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.*;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_membership_rv")
@TypeDef(
        name = "pgsql_enum",
        typeClass = PostgreSQLEnumType.class
)
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DisplayName("Membership")
@TypeDef(
        typeClass = PostgreSQLRangeType.class,
        defaultForType = Range.class
)
public class HsOfficeMembershipEntity implements Stringifyable {
    private static Stringify<HsOfficeMembershipEntity> stringify = stringify(HsOfficeMembershipEntity.class)
@@ -65,21 +56,31 @@
    private int memberNumber;
    @Column(name = "validity", columnDefinition = "daterange")
    @Type(PostgreSQLRangeType.class)
    private Range<LocalDate> validity;
    @Column(name = "reasonfortermination")
    @Enumerated(EnumType.STRING)
    @Type(type = "pgsql_enum")
    @Type(PostgreSQLEnumType.class)
    private HsOfficeReasonForTermination reasonForTermination;
    public void setValidFrom(final LocalDate validFrom) {
        validity = toPostgresDateRange(validFrom, getValidity().upper());
        setValidity(toPostgresDateRange(validFrom, getValidTo()));
    }
    public void setValidTo(final LocalDate validTo) {
        validity = toPostgresDateRange(getValidity().lower(), validTo);
        setValidity(toPostgresDateRange(getValidFrom(), validTo));
    }
    public LocalDate getValidFrom() {
        return lowerInclusiveFromPostgresDateRange(getValidity());
    }
    public LocalDate getValidTo() {
        return upperInclusiveFromPostgresDateRange(getValidity());
    }
    public Range<LocalDate> getValidity() {
        if (validity == null) {
            validity = Range.infinite(LocalDate.class);
src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcher.java
@@ -6,7 +6,7 @@
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.Optional;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java
@@ -1,7 +1,6 @@
package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartnersApi;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
@@ -13,8 +12,8 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntity.java
@@ -5,7 +5,7 @@
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntityPatcher.java
@@ -1,10 +1,10 @@
package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerDetailsPatchResource;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerDetailsPatchResource;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
class HsOfficePartnerDetailsEntityPatcher implements EntityPatcher<HsOfficePartnerDetailsPatchResource> {
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java
@@ -9,7 +9,7 @@
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcher.java
@@ -1,12 +1,12 @@
package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.UUID;
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java
@@ -8,19 +8,14 @@
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_person_rv")
@TypeDef(
        name = "pgsql_enum",
        typeClass = PostgreSQLEnumType.class
)
@Getter
@Setter
@Builder
@@ -42,7 +37,7 @@
    @Column(name = "persontype")
    @Enumerated(EnumType.STRING)
    @Type(type = "pgsql_enum")
    @Type(PostgreSQLEnumType.class)
    private HsOfficePersonType personType;
    @Column(name = "tradename")
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipController.java
@@ -12,8 +12,8 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java
@@ -7,19 +7,14 @@
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_relationship_rv")
@TypeDef(
        name = "pgsql_enum",
        typeClass = PostgreSQLEnumType.class
)
@Getter
@Setter
@Builder
@@ -52,7 +47,7 @@
    @Column(name = "reltype")
    @Enumerated(EnumType.STRING)
    @Type(type = "pgsql_enum")
    @Type(PostgreSQLEnumType.class)
    private HsOfficeRelationshipType relType;
    @Override
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityPatcher.java
@@ -1,11 +1,11 @@
package net.hostsharing.hsadminng.hs.office.relationship;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationshipPatchResource;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.UUID;
class HsOfficeRelationshipEntityPatcher implements EntityPatcher<HsOfficeRelationshipPatchResource> {
src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepository.java
@@ -3,7 +3,7 @@
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateController.java
@@ -12,9 +12,9 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.validation.Valid;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
@@ -32,7 +32,7 @@
    private Mapper mapper;
    @Autowired
    private HsOfficeSepaMandateRepository SepaMandateRepo;
    private HsOfficeSepaMandateRepository sepaMandateRepo;
    @PersistenceContext
    private EntityManager em;
@@ -45,7 +45,7 @@
            final String iban) {
        context.define(currentUser, assumedRoles);
        final var entities = SepaMandateRepo.findSepaMandateByOptionalIban(iban);
        final var entities = sepaMandateRepo.findSepaMandateByOptionalIban(iban);
        final var resources = mapper.mapList(entities, HsOfficeSepaMandateResource.class,
                SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER);
@@ -63,7 +63,7 @@
        final var entityToSave = mapper.map(body, HsOfficeSepaMandateEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER);
        final var saved = SepaMandateRepo.save(entityToSave);
        final var saved = sepaMandateRepo.save(entityToSave);
        final var uri =
                MvcUriComponentsBuilder.fromController(getClass())
@@ -84,7 +84,7 @@
        context.define(currentUser, assumedRoles);
        final var result = SepaMandateRepo.findByUuid(sepaMandateUuid);
        final var result = sepaMandateRepo.findByUuid(sepaMandateUuid);
        if (result.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
@@ -100,7 +100,7 @@
            final UUID sepaMandateUuid) {
        context.define(currentUser, assumedRoles);
        final var result = SepaMandateRepo.deleteByUuid(sepaMandateUuid);
        final var result = sepaMandateRepo.deleteByUuid(sepaMandateUuid);
        if (result == 0) {
            return ResponseEntity.notFound().build();
        }
@@ -118,11 +118,11 @@
        context.define(currentUser, assumedRoles);
        final var current = SepaMandateRepo.findByUuid(sepaMandateUuid).orElseThrow();
        final var current = sepaMandateRepo.findByUuid(sepaMandateUuid).orElseThrow();
        current.setValidity(toPostgresDateRange(current.getValidity().lower(), body.getValidTo()));
        new HsOfficeSepaMandateEntityPatcher(current).apply(body);
        final var saved = SepaMandateRepo.save(current);
        final var saved = sepaMandateRepo.save(current);
        final var mapped = mapper.map(saved, HsOfficeSepaMandateResource.class, SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER);
        return ResponseEntity.ok(mapped);
    }
src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java
@@ -8,12 +8,13 @@
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.UUID;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.*;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@@ -24,15 +25,12 @@
@NoArgsConstructor
@AllArgsConstructor
@DisplayName("SEPA-Mandate")
@TypeDef(
        typeClass = PostgreSQLRangeType.class,
        defaultForType = Range.class
)
public class HsOfficeSepaMandateEntity implements Stringifyable {
    private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
            .withProp(e -> e.getBankAccount().getIban())
            .withProp(HsOfficeSepaMandateEntity::getReference)
            .withProp(HsOfficeSepaMandateEntity::getAgreement)
            .withProp(e -> e.getValidity().asString())
            .withSeparator(", ")
            .quotedValues(false);
@@ -51,8 +49,28 @@
    private @Column(name = "reference") String reference;
    @Column(name="agreement", columnDefinition = "date")
    private LocalDate agreement;
    @Column(name = "validity", columnDefinition = "daterange")
    private Range<LocalDate> validity;
    @Type(PostgreSQLRangeType.class)
    private Range<LocalDate> validity = Range.infinite(LocalDate.class);
    public void setValidFrom(final LocalDate validFrom) {
        setValidity(toPostgresDateRange(validFrom, getValidTo()));
    }
    public void setValidTo(final LocalDate validTo) {
        setValidity(toPostgresDateRange(getValidFrom(), validTo));
    }
    public LocalDate getValidFrom() {
        return lowerInclusiveFromPostgresDateRange(getValidity());
    }
    public LocalDate getValidTo() {
        return upperInclusiveFromPostgresDateRange(getValidity());
    }
    @Override
    public String toString() {
@@ -63,4 +81,5 @@
    public String toShortString() {
        return reference;
    }
}
src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityPatcher.java
New file
@@ -0,0 +1,26 @@
package net.hostsharing.hsadminng.hs.office.sepamandate;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandatePatchResource;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
public class HsOfficeSepaMandateEntityPatcher implements EntityPatcher<HsOfficeSepaMandatePatchResource> {
    private final HsOfficeSepaMandateEntity entity;
    public HsOfficeSepaMandateEntityPatcher(final HsOfficeSepaMandateEntity entity) {
        this.entity = entity;
    }
    @Override
    public void apply(final HsOfficeSepaMandatePatchResource resource) {
        OptionalFromJson.of(resource.getReference()).ifPresent(
                entity::setReference);
        OptionalFromJson.of(resource.getAgreement()).ifPresent(
                entity::setAgreement);
        OptionalFromJson.of(resource.getValidFrom()).ifPresent(
                entity::setValidFrom);
        OptionalFromJson.of(resource.getValidTo()).ifPresent(
                entity::setValidTo);
    }
}
src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java
@@ -2,13 +2,12 @@
import net.hostsharing.hsadminng.errors.DisplayName;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ReflectionUtils;
import javax.persistence.EntityManager;
import javax.persistence.ManyToOne;
import javax.persistence.PersistenceContext;
import javax.validation.ValidationException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PersistenceContext;
import jakarta.validation.ValidationException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.function.BiConsumer;
src/main/java/net/hostsharing/hsadminng/mapper/PostgresDateRange.java
@@ -9,14 +9,25 @@
public class PostgresDateRange {
    public static Range<LocalDate> toPostgresDateRange(
            final LocalDate validFrom,
            final LocalDate validTo) {
        return validFrom != null
                ? validTo != null
                    ? Range.closedOpen(validFrom, validTo.plusDays(1))
                    : Range.closedInfinite(validFrom)
                : validTo != null
                    ? Range.infiniteOpen(validTo.plusDays(1))
            final LocalDate lowerInclusive,
            final LocalDate upperInclusive) {
        return lowerInclusive != null
                ? upperInclusive != null
                    ? Range.closedOpen(lowerInclusive, upperInclusive.plusDays(1))
                    : Range.closedInfinite(lowerInclusive)
                : upperInclusive != null
                    ? Range.infiniteOpen(upperInclusive.plusDays(1))
                    : Range.infinite(LocalDate.class);
    }
    public static LocalDate lowerInclusiveFromPostgresDateRange(
            final Range<LocalDate> range) {
        return range.lower();
    }
    public static LocalDate upperInclusiveFromPostgresDateRange(
        final Range<LocalDate> range) {
        return range.upper() != null ? range.upper().minusDays(1) : null;
    }
}
src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantController.java
@@ -10,8 +10,8 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.UUID;
src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java
@@ -4,7 +4,7 @@
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleType;
import org.springframework.data.annotation.Immutable;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleEntity.java
@@ -2,10 +2,9 @@
import lombok.*;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.annotation.Immutable;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
@@ -19,8 +18,7 @@
public class RbacRoleEntity {
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @GeneratedValue
    private UUID uuid;
    @Column(name = "objectuuid")
src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java
@@ -1,13 +1,12 @@
package net.hostsharing.hsadminng.rbac.rbacuser;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.annotation.Immutable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
@@ -27,8 +26,7 @@
    private static DateTimeFormatter DATE_FORMAT_WITH_FULLHOUR = DateTimeFormatter.ofPattern("MM-dd-yyyy HH");
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @GeneratedValue
    private UUID uuid;
    private String name;
src/main/java/net/hostsharing/hsadminng/stringify/Stringify.java
@@ -2,7 +2,7 @@
import net.hostsharing.hsadminng.errors.DisplayName;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerEntity.java
@@ -5,7 +5,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
src/main/java/net/hostsharing/hsadminng/test/pac/TestPackageEntity.java
@@ -6,7 +6,7 @@
import lombok.Setter;
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
src/main/resources/api-definition/hs-office/api-mappings.yaml
@@ -29,7 +29,7 @@
            null: org.openapitools.jackson.nullable.JsonNullable
        /api/hs/office/debitors/{debitorUUID}:
            null: org.openapitools.jackson.nullable.JsonNullable
        /api/hs/office/sepamandates/{debitorUUID}:
        /api/hs/office/sepamandates/{sepaMandateUUID}:
            null: org.openapitools.jackson.nullable.JsonNullable
        /api/hs/office/memberships/{membershipUUID}:
            null: org.openapitools.jackson.nullable.JsonNullable
src/main/resources/api-definition/hs-office/hs-office-sepamandate-schemas.yaml
@@ -15,6 +15,9 @@
                    $ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
                reference:
                   type: string
                agreement:
                    type: string
                    format: date
                validFrom:
                   type: string
                   format: date
@@ -25,9 +28,21 @@
        HsOfficeSepaMandatePatch:
            type: object
            properties:
                reference:
                    type: string
                    nullable: true
                agreement:
                    type: string
                    format: date
                    nullable: true
                validFrom:
                    type: string
                    format: date
                    nullable: true
                validTo:
                    type: string
                    format: date
                    nullable: true
            additionalProperties: false
        HsOfficeSepaMandateInsert:
@@ -44,6 +59,10 @@
                reference:
                    type: string
                    nullable: false
                agreement:
                    type: string
                    format: date
                    nullable: false
                validFrom:
                    type: string
                    format: date
@@ -56,5 +75,6 @@
                - debitorUuid
                - bankAccountUuid
                - reference
                - agreement
                - validFrom
            additionalProperties: false
src/main/resources/db/changelog/250-hs-office-sepamandate.sql
@@ -10,6 +10,7 @@
    debitorUuid         uuid not null references hs_office_debitor(uuid),
    bankAccountUuid     uuid not null references hs_office_bankaccount(uuid),
    reference           varchar(96) not null,
    agreement           date not null,
    validity            daterange not null
);
--//
src/main/resources/db/changelog/253-hs-office-sepamandate-rbac.sql
@@ -102,6 +102,7 @@
call generateRbacRestrictedView('hs_office_sepamandate',
    orderby => 'target.reference',
    columnUpdates => $updates$
        agreement = new.agreement,
        validity = new.validity
    $updates$);
--//
src/main/resources/db/changelog/258-hs-office-sepamandate-test-data.sql
@@ -31,8 +31,8 @@
    raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
    raise notice '- using bankAccount (%): %', relatedBankAccount.uuid, relatedBankAccount;
    insert
        into hs_office_sepamandate (uuid, debitoruuid, bankAccountuuid, reference, validity)
        values (uuid_generate_v4(), relatedDebitor.uuid, relatedBankAccount.uuid, 'ref'||idName, daterange('20221001' , '20261231', '[]'));
        into hs_office_sepamandate (uuid, debitoruuid, bankAccountuuid, reference, agreement, validity)
        values (uuid_generate_v4(), relatedDebitor.uuid, relatedBankAccount.uuid, 'ref'||idName, '20220930', daterange('20221001' , '20261231', '[]'));
end; $$;
--//
src/main/resources/db/changelog/273-hs-office-debitor-rbac.md
@@ -171,7 +171,6 @@
        %% incoming
            role:hsOfficeDebitor.admin ---> role:hsOfficeDebitor.agent         
            role:hsOfficePartner.admin --> role:hsOfficeDebitor.agent
            role:hsOfficeContact.admin --> role:hsOfficeDebitor.agent
        %% outgoing
            role:hsOfficeDebitor.agent --> role:hsOfficeBankAccount.tenant
    
src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java
@@ -9,7 +9,7 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.RestController;
import static com.tngtech.archunit.core.domain.JavaModifier.*;
import static com.tngtech.archunit.core.domain.JavaModifier.ABSTRACT;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*;
import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices;
@@ -197,19 +197,19 @@
    @ArchTest
    @SuppressWarnings("unused")
    public static final ArchRule doNotUseJavaxTransactionAnnotationAtClassLevel = noClasses()
            .should().beAnnotatedWith(javax.transaction.Transactional.class.getName())
    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(),
                    javax.transaction.Transactional.class));
                    jakarta.transaction.Transactional.class));
    @ArchTest
    @SuppressWarnings("unused")
    public static final ArchRule doNotUseJavaxTransactionAnnotationAtMethodLevel = noMethods()
            .should().beAnnotatedWith(javax.transaction.Transactional.class)
    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(),
                    javax.transaction.Transactional.class.getName()));
                    jakarta.transaction.Transactional.class.getName()));
    @ArchTest
    @SuppressWarnings("unused")
src/test/java/net/hostsharing/hsadminng/context/ContextIntegrationTests.java
@@ -10,7 +10,7 @@
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
@@ -64,7 +64,7 @@
        // then
        result.assertExceptionWithRootCauseMessage(
                javax.persistence.PersistenceException.class,
                jakarta.persistence.PersistenceException.class,
                "ERROR: [403] undefined has no permission to assume role test_package#yyy00.admin");
    }
@@ -77,7 +77,7 @@
        // then
        result.assertExceptionWithRootCauseMessage(
                javax.persistence.PersistenceException.class,
                jakarta.persistence.PersistenceException.class,
                "[401] user unknown@example.org given in `defineContext(...)` does not exist");
    }
@@ -106,7 +106,7 @@
        // then
        result.assertExceptionWithRootCauseMessage(
                javax.persistence.PersistenceException.class,
                jakarta.persistence.PersistenceException.class,
                "ERROR: [403] user customer-admin@xxx.example.com has no permission to assume role test_package#yyy00.admin");
    }
}
src/test/java/net/hostsharing/hsadminng/context/ContextUnitTest.java
@@ -10,9 +10,9 @@
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Collections;
src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java
@@ -9,7 +9,6 @@
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.validation.BindingResult;
@@ -17,7 +16,7 @@
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.context.request.WebRequest;
import javax.persistence.EntityNotFoundException;
import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import java.util.NoSuchElementException;
@@ -40,7 +39,7 @@
        final var errorResponse = exceptionHandler.handleConflict(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(409);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(409);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("First Line");
    }
@@ -58,7 +57,7 @@
        final var errorResponse = exceptionHandler.handleConflict(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
        assertThat(errorResponse.getBody()).isNotNull()
                .extracting(CustomErrorResponse::getMessage).isEqualTo("Second Line");
    }
@@ -74,7 +73,7 @@
        final var errorResponse = exceptionHandler.handleJpaExceptions(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(401);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(401);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [401] First Line");
    }
@@ -91,7 +90,7 @@
        final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("Unable to find Partner with uuid 12345-123454");
    }
@@ -108,7 +107,7 @@
        final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo(
                "Unable to find net.hostsharing.hsadminng.WhateverEntity with id 12345-123454");
    }
@@ -125,7 +124,7 @@
        final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("whatever error message");
    }
@@ -143,7 +142,7 @@
        final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("Unable to find NoDisplayNameEntity with uuid 12345-123454");
    }
@@ -158,7 +157,7 @@
        final var errorResponse = exceptionHandler.handleJpaExceptions(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(500);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(500);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [999] First Line");
    }
@@ -172,7 +171,7 @@
        final var errorResponse = exceptionHandler.handleNoSuchElementException(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(404);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(404);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("some error message");
    }
@@ -191,7 +190,7 @@
        final var errorResponse = exceptionHandler.handleIbanAndBicExceptions(givenException, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("given error message");
    }
@@ -214,9 +213,10 @@
                HttpHeaders.EMPTY, HttpStatus.BAD_REQUEST, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
        assertThat(errorResponse.getBody())
                .isInstanceOf(CustomErrorResponse.class)
                .extracting("statusCode").isEqualTo(400);
        assertThat(errorResponse.getBody())
                .extracting("message")
                .isEqualTo("[someField expected to be something but is \"someRejectedValue\"]");
    }
@@ -231,7 +231,7 @@
        final var errorResponse = exceptionHandler.handleOtherExceptions(givenThrowable, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(500);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(500);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("First Line");
    }
@@ -245,7 +245,7 @@
        final var errorResponse = exceptionHandler.handleOtherExceptions(givenThrowable, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(418);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(418);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [418] First Line");
    }
@@ -259,7 +259,7 @@
        final var errorResponse = exceptionHandler.handleOtherExceptions(givenThrowable, givenWebRequest);
        // then
        assertThat(errorResponse.getStatusCodeValue()).isEqualTo(500);
        assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(500);
        assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [500] java.lang.Error");
    }
src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerAcceptanceTest.java
@@ -2,10 +2,9 @@
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
import org.apache.commons.lang3.RandomStringUtils;
import org.json.JSONException;
@@ -15,8 +14,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
@@ -322,7 +321,6 @@
        return jpaAttempt.transacted(() -> {
            context.define(creatingUser);
            final var newBankAccount = HsOfficeBankAccountEntity.builder()
                    .uuid(UUID.randomUUID())
                    .holder("temp acc #" + RandomStringUtils.randomAlphabetic(3))
                    .iban("DE93500105179473626226")
                    .bic("INGDDEFFXXX")
src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepositoryIntegrationTest.java
@@ -11,19 +11,14 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.junit.jupiter.Container;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
@@ -35,7 +30,7 @@
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
@Import( { Context.class, JpaAttempt.class })
@Import({ Context.class, JpaAttempt.class })
class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTest {
    @Autowired
@@ -55,9 +50,6 @@
    @MockBean
    HttpServletRequest request;
    @Container
    Container postgres;
    @Nested
    class CreateBankAccount {
@@ -106,7 +98,7 @@
            // when
            attempt(em, () -> bankAccountRepo.save(
                    hsOfficeBankAccount("some temp acc C", "DE25500105176934832579", "INGDDEFFXXX"))
            ).assumeSuccessful();
            ).assertSuccessful();
            // then
            final var roles = rawRoleRepo.findAll();
src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactControllerAcceptanceTest.java
@@ -2,9 +2,9 @@
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
import org.apache.commons.lang3.RandomStringUtils;
import org.json.JSONException;
@@ -17,8 +17,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRepositoryIntegrationTest.java
@@ -14,14 +14,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.testcontainers.junit.jupiter.Container;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerAcceptanceTest.java
@@ -4,8 +4,6 @@
import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
@@ -18,8 +16,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.time.LocalDate;
import java.util.UUID;
@@ -235,16 +233,26 @@
    }
    @Nested
    @Accepts({"CoopAssetTransaction:R(Read)"})
    @Accepts({ "CoopAssetTransaction:R(Read)" })
    class GetCoopAssetTransaction {
        @Test
        void globalAdmin_withoutAssumedRole_canGetArbitraryCoopAssetTransaction() {
            context.define("superuser-alex@hostsharing.net");
            final var givenCoopAssetTransactionUuid = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(null, LocalDate.of(2010, 3, 15), LocalDate.of(2010, 3, 15)).get(0).getUuid();
            final var givenCoopAssetTransactionUuid = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
                    null,
                    LocalDate.of(2010, 3, 15),
                    LocalDate.of(2010, 3, 15)).get(0).getUuid();
            RestAssured // @formatter:off
                .given().header("current-user", "superuser-alex@hostsharing.net").port(port).when().get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid).then().log().body().assertThat().statusCode(200).contentType("application/json").body("", lenientlyEquals("""
                .given().header("current-user", "superuser-alex@hostsharing.net")
                    .port(port)
                .when()
                    .get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
                .then().log().body().assertThat()
                    .statusCode(200)
                    .contentType("application/json")
                    .body("", lenientlyEquals("""
                    {
                        "transactionType": "DEPOSIT"
                    }
@@ -252,23 +260,42 @@
        }
        @Test
        @Accepts({"CoopAssetTransaction:X(Access Control)"})
        @Accepts({ "CoopAssetTransaction:X(Access Control)" })
        void normalUser_canNotGetUnrelatedCoopAssetTransaction() {
            context.define("superuser-alex@hostsharing.net");
            final var givenCoopAssetTransactionUuid = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(null, LocalDate.of(2010, 3, 15), LocalDate.of(2010, 3, 15)).get(0).getUuid();
            final var givenCoopAssetTransactionUuid = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
                    null,
                    LocalDate.of(2010, 3, 15),
                    LocalDate.of(2010, 3, 15)).get(0).getUuid();
            RestAssured // @formatter:off
                .given().header("current-user", "selfregistered-user-drew@hostsharing.org").port(port).when().get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid).then().log().body().assertThat().statusCode(404); // @formatter:on
                .given().header("current-user", "selfregistered-user-drew@hostsharing.org")
                    .port(port)
                .when()
                    .get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
                .then().log().body().assertThat()
                    .statusCode(404); // @formatter:on
        }
        @Test
        @Accepts({"CoopAssetTransaction:X(Access Control)"})
        @Accepts({ "CoopAssetTransaction:X(Access Control)" })
        void contactAdminUser_canGetRelatedCoopAssetTransaction() {
            context.define("superuser-alex@hostsharing.net");
            final var givenCoopAssetTransactionUuid = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(null, LocalDate.of(2010, 3, 15), LocalDate.of(2010, 3, 15)).get(0).getUuid();
            final var givenCoopAssetTransactionUuid = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
                    null,
                    LocalDate.of(2010, 3, 15),
                    LocalDate.of(2010, 3, 15)).get(0).getUuid();
            RestAssured // @formatter:off
                .given().header("current-user", "contact-admin@firstcontact.example.com").port(port).when().get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid).then().log().body().assertThat().statusCode(200).contentType("application/json").body("", lenientlyEquals("""
                .given()
                    .header("current-user", "contact-admin@firstcontact.example.com")
                    .port(port)
                .when()
                    .get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
                .then().log().body().assertThat()
                    .statusCode(200)
                    .contentType("application/json")
                    .body("", lenientlyEquals("""
                    {
                         "transactionType": "DEPOSIT",
                         "assetValue": 320
src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java
@@ -14,19 +14,15 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java
@@ -2,10 +2,10 @@
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -16,8 +16,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.time.LocalDate;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java
@@ -14,17 +14,14 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java
@@ -19,8 +19,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcherUnitTest.java
@@ -1,16 +1,16 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import net.hostsharing.test.PatchUnitTestBase;
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;
import net.hostsharing.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.UUID;
import java.util.stream.Stream;
src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java
@@ -18,15 +18,16 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
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;
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java
@@ -19,8 +19,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.time.LocalDate;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java
@@ -7,23 +7,18 @@
import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.SynchronizationType;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.SynchronizationType;
import java.util.Map;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java
@@ -11,9 +11,8 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.time.LocalDate;
import java.util.UUID;
import java.util.stream.Stream;
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java
@@ -3,7 +3,7 @@
import com.vladmihalcea.hibernate.type.range.Range;
import org.junit.jupiter.api.Test;
import javax.persistence.PrePersist;
import jakarta.persistence.PrePersist;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.util.Arrays;
@@ -15,6 +15,7 @@
class HsOfficeMembershipEntityUnitTest {
    public static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-01-01");
    final HsOfficeMembershipEntity givenMembership = HsOfficeMembershipEntity.builder()
            .memberNumber(10001)
            .partner(TEST_PARTNER)
@@ -54,9 +55,19 @@
    }
    @Test
    void settingValidFromKeepsValidTo() {
        givenMembership.setValidFrom(LocalDate.parse("2020-01-01"));
        assertThat(givenMembership.getValidFrom()).isEqualTo(LocalDate.parse("2020-01-01"));
        assertThat(givenMembership.getValidTo()).isNull();
    }
    @Test
    void settingValidToKeepsValidFrom() {
        givenMembership.setValidTo(LocalDate.parse("2024-12-31"));
        assertThat(givenMembership.getValidity().lower()).isEqualTo(GIVEN_VALID_FROM);
        assertThat(givenMembership.getValidFrom()).isEqualTo(GIVEN_VALID_FROM);
        assertThat(givenMembership.getValidTo()).isEqualTo(LocalDate.parse("2024-12-31"));
    }
    private static void invokePrePersist(final HsOfficeMembershipEntity membershipEntity)
src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java
@@ -16,16 +16,17 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.*;
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;
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java
@@ -17,8 +17,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntityPatcherUnitTest.java
@@ -1,16 +1,16 @@
package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.test.PatchUnitTestBase;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerDetailsPatchResource;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.time.LocalDate;
import java.util.UUID;
import java.util.stream.Stream;
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcherUnitTest.java
@@ -1,16 +1,16 @@
package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.test.PatchUnitTestBase;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.UUID;
import java.util.stream.Stream;
src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java
@@ -14,15 +14,16 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
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;
src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonControllerAcceptanceTest.java
@@ -16,8 +16,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRepositoryIntegrationTest.java
@@ -13,13 +13,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntityPatcherUnitTest.java
@@ -1,16 +1,16 @@
package net.hostsharing.hsadminng.hs.office.relationship;
import net.hostsharing.test.PatchUnitTestBase;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationshipPatchResource;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.UUID;
import java.util.stream.Stream;
src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java
@@ -17,10 +17,13 @@
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
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;
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java
@@ -19,8 +19,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.time.LocalDate;
import java.util.UUID;
@@ -134,6 +134,7 @@
                                   "debitorUuid": "%s",
                                   "bankAccountUuid": "%s",
                                   "reference": "temp ref CAT A",
                                   "agreement": "2020-01-02",
                                   "validFrom": "2022-10-13"
                                 }
                            """.formatted(givenDebitor.getUuid(), givenBankAccount.getUuid()))
@@ -200,6 +201,7 @@
                                   "debitorUuid": "%s",
                                   "bankAccountUuid": "%s",
                                   "reference": "temp ref CAT C",
                                   "agreement": "2022-10-12",
                                   "validFrom": "2022-10-13",
                                   "validTo": "2024-12-31"
                                 }
@@ -229,6 +231,7 @@
                                   "debitorUuid": "%s",
                                   "bankAccountUuid": "%s",
                                   "reference": "temp refCAT D",
                                   "agreement": "2022-10-12",
                                   "validFrom": "2022-10-13",
                                   "validTo": "2024-12-31"
                                 }
@@ -403,7 +406,7 @@
            // finally, the sepaMandate is actually updated
            assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
                    .matches(mandate -> {
                        assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");
                        assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-03-31)");
                        return true;
                    });
        }
@@ -480,6 +483,7 @@
                    .debitor(givenDebitor)
                    .bankAccount(givenBankAccount)
                    .reference("temp ref CAT Z")
                    .agreement(LocalDate.parse("2022-10-31"))
                    .validity(Range.closedOpen(
                            LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31")))
                    .build();
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityPatcherUnitTest.java
New file
@@ -0,0 +1,98 @@
package net.hostsharing.hsadminng.hs.office.sepamandate;
import com.vladmihalcea.hibernate.type.range.Range;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandatePatchResource;
import net.hostsharing.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import jakarta.persistence.EntityManager;
import java.time.LocalDate;
import java.util.UUID;
import java.util.stream.Stream;
import static net.hostsharing.hsadminng.hs.office.bankaccount.TestHsOfficeBankAccount.TEST_BANK_ACCOUNT;
import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
@TestInstance(PER_CLASS)
@ExtendWith(MockitoExtension.class)
class HsOfficeSepaMandateEntityPatcherUnitTest extends PatchUnitTestBase<
        HsOfficeSepaMandatePatchResource,
        HsOfficeSepaMandateEntity
        > {
    private static final UUID INITIAL_SepaMandate_UUID = UUID.randomUUID();
    private static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-04-15");
    private static final LocalDate PATCHED_VALID_FROM = LocalDate.parse("2022-10-30");
    private static final LocalDate PATCHED_VALID_TO = LocalDate.parse("2022-12-31");
    private static final LocalDate PATCHED_AGREEMENT = LocalDate.parse("2022-11-01");
    private static final String PATCHED_REFERENCE = "ref sepamandate-patched";
    @Mock
    private EntityManager em;
    @BeforeEach
    void initMocks() {
        lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
                HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
        lenient().when(em.getReference(eq(HsOfficeSepaMandateEntity.class), any())).thenAnswer(invocation ->
                HsOfficeSepaMandateEntity.builder().uuid(invocation.getArgument(1)).build());
    }
    @Override
    protected HsOfficeSepaMandateEntity newInitialEntity() {
        final var entity = new HsOfficeSepaMandateEntity();
        entity.setUuid(INITIAL_SepaMandate_UUID);
        entity.setDebitor(TEST_DEBITOR);
        entity.setBankAccount(TEST_BANK_ACCOUNT);
        entity.setReference("ref sepamandate");
        entity.setAgreement(LocalDate.parse("2022-10-28"));
        entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
        return entity;
    }
    @Override
    protected HsOfficeSepaMandatePatchResource newPatchResource() {
        return new HsOfficeSepaMandatePatchResource();
    }
    @Override
    protected HsOfficeSepaMandateEntityPatcher createPatcher(final HsOfficeSepaMandateEntity sepaMandate) {
        return new HsOfficeSepaMandateEntityPatcher(sepaMandate);
    }
    @Override
    protected Stream<Property> propertyTestDescriptors() {
        return Stream.of(
                new JsonNullableProperty<>(
                        "reference",
                        HsOfficeSepaMandatePatchResource::setReference,
                        PATCHED_REFERENCE,
                        HsOfficeSepaMandateEntity::setReference),
                new JsonNullableProperty<>(
                        "agreement",
                        HsOfficeSepaMandatePatchResource::setAgreement,
                        PATCHED_AGREEMENT,
                        HsOfficeSepaMandateEntity::setAgreement),
                new JsonNullableProperty<>(
                        "validfrom",
                        HsOfficeSepaMandatePatchResource::setValidFrom,
                        PATCHED_VALID_FROM,
                        HsOfficeSepaMandateEntity::setValidFrom),
                new JsonNullableProperty<>(
                        "validto",
                        HsOfficeSepaMandatePatchResource::setValidTo,
                        PATCHED_VALID_TO,
                        HsOfficeSepaMandateEntity::setValidTo)
        );
    }
}
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityUnitTest.java
@@ -7,14 +7,17 @@
import java.time.LocalDate;
import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static org.assertj.core.api.Assertions.assertThat;
class HsOfficeSepaMandateEntityUnitTest {
    public static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-01-01");
    public static final LocalDate GIVEN_VALID_TO = LocalDate.parse("2030-12-31");
    final HsOfficeSepaMandateEntity givenSepaMandate = HsOfficeSepaMandateEntity.builder()
            .debitor(TEST_DEBITOR)
            .reference("some-ref")
            .validity(Range.closedOpen(LocalDate.parse("2020-01-01"), LocalDate.parse("2031-01-01")))
            .validity(toPostgresDateRange(GIVEN_VALID_FROM, GIVEN_VALID_TO))
            .bankAccount(HsOfficeBankAccountEntity.builder().iban("some label").build())
            .build();
@@ -31,4 +34,20 @@
        assertThat(result).isEqualTo("some-ref");
    }
    @Test
    void settingValidFromKeepsValidTo() {
        givenSepaMandate.setValidFrom(LocalDate.parse("2023-12-31"));
        assertThat(givenSepaMandate.getValidFrom()).isEqualTo(LocalDate.parse("2023-12-31"));
        assertThat(givenSepaMandate.getValidTo()).isEqualTo(GIVEN_VALID_TO);
    }
    @Test
    void settingValidToKeepsValidFrom() {
        givenSepaMandate.setValidTo(LocalDate.parse("2024-12-31"));
        assertThat(givenSepaMandate.getValidFrom()).isEqualTo(GIVEN_VALID_FROM);
        assertThat(givenSepaMandate.getValidTo()).isEqualTo(LocalDate.parse("2024-12-31"));
    }
}
src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java
@@ -20,9 +20,9 @@
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
@@ -78,6 +78,7 @@
                        .debitor(givenDebitor)
                        .bankAccount(givenBankAccount)
                        .reference("temp ref A")
                        .agreement(LocalDate.parse( "2020-01-02"))
                        .validity(Range.closedOpen(
                                LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
                        .build();
@@ -110,6 +111,7 @@
                        .debitor(givenDebitor)
                        .bankAccount(givenBankAccount)
                        .reference("temp ref B")
                        .agreement(LocalDate.parse("2020-01-02"))
                        .validity(Range.closedOpen(
                                LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
                        .build();
@@ -178,9 +180,9 @@
            // then
            allTheseSepaMandatesAreReturned(
                    result,
                    "SEPA-Mandate(DE02120300000000202051, refFirstGmbH, [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02100500000054540402, refSeconde.K., [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02300209000106531065, refThirdOHG, [2022-10-01,2027-01-01))");
                    "SEPA-Mandate(DE02120300000000202051, refFirstGmbH, 2022-09-30, [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02100500000054540402, refSeconde.K., 2022-09-30, [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02300209000106531065, refThirdOHG, 2022-09-30, [2022-10-01,2027-01-01))");
        }
        @Test
@@ -194,7 +196,7 @@
            // then:
            exactlyTheseSepaMandatesAreReturned(
                    result,
                    "SEPA-Mandate(DE02120300000000202051, refFirstGmbH, [2022-10-01,2027-01-01))");
                    "SEPA-Mandate(DE02120300000000202051, refFirstGmbH, 2022-09-30, [2022-10-01,2027-01-01))");
        }
    }
@@ -212,9 +214,9 @@
            // then
            exactlyTheseSepaMandatesAreReturned(
                    result,
                    "SEPA-Mandate(DE02120300000000202051, refFirstGmbH, [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02100500000054540402, refSeconde.K., [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02300209000106531065, refThirdOHG, [2022-10-01,2027-01-01))");
                    "SEPA-Mandate(DE02120300000000202051, refFirstGmbH, 2022-09-30, [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02100500000054540402, refSeconde.K., 2022-09-30, [2022-10-01,2027-01-01))",
                    "SEPA-Mandate(DE02300209000106531065, refThirdOHG, 2022-09-30, [2022-10-01,2027-01-01))");
        }
        @Test
@@ -228,7 +230,7 @@
            // then
            exactlyTheseSepaMandatesAreReturned(
                    result,
                    "SEPA-Mandate(DE02300209000106531065, refThirdOHG, [2022-10-01,2027-01-01))");
                    "SEPA-Mandate(DE02300209000106531065, refThirdOHG, 2022-09-30, [2022-10-01,2027-01-01))");
        }
    }
@@ -420,6 +422,7 @@
                    .debitor(givenDebitor)
                    .bankAccount(givenBankAccount)
                    .reference("temp ref X")
                    .agreement(LocalDate.parse( "2020-01-02"))
                    .validity(Range.closedOpen(
                            LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
                    .build();
src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RawRbacGrantEntity.java
@@ -4,7 +4,10 @@
import org.jetbrains.annotations.NotNull;
import org.springframework.data.annotation.Immutable;
import javax.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantControllerAcceptanceTest.java
@@ -3,13 +3,13 @@
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.Nested;
@@ -20,8 +20,8 @@
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantRepositoryIntegrationTest.java
@@ -1,27 +1,25 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RawRbacRoleEntity.java
@@ -5,7 +5,7 @@
import org.jetbrains.annotations.NotNull;
import org.springframework.data.annotation.Immutable;
import javax.persistence.*;
import jakarta.persistence.*;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerAcceptanceTest.java
@@ -1,17 +1,17 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import io.restassured.RestAssured;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
import net.hostsharing.test.Accepts;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import static org.hamcrest.Matchers.*;
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerRestTest.java
@@ -15,10 +15,9 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.SynchronizationType;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.SynchronizationType;
import java.util.Map;
import static java.util.Arrays.asList;
src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleRepositoryIntegrationTest.java
@@ -8,13 +8,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import static net.hostsharing.test.JpaAttempt.attempt;
src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java
@@ -2,9 +2,9 @@
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.test.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.test.Accepts;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -13,8 +13,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java
@@ -15,9 +15,9 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.SynchronizationType;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.SynchronizationType;
import java.util.Map;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepositoryIntegrationTest.java
@@ -9,16 +9,14 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java
@@ -14,8 +14,8 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepositoryIntegrationTest.java
@@ -10,10 +10,10 @@
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.PersistenceException;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;
src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageRepositoryIntegrationTest.java
@@ -1,21 +1,18 @@
package net.hostsharing.hsadminng.test.pac;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.test.cust.TestCustomerRepository;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
src/test/java/net/hostsharing/test/JpaAttempt.java
@@ -7,7 +7,7 @@
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import java.util.Optional;
import java.util.function.Supplier;
src/test/java/net/hostsharing/test/MapperUnitTest.java
@@ -9,9 +9,9 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.persistence.EntityManager;
import javax.persistence.ManyToOne;
import javax.validation.ValidationException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.ManyToOne;
import jakarta.validation.ValidationException;
import java.util.List;
import java.util.UUID;
src/test/java/net/hostsharing/test/StringTemplater.java
@@ -2,11 +2,11 @@
import lombok.experimental.UtilityClass;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import java.util.Map;
import static liquibase.repackaged.org.apache.commons.text.StringSubstitutor.replace;
import static org.apache.commons.lang3.StringUtils.stripEnd;
import static org.apache.commons.text.StringSubstitutor.replace;
@UtilityClass
public class StringTemplater {
src/test/resources/migration/asset-transactions.csv
New file
@@ -0,0 +1,5 @@
member_asstr_id;    bp_id;    date;        action;        amount
33443;        7;    2000-12-06;    PAYMENT;    1280
33451;        10;    2000-12-06;    PAYMENT;    128
33701;        7;    2005-01-10;    PAYMENT;    2560
33810;        10;    2016-12-31;    PAYBACK;    128
src/test/resources/migration/business_partners.csv
New 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
7;    10007;        mih;        2000-12-06;    ;        Aufsichtsrat;    2006-10-15;    2001-10-15;        false;    false;        NET;        DE-VAT-007
10;    10010;        xyz;        2000-12-06;    2015-12-31;    ;        ;        ;            false;    false;        GROSS;
12;    11012;        xxx;        2021-04-01;    ;        ;        ;        ;            true;    true;        GROSS;
src/test/resources/migration/contacts.csv
New file
@@ -0,0 +1,5 @@
contact_id;    bp_id;    salut;    first_name;    last_name;    title;    firma;    co;    street;            zipcode;city;    country;    phone_private;        phone_office;        phone_mobile;    fax;        email
71;        7;    Herr;    Michael;    Mellies;        ;    ;    ;    Kleine Freiheit 50;    26524;    Hage;    DE;        ;            +49 4931 123456;    +49 1522 123456;;        mih@example.org
101;        10;    Frau;    Jenny;        Meyer;        Dr.;    JM e.K.;;    Waldweg 5;        11001;    Berlin; DE;        +49 30 7777777;        +49 30 8888888;        ;        +49 30 9999999; jm@example.org
102;        10;    Herr;    Andrew;        Meyer;        ;    JM e.K.;;    Waldweg 5;        11001;    Berlin; DE;        +49 30 6666666;        +49 30 5555555;        ;        +49 30 9999999; am@example.org
121;        12;    ;    Paule;        Schmidt;    ;    Test PS;;    ;            ;    ;    ;        ;            ;            ;        ;        ps@example.com
src/test/resources/migration/sepa-mandates.csv
New file
@@ -0,0 +1,3 @@
sepa_mandat_id;    bp_id;    bank_customer;    bank_name;    bank_iban;        bank_bic;    mandat_ref;    mandat_signed;    mandat_since;    mandat_until;    mandat_used
234234;        7;    Michael Mellies;    ING Bank AG;    DE37500105177419788228;    INGDDEFFXXX;    MH12345;    2004-06-12;    2004-06-15;    ;        2022-10-20
235662;        10;    JM e.K.;    ING Bank AG;    DE49500105174516484892;    INGDDEFFXXX;    JM33344;    2005-06-282;    2005-07-01;    ;        2016-01-18
src/test/resources/migration/share-transactions.csv
New file
@@ -0,0 +1,5 @@
member_share_id;bp_id;    date;        action;        quantity;    comment
33443;        7;    2000-12-06;    SUBSCRIPTION;    20;        initial share subscription
33451;        10;    2000-12-06;    SUBSCRIPTION;    2;        initial share subscription
33701;        7;    2005-01-10;    SUBSCRIPTION;    40;        increase
33810;        10;    2016-12-31;    UNSUBSCRIPTION;    22;        membership ended