initial data import for hs-office tables (db-migration #10)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Co-authored-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net> Reviewed-on: #10 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
parent
e427bb1784
commit
fd1bd897b1
29
.aliases
29
.aliases
@ -1,3 +1,10 @@
|
|||||||
|
# For using the alias import-office-tables, # copy these exports to .environment (ignored by git)
|
||||||
|
# and amend them according to your external DB:
|
||||||
|
export HSADMINNG_POSTGRES_JDBC_URL=jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
|
||||||
|
export HSADMINNG_POSTGRES_ADMIN_USERNAME=admin
|
||||||
|
export HSADMINNG_POSTGRES_ADMIN_PASSWORD=
|
||||||
|
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
||||||
|
|
||||||
gradleWrapper () {
|
gradleWrapper () {
|
||||||
if [ ! -f gradlew ]; then
|
if [ ! -f gradlew ]; then
|
||||||
echo "No 'gradlew' found. Maybe you are not in the root dir of a gradle project?"
|
echo "No 'gradlew' found. Maybe you are not in the root dir of a gradle project?"
|
||||||
@ -36,9 +43,26 @@ postgresAutodoc () {
|
|||||||
dot -Tsvg build/postgres-autodoc.neato >build/postgres-autodoc-rbac.svg && \
|
dot -Tsvg build/postgres-autodoc.neato >build/postgres-autodoc-rbac.svg && \
|
||||||
echo "generated $PWD/build/postgres-autodoc-rbac.svg"
|
echo "generated $PWD/build/postgres-autodoc-rbac.svg"
|
||||||
}
|
}
|
||||||
|
|
||||||
alias postgres-autodoc=postgresAutodoc
|
alias postgres-autodoc=postgresAutodoc
|
||||||
|
|
||||||
|
function importOfficeData() {
|
||||||
|
export HSADMINNG_POSTGRES_JDBC=jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
|
||||||
|
export HSADMINNG_POSTGRES_ADMIN_USERNAME=admin
|
||||||
|
export HSADMINNG_POSTGRES_ADMIN_PASSWORD=password
|
||||||
|
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
||||||
|
export HSADMINNG_SUPERUSER=superuser-alex@hostsharing.net
|
||||||
|
|
||||||
|
if [ -f .environment ]; then
|
||||||
|
source .environment
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "using environment (with ending ';' for use in IntelliJ IDEA):"
|
||||||
|
set | grep ^HSADMINNG_ | sed 's/$/;/'
|
||||||
|
|
||||||
|
./gradlew importOfficeData --rerun
|
||||||
|
}
|
||||||
|
alias gw-importOfficeData=importOfficeData
|
||||||
|
|
||||||
alias podman-start='systemctl --user enable --now podman.socket && systemctl --user status podman.socket && ls -la /run/user/$UID/podman/podman.sock'
|
alias podman-start='systemctl --user enable --now podman.socket && systemctl --user status podman.socket && ls -la /run/user/$UID/podman/podman.sock'
|
||||||
alias podman-stop='systemctl --user disable --now podman.socket && systemctl --user status podman.socket && ls -la /run/user/$UID/podman/podman.sock'
|
alias podman-stop='systemctl --user disable --now podman.socket && systemctl --user status podman.socket && ls -la /run/user/$UID/podman/podman.sock'
|
||||||
alias podman-use='export DOCKER_HOST="unix:///run/user/$UID/podman/podman.sock"; export TESTCONTAINERS_RYUK_DISABLED=true'
|
alias podman-use='export DOCKER_HOST="unix:///run/user/$UID/podman/podman.sock"; export TESTCONTAINERS_RYUK_DISABLED=true'
|
||||||
@ -53,3 +77,6 @@ alias pg-sql-backup='docker exec -i hsadmin-ng-postgres /usr/bin/pg_dump --clean
|
|||||||
alias pg-sql-restore='gunzip --stdout | docker exec -i hsadmin-ng-postgres psql -U postgres -d postgres'
|
alias pg-sql-restore='gunzip --stdout | docker exec -i hsadmin-ng-postgres psql -U postgres -d postgres'
|
||||||
|
|
||||||
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
|
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
|
||||||
|
|
||||||
|
alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResources'
|
||||||
|
alias gw-test='. .aliases; ./gradlew test'
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -137,3 +137,4 @@ Desktop.ini
|
|||||||
# ESLint
|
# ESLint
|
||||||
######################
|
######################
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
/.environment*
|
||||||
|
22
build.gradle
22
build.gradle
@ -100,6 +100,7 @@ dependencies {
|
|||||||
testImplementation 'io.rest-assured:spring-mock-mvc'
|
testImplementation 'io.rest-assured:spring-mock-mvc'
|
||||||
testImplementation 'org.hamcrest:hamcrest-core:2.2'
|
testImplementation 'org.hamcrest:hamcrest-core:2.2'
|
||||||
testImplementation 'org.pitest:pitest-junit5-plugin:1.2.1'
|
testImplementation 'org.pitest:pitest-junit5-plugin:1.2.1'
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter-api'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyManagement {
|
dependencyManagement {
|
||||||
@ -129,7 +130,7 @@ openapiProcessor {
|
|||||||
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
||||||
apiPath "$projectDir/src/main/resources/api-definition.yaml"
|
apiPath "$projectDir/src/main/resources/api-definition.yaml"
|
||||||
mapping "$projectDir/src/main/resources/api-mappings.yaml"
|
mapping "$projectDir/src/main/resources/api-mappings.yaml"
|
||||||
targetDir "$projectDir/build/generated/sources/openapi-javax"
|
targetDir "$buildDir/generated/sources/openapi-javax"
|
||||||
showWarnings true
|
showWarnings true
|
||||||
openApiNullable true
|
openApiNullable true
|
||||||
}
|
}
|
||||||
@ -138,7 +139,7 @@ openapiProcessor {
|
|||||||
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
||||||
apiPath "$projectDir/src/main/resources/api-definition/rbac/rbac.yaml"
|
apiPath "$projectDir/src/main/resources/api-definition/rbac/rbac.yaml"
|
||||||
mapping "$projectDir/src/main/resources/api-definition/rbac/api-mappings.yaml"
|
mapping "$projectDir/src/main/resources/api-definition/rbac/api-mappings.yaml"
|
||||||
targetDir "$projectDir/build/generated/sources/openapi-javax"
|
targetDir "$buildDir/generated/sources/openapi-javax"
|
||||||
showWarnings true
|
showWarnings true
|
||||||
openApiNullable true
|
openApiNullable true
|
||||||
}
|
}
|
||||||
@ -147,7 +148,7 @@ openapiProcessor {
|
|||||||
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
||||||
apiPath "$projectDir/src/main/resources/api-definition/test/test.yaml"
|
apiPath "$projectDir/src/main/resources/api-definition/test/test.yaml"
|
||||||
mapping "$projectDir/src/main/resources/api-definition/test/api-mappings.yaml"
|
mapping "$projectDir/src/main/resources/api-definition/test/api-mappings.yaml"
|
||||||
targetDir "$projectDir/build/generated/sources/openapi-javax"
|
targetDir "$buildDir/generated/sources/openapi-javax"
|
||||||
showWarnings true
|
showWarnings true
|
||||||
openApiNullable true
|
openApiNullable true
|
||||||
}
|
}
|
||||||
@ -156,7 +157,7 @@ openapiProcessor {
|
|||||||
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
||||||
apiPath "$projectDir/src/main/resources/api-definition/hs-office/hs-office.yaml"
|
apiPath "$projectDir/src/main/resources/api-definition/hs-office/hs-office.yaml"
|
||||||
mapping "$projectDir/src/main/resources/api-definition/hs-office/api-mappings.yaml"
|
mapping "$projectDir/src/main/resources/api-definition/hs-office/api-mappings.yaml"
|
||||||
targetDir "$projectDir/build/generated/sources/openapi-javax"
|
targetDir "$buildDir/generated/sources/openapi-javax"
|
||||||
showWarnings true
|
showWarnings true
|
||||||
openApiNullable true
|
openApiNullable true
|
||||||
}
|
}
|
||||||
@ -237,6 +238,9 @@ test {
|
|||||||
excludes = [
|
excludes = [
|
||||||
'net.hostsharing.hsadminng.**.generated.**',
|
'net.hostsharing.hsadminng.**.generated.**',
|
||||||
]
|
]
|
||||||
|
useJUnitPlatform {
|
||||||
|
excludeTags 'import'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
jacocoTestReport {
|
jacocoTestReport {
|
||||||
dependsOn test
|
dependsOn test
|
||||||
@ -297,6 +301,16 @@ jacocoTestCoverageVerification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register('importOfficeData', Test) {
|
||||||
|
useJUnitPlatform {
|
||||||
|
includeTags 'import'
|
||||||
|
}
|
||||||
|
|
||||||
|
group 'verification'
|
||||||
|
description 'run the import jobs as tests'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// pitest mutation testing
|
// pitest mutation testing
|
||||||
pitest {
|
pitest {
|
||||||
targetClasses = ['net.hostsharing.hsadminng.**']
|
targetClasses = ['net.hostsharing.hsadminng.**']
|
||||||
|
186
doc/hs-office-data-structure.md
Normal file
186
doc/hs-office-data-structure.md
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
# Beispiel: juristische Person (GmbH)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
direction TD
|
||||||
|
|
||||||
|
namespace Hostsharing {
|
||||||
|
class person-HostsharingEG
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Partner {
|
||||||
|
class partner-MeierGmbH
|
||||||
|
class role-MeierGmbH
|
||||||
|
class personDetails-MeierGmbH
|
||||||
|
class contactData-MeierGmbH
|
||||||
|
class person-MeierGmbH
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Representatives {
|
||||||
|
class person-FrankMeier
|
||||||
|
class contactData-FrankMeier
|
||||||
|
class role-MeierGmbH-FrankMeier
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Debitors {
|
||||||
|
class debitor-MeierGmbH
|
||||||
|
class contactData-MeierGmbH-Buha
|
||||||
|
class role-MeierGmbH-Buha
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Operations {
|
||||||
|
class person-SabineMeier
|
||||||
|
class contactData-SabineMeier
|
||||||
|
class role-MeierGmbH-SabineMeier
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Enums {
|
||||||
|
|
||||||
|
class RoleType {
|
||||||
|
<<enumeration>>
|
||||||
|
UNKNOWN
|
||||||
|
REPRESENTATIVE
|
||||||
|
ACCOUNTING
|
||||||
|
OPERATIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersonType {
|
||||||
|
<<enumeration>>
|
||||||
|
UNKNOWN: nur für Import
|
||||||
|
NATURAL_PERSON: natürliche Person
|
||||||
|
LEGAL_PERSON: z.B. GmbH, e.K., eG, e.V.
|
||||||
|
INCORORATED_FIRM: z.B. OHG, Partnerschaftsgesellschaft
|
||||||
|
UNINCORPORATED_FIRM: z.B. GbR, ARGE, Erbengemeinschaft
|
||||||
|
PUBLIC_INSTITUTION: KdöR, AöR [ohne Registergericht/Registernummer]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class person-HostsharingEG {
|
||||||
|
+personType: LEGAL
|
||||||
|
+tradeName: Hostsahring eG
|
||||||
|
+familyName
|
||||||
|
+givenName
|
||||||
|
}
|
||||||
|
|
||||||
|
class partner-MeierGmbH {
|
||||||
|
+Numeric partnerNumber: 12345
|
||||||
|
+Role partnerRole
|
||||||
|
}
|
||||||
|
partner-MeierGmbH *-- role-MeierGmbH
|
||||||
|
|
||||||
|
class person-MeierGmbH {
|
||||||
|
+personType: LEGAL
|
||||||
|
+tradeName: Meier GmbH
|
||||||
|
+familyName
|
||||||
|
+givenName
|
||||||
|
}
|
||||||
|
person-MeierGmbH *-- personDetails-MeierGmbH
|
||||||
|
|
||||||
|
class personDetails-MeierGmbH {
|
||||||
|
+registrationOffice: AG Hamburg
|
||||||
|
+registrationNumber: ABC123434
|
||||||
|
+birthName
|
||||||
|
+birthPlace
|
||||||
|
+dateOfDeath
|
||||||
|
}
|
||||||
|
|
||||||
|
class contactData-MeierGmbH {
|
||||||
|
+postalAddress: Hauptstraße 5, 22345 Hamburg
|
||||||
|
+phoneNumbers: +49 40 12345-00
|
||||||
|
+emailAddresses: office@meier-gmbh.de
|
||||||
|
}
|
||||||
|
|
||||||
|
class role-MeierGmbH {
|
||||||
|
+RoleType RoleType PARTNER
|
||||||
|
+Person anchor
|
||||||
|
+Person holder
|
||||||
|
+Contact roleContact
|
||||||
|
}
|
||||||
|
role-MeierGmbH o-- person-HostsharingEG : anchor
|
||||||
|
role-MeierGmbH o-- person-MeierGmbH : holder
|
||||||
|
role-MeierGmbH o-- contactData-MeierGmbH
|
||||||
|
|
||||||
|
%% --- Debitors ---
|
||||||
|
|
||||||
|
class debitor-MeierGmbH {
|
||||||
|
+Partner partner
|
||||||
|
+Numeric[2] debitorNumberSuffix: 00
|
||||||
|
+Role billingRole
|
||||||
|
+boolean billable: true
|
||||||
|
+String vatId: ID123456789
|
||||||
|
+String vatCountryCode: DE
|
||||||
|
+boolean vatBusiness: true
|
||||||
|
+boolean vatReverseCharge: false
|
||||||
|
+BankAccount refundBankAccount
|
||||||
|
+String defaultPrefix: mei
|
||||||
|
}
|
||||||
|
debitor-MeierGmbH o-- partner-MeierGmbH
|
||||||
|
debitor-MeierGmbH *-- role-MeierGmbH-Buha
|
||||||
|
|
||||||
|
class contactData-MeierGmbH-Buha {
|
||||||
|
+postalAddress: Hauptstraße 5, 22345 Hamburg
|
||||||
|
+phoneNumbers: +49 40 12345-05
|
||||||
|
+emailAddresses: buha@meier-gmbh.de
|
||||||
|
}
|
||||||
|
|
||||||
|
class role-MeierGmbH-Buha {
|
||||||
|
+RoleType RoleType ACCOUNTING
|
||||||
|
+Person anchor
|
||||||
|
+Person holder
|
||||||
|
+Contact roleContact
|
||||||
|
}
|
||||||
|
role-MeierGmbH-Buha o-- person-MeierGmbH : anchor
|
||||||
|
role-MeierGmbH-Buha o-- person-MeierGmbH : holder
|
||||||
|
role-MeierGmbH-Buha o-- contactData-MeierGmbH-Buha
|
||||||
|
|
||||||
|
%% --- Representatives ---
|
||||||
|
|
||||||
|
class person-FrankMeier {
|
||||||
|
+ personType: NATURAL
|
||||||
|
+ tradeName
|
||||||
|
+ familyName: Meier
|
||||||
|
+ givenName: Frank
|
||||||
|
}
|
||||||
|
|
||||||
|
class contactData-FrankMeier {
|
||||||
|
+postalAddress
|
||||||
|
+phoneNumbers: +49 40 12345-22
|
||||||
|
+emailAddresses: frank.meier@meier-gmbh.de
|
||||||
|
}
|
||||||
|
|
||||||
|
class role-MeierGmbH-FrankMeier {
|
||||||
|
+RoleType RoleType REPRESENTATIVE
|
||||||
|
+Person anchor
|
||||||
|
+Person holder
|
||||||
|
+Contact roleContact
|
||||||
|
}
|
||||||
|
role-MeierGmbH-FrankMeier o-- person-MeierGmbH : anchor
|
||||||
|
role-MeierGmbH-FrankMeier o-- person-FrankMeier : holder
|
||||||
|
role-MeierGmbH-FrankMeier o-- contactData-FrankMeier
|
||||||
|
|
||||||
|
%% --- Operations ---
|
||||||
|
|
||||||
|
class person-SabineMeier {
|
||||||
|
+personType: NATURAL
|
||||||
|
+tradeName
|
||||||
|
+familyName: Meier
|
||||||
|
+givenName: Sabine
|
||||||
|
}
|
||||||
|
|
||||||
|
class contactData-SabineMeier {
|
||||||
|
+postalAddress
|
||||||
|
+phoneNumbers: +49 40 12345-22
|
||||||
|
+emailAddresses: sabine.meier@meier-gmbh.de
|
||||||
|
}
|
||||||
|
|
||||||
|
class role-MeierGmbH-SabineMeier {
|
||||||
|
+RoleType RoleType OPERATIONAL
|
||||||
|
+Person anchor
|
||||||
|
+Person holder
|
||||||
|
+Contact roleContact
|
||||||
|
}
|
||||||
|
role-MeierGmbH-SabineMeier o-- person-MeierGmbH : anchor
|
||||||
|
role-MeierGmbH-SabineMeier o-- person-SabineMeier : holder
|
||||||
|
role-MeierGmbH-SabineMeier o-- contactData-SabineMeier
|
||||||
|
|
||||||
|
```
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayName("BankAccount")
|
@DisplayName("BankAccount")
|
||||||
public class HsOfficeBankAccountEntity implements Stringifyable {
|
public class HsOfficeBankAccountEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
|
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
|
||||||
.withProp(Fields.holder, HsOfficeBankAccountEntity::getHolder)
|
.withProp(Fields.holder, HsOfficeBankAccountEntity::getHolder)
|
||||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
@ -21,7 +22,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayName("Contact")
|
@DisplayName("Contact")
|
||||||
public class HsOfficeContactEntity implements Stringifyable {
|
public class HsOfficeContactEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficeContactEntity> toString = stringify(HsOfficeContactEntity.class, "contact")
|
private static Stringify<HsOfficeContactEntity> toString = stringify(HsOfficeContactEntity.class, "contact")
|
||||||
.withProp(Fields.label, HsOfficeContactEntity::getLabel)
|
.withProp(Fields.label, HsOfficeContactEntity::getLabel)
|
||||||
@ -38,10 +39,10 @@ public class HsOfficeContactEntity implements Stringifyable {
|
|||||||
private String postalAddress;
|
private String postalAddress;
|
||||||
|
|
||||||
@Column(name = "emailaddresses", columnDefinition = "json")
|
@Column(name = "emailaddresses", columnDefinition = "json")
|
||||||
private String emailAddresses;
|
private String emailAddresses; // TODO: check if we can really add multiple. format: ["eins@...", "zwei@..."]
|
||||||
|
|
||||||
@Column(name = "phonenumbers", columnDefinition = "json")
|
@Column(name = "phonenumbers", columnDefinition = "json")
|
||||||
private String phoneNumbers;
|
private String phoneNumbers; // TODO: check if we can really add multiple. format: { "office": "+49 40 12345-10", "fax": "+49 40 12345-05" }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
@ -13,6 +15,7 @@ import java.text.DecimalFormat;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -23,14 +26,15 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("CoopAssetsTransaction")
|
@DisplayName("CoopAssetsTransaction")
|
||||||
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable {
|
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
||||||
.withProp(e -> e.getMembership().getMemberNumber())
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getMemberNumber)
|
||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getValueDate)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getValueDate)
|
||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getTransactionType)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getTransactionType)
|
||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getAssetValue)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getAssetValue)
|
||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getReference)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getReference)
|
||||||
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getComment)
|
||||||
.withSeparator(", ")
|
.withSeparator(", ")
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@ -54,11 +58,16 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable {
|
|||||||
private BigDecimal assetValue;
|
private BigDecimal assetValue;
|
||||||
|
|
||||||
@Column(name = "reference")
|
@Column(name = "reference")
|
||||||
private String reference;
|
private String reference; // TODO: what is this for?
|
||||||
|
|
||||||
@Column(name = "comment")
|
@Column(name = "comment")
|
||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
|
|
||||||
|
public Integer getMemberNumber() {
|
||||||
|
return ofNullable(membership).map(HsOfficeMembershipEntity::getMemberNumber).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
@ -66,6 +75,6 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return membership.getMemberNumber() + new DecimalFormat("+0.00").format(assetValue);
|
return "%s%+1.2f".formatted(getMemberNumber(), assetValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||||
|
|
||||||
public enum HsOfficeCoopAssetsTransactionType {
|
public enum HsOfficeCoopAssetsTransactionType {
|
||||||
ADJUSTMENT, DEPOSIT, DISBURSAL, TRANSFER, ADOPTION, CLEARING, LOSS
|
ADJUSTMENT, // correction of wrong bookings
|
||||||
|
DEPOSIT, // payment received from member after signing shares, >0
|
||||||
|
DISBURSAL, // payment send to member after cancellation of shares, <0
|
||||||
|
TRANSFER, // transferring shares to another member, <0
|
||||||
|
ADOPTION, // receiving shares from another member, >0
|
||||||
|
CLEARING, // settlement with members dept, <0
|
||||||
|
LOSS, // assignment of balance sheet loss in case of cancellation of shares, <0
|
||||||
|
LIMITATION // limitation period was reached after impossible disbursal, <0
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ import jakarta.persistence.*;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -20,14 +22,15 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("CoopShareTransaction")
|
@DisplayName("CoopShareTransaction")
|
||||||
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable {
|
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
||||||
.withProp(e -> e.getMembership().getMemberNumber())
|
.withProp(HsOfficeCoopSharesTransactionEntity::getMemberNumber)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getValueDate)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getValueDate)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getTransactionType)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getTransactionType)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getShareCount)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getShareCount)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getReference)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getReference)
|
||||||
|
.withProp(HsOfficeCoopSharesTransactionEntity::getComment)
|
||||||
.withSeparator(", ")
|
.withSeparator(", ")
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable {
|
|||||||
private int shareCount;
|
private int shareCount;
|
||||||
|
|
||||||
@Column(name = "reference")
|
@Column(name = "reference")
|
||||||
private String reference;
|
private String reference; // TODO: what is this for?
|
||||||
|
|
||||||
@Column(name = "comment")
|
@Column(name = "comment")
|
||||||
private String comment;
|
private String comment;
|
||||||
@ -60,8 +63,12 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable {
|
|||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getMemberNumber() {
|
||||||
|
return ofNullable(membership).map(HsOfficeMembershipEntity::getMemberNumber).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return "%s%+d".formatted(membership.getMemberNumber(), shareCount);
|
return "%s%+d".formatted(getMemberNumber(), shareCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||||
|
|
||||||
public enum HsOfficeCoopSharesTransactionType {
|
public enum HsOfficeCoopSharesTransactionType {
|
||||||
ADJUSTMENT, SUBSCRIPTION, CANCELLATION;
|
ADJUSTMENT, // correction of wrong bookings
|
||||||
|
SUBSCRIPTION, // shares signed, e.g. with the declaration of accession, >0
|
||||||
|
CANCELLATION; // shares terminated, e.g. when a membership is resigned, <0
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@ import lombok.*;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
@ -22,12 +24,16 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("Debitor")
|
@DisplayName("Debitor")
|
||||||
public class HsOfficeDebitorEntity implements Stringifyable {
|
public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
|
// TODO: I would rather like to generate something matching this example:
|
||||||
|
// debitor(1234500: Test AG, tes)
|
||||||
|
// maybe remove withSepararator (always use ', ') and add withBusinessIdProp (with ': ' afterwards)?
|
||||||
private static Stringify<HsOfficeDebitorEntity> stringify =
|
private static Stringify<HsOfficeDebitorEntity> stringify =
|
||||||
stringify(HsOfficeDebitorEntity.class, "debitor")
|
stringify(HsOfficeDebitorEntity.class, "debitor")
|
||||||
.withProp(HsOfficeDebitorEntity::getDebitorNumber)
|
.withProp(HsOfficeDebitorEntity::getDebitorNumber)
|
||||||
.withProp(HsOfficeDebitorEntity::getPartner)
|
.withProp(HsOfficeDebitorEntity::getPartner)
|
||||||
|
.withProp(HsOfficeDebitorEntity::getDefaultPrefix)
|
||||||
.withSeparator(": ")
|
.withSeparator(": ")
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@ -40,12 +46,15 @@ public class HsOfficeDebitorEntity implements Stringifyable {
|
|||||||
@JoinColumn(name = "partneruuid")
|
@JoinColumn(name = "partneruuid")
|
||||||
private HsOfficePartnerEntity partner;
|
private HsOfficePartnerEntity partner;
|
||||||
|
|
||||||
@Column(name = "debitornumber")
|
@Column(name = "debitornumbersuffix", columnDefinition = "numeric(2)")
|
||||||
private Integer debitorNumber;
|
private Byte debitorNumberSuffix; // TODO maybe rather as a formatted String?
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "billingcontactuuid")
|
@JoinColumn(name = "billingcontactuuid")
|
||||||
private HsOfficeContactEntity billingContact;
|
private HsOfficeContactEntity billingContact; // TODO: migrate to billingPerson
|
||||||
|
|
||||||
|
@Column(name = "billable", nullable = false)
|
||||||
|
private Boolean billable; // not a primitive because otherwise the default would be false
|
||||||
|
|
||||||
@Column(name = "vatid")
|
@Column(name = "vatid")
|
||||||
private String vatId;
|
private String vatId;
|
||||||
@ -56,10 +65,34 @@ public class HsOfficeDebitorEntity implements Stringifyable {
|
|||||||
@Column(name = "vatbusiness")
|
@Column(name = "vatbusiness")
|
||||||
private boolean vatBusiness;
|
private boolean vatBusiness;
|
||||||
|
|
||||||
|
@Column(name = "vatreversecharge")
|
||||||
|
private boolean vatReverseCharge;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "refundbankaccountuuid")
|
@JoinColumn(name = "refundbankaccountuuid")
|
||||||
private HsOfficeBankAccountEntity refundBankAccount;
|
private HsOfficeBankAccountEntity refundBankAccount;
|
||||||
|
|
||||||
|
@Column(name = "defaultprefix", columnDefinition = "char(3) not null")
|
||||||
|
private String defaultPrefix;
|
||||||
|
|
||||||
|
public String getDebitorNumberString() {
|
||||||
|
// TODO: refactor
|
||||||
|
if (partner.getDebitorNumberPrefix() == null ) {
|
||||||
|
if (debitorNumberSuffix == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return String.format("%02d", debitorNumberSuffix);
|
||||||
|
}
|
||||||
|
if (debitorNumberSuffix == null) {
|
||||||
|
return partner.getDebitorNumberPrefix() + "??";
|
||||||
|
}
|
||||||
|
return partner.getDebitorNumberPrefix() + String.format("%02d", debitorNumberSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDebitorNumber() {
|
||||||
|
return Optional.ofNullable(getDebitorNumberString()).map(Integer::parseInt).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
@ -67,6 +100,6 @@ public class HsOfficeDebitorEntity implements Stringifyable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return debitorNumber.toString();
|
return getDebitorNumberString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.debitor;
|
package net.hostsharing.hsadminng.hs.office.debitor;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
class HsOfficeDebitorEntityPatcher implements EntityPatcher<HsOfficeDebitorPatchResource> {
|
class HsOfficeDebitorEntityPatcher implements EntityPatcher<HsOfficeDebitorPatchResource> {
|
||||||
|
|
||||||
@ -25,11 +27,18 @@ class HsOfficeDebitorEntityPatcher implements EntityPatcher<HsOfficeDebitorPatch
|
|||||||
verifyNotNull(newValue, "billingContact");
|
verifyNotNull(newValue, "billingContact");
|
||||||
entity.setBillingContact(em.getReference(HsOfficeContactEntity.class, newValue));
|
entity.setBillingContact(em.getReference(HsOfficeContactEntity.class, newValue));
|
||||||
});
|
});
|
||||||
|
Optional.ofNullable(resource.getBillable()).ifPresent(entity::setBillable);
|
||||||
OptionalFromJson.of(resource.getVatId()).ifPresent(entity::setVatId);
|
OptionalFromJson.of(resource.getVatId()).ifPresent(entity::setVatId);
|
||||||
OptionalFromJson.of(resource.getVatCountryCode()).ifPresent(entity::setVatCountryCode);
|
OptionalFromJson.of(resource.getVatCountryCode()).ifPresent(entity::setVatCountryCode);
|
||||||
OptionalFromJson.of(resource.getVatBusiness()).ifPresent(newValue -> {
|
Optional.ofNullable(resource.getVatBusiness()).ifPresent(entity::setVatBusiness);
|
||||||
verifyNotNull(newValue, "vatBusiness");
|
Optional.ofNullable(resource.getVatReverseCharge()).ifPresent(entity::setVatReverseCharge);
|
||||||
entity.setVatBusiness(newValue);
|
OptionalFromJson.of(resource.getDefaultPrefix()).ifPresent(newValue -> {
|
||||||
|
verifyNotNull(newValue, "defaultPrefix");
|
||||||
|
entity.setDefaultPrefix(newValue);
|
||||||
|
});
|
||||||
|
OptionalFromJson.of(resource.getRefundBankAccountUuid()).ifPresent(newValue -> {
|
||||||
|
verifyNotNull(newValue, "refundBankAccount");
|
||||||
|
entity.setRefundBankAccount(em.getReference(HsOfficeBankAccountEntity.class, newValue));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,14 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
|||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||||
WHERE debitor.debitorNumber = :debitorNumber
|
WHERE cast(debitor.partner.debitorNumberPrefix as integer) = :debitorNumberPrefix
|
||||||
|
AND cast(debitor.debitorNumberSuffix as integer) = :debitorNumberSuffix
|
||||||
""")
|
""")
|
||||||
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber);
|
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumberPrefix, byte debitorNumberSuffix);
|
||||||
|
|
||||||
|
default List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
|
||||||
|
return findDebitorByDebitorNumber( debitorNumber/100, (byte) (debitorNumber%100));
|
||||||
|
}
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||||
|
@ -5,6 +5,7 @@ import com.vladmihalcea.hibernate.type.range.Range;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
@ -27,7 +28,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("Membership")
|
@DisplayName("Membership")
|
||||||
public class HsOfficeMembershipEntity implements Stringifyable {
|
public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeMembershipEntity> stringify = stringify(HsOfficeMembershipEntity.class)
|
private static Stringify<HsOfficeMembershipEntity> stringify = stringify(HsOfficeMembershipEntity.class)
|
||||||
.withProp(HsOfficeMembershipEntity::getMemberNumber)
|
.withProp(HsOfficeMembershipEntity::getMemberNumber)
|
||||||
@ -52,12 +53,15 @@ public class HsOfficeMembershipEntity implements Stringifyable {
|
|||||||
private HsOfficeDebitorEntity mainDebitor;
|
private HsOfficeDebitorEntity mainDebitor;
|
||||||
|
|
||||||
@Column(name = "membernumber")
|
@Column(name = "membernumber")
|
||||||
private int memberNumber;
|
private int memberNumber; // TODO: migrate to suffix, like debitorNumberSuffix
|
||||||
|
|
||||||
@Column(name = "validity", columnDefinition = "daterange")
|
@Column(name = "validity", columnDefinition = "daterange")
|
||||||
@Type(PostgreSQLRangeType.class)
|
@Type(PostgreSQLRangeType.class)
|
||||||
private Range<LocalDate> validity;
|
private Range<LocalDate> validity;
|
||||||
|
|
||||||
|
@Column(name = "membershipfeebillable", nullable = false)
|
||||||
|
private Boolean membershipFeeBillable; // not primitive to force setting the value
|
||||||
|
|
||||||
@Column(name = "reasonfortermination")
|
@Column(name = "reasonfortermination")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private HsOfficeReasonForTermination reasonForTermination;
|
private HsOfficeReasonForTermination reasonForTermination;
|
||||||
|
@ -37,6 +37,8 @@ public class HsOfficeMembershipEntityPatcher implements EntityPatcher<HsOfficeMe
|
|||||||
Optional.ofNullable(resource.getReasonForTermination())
|
Optional.ofNullable(resource.getReasonForTermination())
|
||||||
.map(v -> mapper.map(v, HsOfficeReasonForTermination.class))
|
.map(v -> mapper.map(v, HsOfficeReasonForTermination.class))
|
||||||
.ifPresent(entity::setReasonForTermination);
|
.ifPresent(entity::setReasonForTermination);
|
||||||
|
OptionalFromJson.of(resource.getMembershipFeeBillable()).ifPresent(
|
||||||
|
entity::setMembershipFeeBillable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyNotNull(final UUID newValue, final String propertyName) {
|
private void verifyNotNull(final UUID newValue, final String propertyName) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.membership;
|
package net.hostsharing.hsadminng.hs.office.membership;
|
||||||
|
|
||||||
public enum HsOfficeReasonForTermination {
|
public enum HsOfficeReasonForTermination {
|
||||||
NONE, CANCELLATION, TRANSFER, DEATH, LIQUIDATION, EXPULSION;
|
NONE, CANCELLATION, TRANSFER, DEATH, LIQUIDATION, EXPULSION, UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.migration;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface HasUuid {
|
||||||
|
UUID getUuid();
|
||||||
|
}
|
@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
@ -19,15 +20,16 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("PartnerDetails")
|
@DisplayName("PartnerDetails")
|
||||||
public class HsOfficePartnerDetailsEntity implements Stringifyable {
|
public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
|
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
|
||||||
HsOfficePartnerDetailsEntity.class,
|
HsOfficePartnerDetailsEntity.class,
|
||||||
"partnerDetails")
|
"partnerDetails")
|
||||||
.withProp(HsOfficePartnerDetailsEntity::getRegistrationOffice)
|
.withProp(HsOfficePartnerDetailsEntity::getRegistrationOffice)
|
||||||
.withProp(HsOfficePartnerDetailsEntity::getRegistrationNumber)
|
.withProp(HsOfficePartnerDetailsEntity::getRegistrationNumber)
|
||||||
|
.withProp(HsOfficePartnerDetailsEntity::getBirthPlace)
|
||||||
.withProp(HsOfficePartnerDetailsEntity::getBirthday)
|
.withProp(HsOfficePartnerDetailsEntity::getBirthday)
|
||||||
.withProp(HsOfficePartnerDetailsEntity::getBirthday)
|
.withProp(HsOfficePartnerDetailsEntity::getBirthName)
|
||||||
.withProp(HsOfficePartnerDetailsEntity::getDateOfDeath)
|
.withProp(HsOfficePartnerDetailsEntity::getDateOfDeath)
|
||||||
.withSeparator(", ")
|
.withSeparator(", ")
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
@ -39,6 +41,7 @@ public class HsOfficePartnerDetailsEntity implements Stringifyable {
|
|||||||
private @Column(name = "registrationoffice") String registrationOffice;
|
private @Column(name = "registrationoffice") String registrationOffice;
|
||||||
private @Column(name = "registrationnumber") String registrationNumber;
|
private @Column(name = "registrationnumber") String registrationNumber;
|
||||||
private @Column(name = "birthname") String birthName;
|
private @Column(name = "birthname") String birthName;
|
||||||
|
private @Column(name = "birthplace") String birthPlace;
|
||||||
private @Column(name = "birthday") LocalDate birthday;
|
private @Column(name = "birthday") LocalDate birthday;
|
||||||
private @Column(name = "dateofdeath") LocalDate dateOfDeath;
|
private @Column(name = "dateofdeath") LocalDate dateOfDeath;
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ class HsOfficePartnerDetailsEntityPatcher implements EntityPatcher<HsOfficePartn
|
|||||||
OptionalFromJson.of(resource.getRegistrationOffice()).ifPresent(entity::setRegistrationOffice);
|
OptionalFromJson.of(resource.getRegistrationOffice()).ifPresent(entity::setRegistrationOffice);
|
||||||
OptionalFromJson.of(resource.getRegistrationNumber()).ifPresent(entity::setRegistrationNumber);
|
OptionalFromJson.of(resource.getRegistrationNumber()).ifPresent(entity::setRegistrationNumber);
|
||||||
OptionalFromJson.of(resource.getBirthday()).ifPresent(entity::setBirthday);
|
OptionalFromJson.of(resource.getBirthday()).ifPresent(entity::setBirthday);
|
||||||
|
OptionalFromJson.of(resource.getBirthPlace()).ifPresent(entity::setBirthPlace);
|
||||||
OptionalFromJson.of(resource.getBirthName()).ifPresent(entity::setBirthName);
|
OptionalFromJson.of(resource.getBirthName()).ifPresent(entity::setBirthName);
|
||||||
OptionalFromJson.of(resource.getDateOfDeath()).ifPresent(entity::setDateOfDeath);
|
OptionalFromJson.of(resource.getDateOfDeath()).ifPresent(entity::setDateOfDeath);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
@ -10,6 +11,7 @@ import org.hibernate.annotations.NotFound;
|
|||||||
import org.hibernate.annotations.NotFoundAction;
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
@ -22,7 +24,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("Partner")
|
@DisplayName("Partner")
|
||||||
public class HsOfficePartnerEntity implements Stringifyable {
|
public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficePartnerEntity> stringify = stringify(HsOfficePartnerEntity.class, "partner")
|
private static Stringify<HsOfficePartnerEntity> stringify = stringify(HsOfficePartnerEntity.class, "partner")
|
||||||
.withProp(HsOfficePartnerEntity::getPerson)
|
.withProp(HsOfficePartnerEntity::getPerson)
|
||||||
@ -34,6 +36,9 @@ public class HsOfficePartnerEntity implements Stringifyable {
|
|||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
|
@Column(name = "debitornumberprefix", columnDefinition = "numeric(5) not null")
|
||||||
|
private Integer debitorNumberPrefix;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "personuuid", nullable = false)
|
@JoinColumn(name = "personuuid", nullable = false)
|
||||||
private HsOfficePersonEntity person;
|
private HsOfficePersonEntity person;
|
||||||
@ -43,7 +48,7 @@ public class HsOfficePartnerEntity implements Stringifyable {
|
|||||||
private HsOfficeContactEntity contact;
|
private HsOfficeContactEntity contact;
|
||||||
|
|
||||||
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, optional = true)
|
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, optional = true)
|
||||||
@JoinColumn(name = "detailsuuid", nullable = true)
|
@JoinColumn(name = "detailsuuid")
|
||||||
@NotFound(action = NotFoundAction.IGNORE)
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
private HsOfficePartnerDetailsEntity details;
|
private HsOfficePartnerDetailsEntity details;
|
||||||
|
|
||||||
@ -54,6 +59,6 @@ public class HsOfficePartnerEntity implements Stringifyable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return person.toShortString();
|
return Optional.ofNullable(person).map(HsOfficePersonEntity::toShortString).orElse("<person=null>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -21,7 +22,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayName("Person")
|
@DisplayName("Person")
|
||||||
public class HsOfficePersonEntity implements Stringifyable {
|
public class HsOfficePersonEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
|
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
|
||||||
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType)
|
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType)
|
||||||
@ -53,6 +54,7 @@ public class HsOfficePersonEntity implements Stringifyable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return !StringUtils.isEmpty(tradeName) ? tradeName : (familyName + ", " + givenName);
|
return personType + " " +
|
||||||
|
(!StringUtils.isEmpty(tradeName) ? tradeName : (familyName + ", " + givenName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.person;
|
package net.hostsharing.hsadminng.hs.office.person;
|
||||||
|
|
||||||
public enum HsOfficePersonType {
|
public enum HsOfficePersonType {
|
||||||
|
UNKNOWN,
|
||||||
NATURAL,
|
NATURAL,
|
||||||
LEGAL,
|
LEGAL,
|
||||||
SOLE_REPRESENTATION,
|
SOLE_REPRESENTATION,
|
||||||
|
@ -3,8 +3,10 @@ package net.hostsharing.hsadminng.hs.office.relationship;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -19,7 +21,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
public class HsOfficeRelationshipEntity {
|
public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeRelationshipEntity> toString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
private static Stringify<HsOfficeRelationshipEntity> toString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
||||||
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
||||||
@ -27,6 +29,11 @@ public class HsOfficeRelationshipEntity {
|
|||||||
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder)
|
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder)
|
||||||
.withProp(Fields.contact, HsOfficeRelationshipEntity::getContact);
|
.withProp(Fields.contact, HsOfficeRelationshipEntity::getContact);
|
||||||
|
|
||||||
|
private static Stringify<HsOfficeRelationshipEntity> toShortString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
||||||
|
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
||||||
|
.withProp(Fields.relType, HsOfficeRelationshipEntity::getRelType)
|
||||||
|
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
@ -51,4 +58,9 @@ public class HsOfficeRelationshipEntity {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return toString.apply(this);
|
return toString.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toShortString() {
|
||||||
|
return toShortString.apply(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relationship;
|
||||||
|
|
||||||
public enum HsOfficeRelationshipType {
|
public enum HsOfficeRelationshipType {
|
||||||
SOLE_AGENT,
|
UNKNOWN,
|
||||||
JOINT_AGENT,
|
EX_PARTNER,
|
||||||
ACCOUNTING_CONTACT,
|
REPRESENTATIVE,
|
||||||
TECHNICAL_CONTACT
|
VIP_CONTACT,
|
||||||
|
ACCOUNTING,
|
||||||
|
OPERATIONS
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import lombok.*;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
@ -25,7 +26,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("SEPA-Mandate")
|
@DisplayName("SEPA-Mandate")
|
||||||
public class HsOfficeSepaMandateEntity implements Stringifyable {
|
public class HsOfficeSepaMandateEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
|
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
|
||||||
.withProp(e -> e.getBankAccount().getIban())
|
.withProp(e -> e.getBankAccount().getIban())
|
||||||
|
@ -12,12 +12,19 @@ components:
|
|||||||
debitorNumber:
|
debitorNumber:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
minimum: 10000
|
minimum: 1000000
|
||||||
maximum: 99999
|
maximum: 9999999
|
||||||
|
debitorNumberSuffix:
|
||||||
|
type: integer
|
||||||
|
format: int8
|
||||||
|
minimum: 00
|
||||||
|
maximum: 99
|
||||||
partner:
|
partner:
|
||||||
$ref: './hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
$ref: './hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
||||||
billingContact:
|
billingContact:
|
||||||
$ref: './hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
|
$ref: './hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
|
||||||
|
billable:
|
||||||
|
type: boolean
|
||||||
vatId:
|
vatId:
|
||||||
type: string
|
type: string
|
||||||
vatCountryCode:
|
vatCountryCode:
|
||||||
@ -25,8 +32,13 @@ components:
|
|||||||
pattern: '^[A-Z][A-Z]$'
|
pattern: '^[A-Z][A-Z]$'
|
||||||
vatBusiness:
|
vatBusiness:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
vatReverseCharge:
|
||||||
|
type: boolean
|
||||||
refundBankAccount:
|
refundBankAccount:
|
||||||
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
|
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
|
||||||
|
defaultPrefix:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-z0-9]{3}$'
|
||||||
|
|
||||||
HsOfficeDebitorPatch:
|
HsOfficeDebitorPatch:
|
||||||
type: object
|
type: object
|
||||||
@ -35,6 +47,9 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
billable:
|
||||||
|
type: boolean
|
||||||
|
nullable: false
|
||||||
vatId:
|
vatId:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -44,11 +59,18 @@ components:
|
|||||||
nullable: true
|
nullable: true
|
||||||
vatBusiness:
|
vatBusiness:
|
||||||
type: boolean
|
type: boolean
|
||||||
nullable: true
|
nullable: false
|
||||||
|
vatReverseCharge:
|
||||||
|
type: boolean
|
||||||
|
nullable: false
|
||||||
refundBankAccountUuid:
|
refundBankAccountUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
defaultPrefix:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-z0-9]{3}$'
|
||||||
|
nullable: true
|
||||||
|
|
||||||
HsOfficeDebitorInsert:
|
HsOfficeDebitorInsert:
|
||||||
type: object
|
type: object
|
||||||
@ -61,11 +83,13 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
debitorNumber:
|
debitorNumberSuffix:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int8
|
||||||
minimum: 10000
|
minimum: 00
|
||||||
maximum: 99999
|
maximum: 99
|
||||||
|
billable:
|
||||||
|
type: boolean
|
||||||
vatId:
|
vatId:
|
||||||
type: string
|
type: string
|
||||||
vatCountryCode:
|
vatCountryCode:
|
||||||
@ -73,9 +97,17 @@ components:
|
|||||||
pattern: '^[A-Z][A-Z]$'
|
pattern: '^[A-Z][A-Z]$'
|
||||||
vatBusiness:
|
vatBusiness:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
vatReverseCharge:
|
||||||
|
type: boolean
|
||||||
refundBankAccountUuid:
|
refundBankAccountUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
defaultPrefix:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-z]{3}$'
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- partnerUuid
|
- partnerUuid
|
||||||
- billingContactUuid
|
- billingContactUuid
|
||||||
|
- defaultPrefix
|
||||||
|
- billable
|
||||||
|
@ -33,6 +33,8 @@ components:
|
|||||||
format: date
|
format: date
|
||||||
reasonForTermination:
|
reasonForTermination:
|
||||||
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
||||||
|
membershipFeeBillable:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
HsOfficeMembershipPatch:
|
HsOfficeMembershipPatch:
|
||||||
type: object
|
type: object
|
||||||
@ -48,6 +50,9 @@ components:
|
|||||||
reasonForTermination:
|
reasonForTermination:
|
||||||
nullable: true
|
nullable: true
|
||||||
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
||||||
|
membershipFeeBillable:
|
||||||
|
nullable: true
|
||||||
|
type: boolean
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
HsOfficeMembershipInsert:
|
HsOfficeMembershipInsert:
|
||||||
@ -74,8 +79,12 @@ components:
|
|||||||
nullable: true
|
nullable: true
|
||||||
reasonForTermination:
|
reasonForTermination:
|
||||||
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
||||||
|
membershipFeeBillable:
|
||||||
|
nullable: false
|
||||||
|
type: boolean
|
||||||
required:
|
required:
|
||||||
- partnerUuid
|
- partnerUuid
|
||||||
- mainDebitorUuid
|
- mainDebitorUuid
|
||||||
- validFrom
|
- validFrom
|
||||||
|
- membershipFeeBillable
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
@ -9,6 +9,11 @@ components:
|
|||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
debitorNumberPrefix:
|
||||||
|
type: integer
|
||||||
|
format: int8
|
||||||
|
minimum: 10000
|
||||||
|
maximum: 99999
|
||||||
person:
|
person:
|
||||||
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson'
|
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson'
|
||||||
contact:
|
contact:
|
||||||
@ -32,6 +37,9 @@ components:
|
|||||||
birthName:
|
birthName:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
|
birthPlace:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
birthday:
|
birthday:
|
||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
@ -68,6 +76,9 @@ components:
|
|||||||
birthName:
|
birthName:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
|
birthPlace:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
birthday:
|
birthday:
|
||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
@ -80,6 +91,11 @@ components:
|
|||||||
HsOfficePartnerInsert:
|
HsOfficePartnerInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
debitorNumberPrefix:
|
||||||
|
type: integer
|
||||||
|
format: int8
|
||||||
|
minimum: 10000
|
||||||
|
maximum: 99999
|
||||||
personUuid:
|
personUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
@ -89,6 +105,7 @@ components:
|
|||||||
details:
|
details:
|
||||||
$ref: '#/components/schemas/HsOfficePartnerDetailsInsert'
|
$ref: '#/components/schemas/HsOfficePartnerDetailsInsert'
|
||||||
required:
|
required:
|
||||||
|
- debitorNumberPrefix
|
||||||
- personUuid
|
- personUuid
|
||||||
- contactUuid
|
- contactUuid
|
||||||
- details
|
- details
|
||||||
@ -106,6 +123,9 @@ components:
|
|||||||
birthName:
|
birthName:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
|
birthPlace:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
birthday:
|
birthday:
|
||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
|
@ -6,10 +6,12 @@ components:
|
|||||||
HsOfficeRelationshipType:
|
HsOfficeRelationshipType:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- SOLE_AGENT # e.g. CEO
|
- UNKNOWN
|
||||||
- JOINT_AGENT # e.g. heir
|
- EX_PARTNER
|
||||||
- ACCOUNTING_CONTACT
|
- REPRESENTATIVE,
|
||||||
- TECHNICAL_CONTACT
|
- VIP_CONTACT
|
||||||
|
- ACCOUNTING,
|
||||||
|
- OPERATIONS
|
||||||
|
|
||||||
HsOfficeRelationship:
|
HsOfficeRelationship:
|
||||||
type: object
|
type: object
|
||||||
|
@ -20,3 +20,7 @@ spring:
|
|||||||
|
|
||||||
liquibase:
|
liquibase:
|
||||||
contexts: dev
|
contexts: dev
|
||||||
|
|
||||||
|
hsadminng:
|
||||||
|
postgres:
|
||||||
|
leakproof:
|
||||||
|
18
src/main/resources/db/changelog/009-check-environment.sql
Normal file
18
src/main/resources/db/changelog/009-check-environment.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- NUMERIC-HASH-FUNCTIONS
|
||||||
|
--changeset hash:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
do $$
|
||||||
|
begin
|
||||||
|
if starts_with ('${HSADMINNG_POSTGRES_ADMIN_USERNAME}', '$') then
|
||||||
|
RAISE EXCEPTION 'environment variable HSADMINNG_POSTGRES_ADMIN_USERNAME not set';
|
||||||
|
end if;
|
||||||
|
if starts_with ('${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}', '$') then
|
||||||
|
RAISE EXCEPTION 'environment variable HSADMINNG_POSTGRES_RESTRICTED_USERNAME not set';
|
||||||
|
end if;
|
||||||
|
end $$
|
||||||
|
--//
|
@ -55,7 +55,7 @@ end; $$;
|
|||||||
*/
|
*/
|
||||||
create or replace function currentTask()
|
create or replace function currentTask()
|
||||||
returns varchar(96)
|
returns varchar(96)
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentTask varchar(96);
|
currentTask varchar(96);
|
||||||
@ -83,7 +83,7 @@ end; $$;
|
|||||||
*/
|
*/
|
||||||
create or replace function currentRequest()
|
create or replace function currentRequest()
|
||||||
returns varchar(512)
|
returns varchar(512)
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentRequest varchar(512);
|
currentRequest varchar(512);
|
||||||
@ -107,7 +107,7 @@ end; $$;
|
|||||||
*/
|
*/
|
||||||
create or replace function currentUser()
|
create or replace function currentUser()
|
||||||
returns varchar(63)
|
returns varchar(63)
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentUser varchar(63);
|
currentUser varchar(63);
|
||||||
@ -131,7 +131,7 @@ end; $$;
|
|||||||
*/
|
*/
|
||||||
create or replace function assumedRoles()
|
create or replace function assumedRoles()
|
||||||
returns varchar(63)[]
|
returns varchar(63)[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentSubject varchar(63);
|
currentSubject varchar(63);
|
||||||
@ -155,7 +155,7 @@ create or replace function cleanIdentifier(rawIdentifier varchar)
|
|||||||
declare
|
declare
|
||||||
cleanIdentifier varchar;
|
cleanIdentifier varchar;
|
||||||
begin
|
begin
|
||||||
cleanIdentifier := regexp_replace(rawIdentifier, '[^A-Za-z0-9\-._]+', '', 'g');
|
cleanIdentifier := regexp_replace(rawIdentifier, '[^A-Za-z0-9\-._:]+', '', 'g');
|
||||||
return cleanIdentifier;
|
return cleanIdentifier;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ end ; $$;
|
|||||||
|
|
||||||
create or replace function currentSubjects()
|
create or replace function currentSubjects()
|
||||||
returns varchar(63)[]
|
returns varchar(63)[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
assumedRoles varchar(63)[];
|
assumedRoles varchar(63)[];
|
||||||
@ -229,7 +229,7 @@ end; $$;
|
|||||||
|
|
||||||
create or replace function hasAssumedRole()
|
create or replace function hasAssumedRole()
|
||||||
returns boolean
|
returns boolean
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
return array_length(assumedRoles(), 1) > 0;
|
return array_length(assumedRoles(), 1) > 0;
|
||||||
|
@ -208,7 +208,7 @@ create type RbacRoleDescriptor as
|
|||||||
create or replace function roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType)
|
create or replace function roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType)
|
||||||
returns RbacRoleDescriptor
|
returns RbacRoleDescriptor
|
||||||
returns null on null input
|
returns null on null input
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select objectTable, objectUuid, roleType::RbacRoleType;
|
select objectTable, objectUuid, roleType::RbacRoleType;
|
||||||
$$;
|
$$;
|
||||||
@ -432,7 +432,7 @@ $$;
|
|||||||
create or replace function findPermissionId(forObjectUuid uuid, forOp RbacOp)
|
create or replace function findPermissionId(forObjectUuid uuid, forOp RbacOp)
|
||||||
returns uuid
|
returns uuid
|
||||||
returns null on null input
|
returns null on null input
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select uuid
|
select uuid
|
||||||
from RbacPermission p
|
from RbacPermission p
|
||||||
@ -515,7 +515,7 @@ end; $$;
|
|||||||
|
|
||||||
create or replace function isPermissionGrantedToSubject(permissionId uuid, subjectId uuid)
|
create or replace function isPermissionGrantedToSubject(permissionId uuid, subjectId uuid)
|
||||||
returns BOOL
|
returns BOOL
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select exists(
|
select exists(
|
||||||
select *
|
select *
|
||||||
@ -537,7 +537,7 @@ $$;
|
|||||||
|
|
||||||
create or replace function hasGlobalRoleGranted(userUuid uuid)
|
create or replace function hasGlobalRoleGranted(userUuid uuid)
|
||||||
returns bool
|
returns bool
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select exists(
|
select exists(
|
||||||
select r.uuid
|
select r.uuid
|
||||||
@ -758,13 +758,20 @@ $$;
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset rbac-base-PGSQL-ROLES:1 endDelimiter:--//
|
--changeset rbac-base-PGSQL-ROLES:1 context:dev,tc endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
create role admin;
|
do $$
|
||||||
grant all privileges on all tables in schema public to admin;
|
begin
|
||||||
|
if '${HSADMINNG_POSTGRES_ADMIN_USERNAME}'='admin' then
|
||||||
create role restricted;
|
create role admin;
|
||||||
grant all privileges on all tables in schema public to restricted;
|
grant all privileges on all tables in schema public to admin;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if '${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}'='restricted' then
|
||||||
|
create role restricted;
|
||||||
|
end if;
|
||||||
|
-- grant all privileges on all tables in schema public to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
|
end $$
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
create or replace function assumedRoleUuid()
|
create or replace function assumedRoleUuid()
|
||||||
returns uuid
|
returns uuid
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentSubjectsUuids uuid[];
|
currentSubjectsUuids uuid[];
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
create or replace function determineCurrentUserUuid(currentUser varchar)
|
create or replace function determineCurrentUserUuid(currentUser varchar)
|
||||||
returns uuid
|
returns uuid
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentUserUuid uuid;
|
currentUserUuid uuid;
|
||||||
@ -25,11 +25,11 @@ end; $$;
|
|||||||
|
|
||||||
create or replace function determineCurrentSubjectsUuids(currentUserUuid uuid, assumedRoles varchar)
|
create or replace function determineCurrentSubjectsUuids(currentUserUuid uuid, assumedRoles varchar)
|
||||||
returns uuid[]
|
returns uuid[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
roleName varchar(63);
|
roleName text;
|
||||||
roleNameParts varchar(63);
|
roleNameParts text;
|
||||||
objectTableToAssume varchar(63);
|
objectTableToAssume varchar(63);
|
||||||
objectNameToAssume varchar(63);
|
objectNameToAssume varchar(63);
|
||||||
objectUuidToAssume uuid;
|
objectUuidToAssume uuid;
|
||||||
@ -116,7 +116,7 @@ end; $$;
|
|||||||
|
|
||||||
create or replace function currentUserUuid()
|
create or replace function currentUserUuid()
|
||||||
returns uuid
|
returns uuid
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentUserUuid text;
|
currentUserUuid text;
|
||||||
@ -150,7 +150,7 @@ end; $$;
|
|||||||
*/
|
*/
|
||||||
create or replace function currentSubjectsUuids()
|
create or replace function currentSubjectsUuids()
|
||||||
returns uuid[]
|
returns uuid[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentSubjectsUuids text;
|
currentSubjectsUuids text;
|
||||||
|
@ -41,7 +41,7 @@ select *
|
|||||||
) as unordered
|
) as unordered
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
order by objectTable || '#' || objectIdName || '.' || roleType;
|
order by objectTable || '#' || objectIdName || '.' || roleType;
|
||||||
grant all privileges on rbacrole_rv to restricted;
|
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) ||
|
|||||||
join RbacObject as o on o.uuid = r.objectUuid
|
join RbacObject as o on o.uuid = r.objectUuid
|
||||||
order by grantedRoleIdName;
|
order by grantedRoleIdName;
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
grant all privileges on rbacrole_rv to restricted;
|
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ create or replace view RbacUser_rv as
|
|||||||
) as unordered
|
) as unordered
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
order by unordered.name;
|
order by unordered.name;
|
||||||
grant all privileges on RbacUser_rv to restricted;
|
grant all privileges on RbacUser_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
@ -326,7 +326,7 @@ select r.uuid as roleuuid, p.uuid as permissionUuid,
|
|||||||
join rbacgrants g on g.ascendantuuid = r.uuid
|
join rbacgrants g on g.ascendantuuid = r.uuid
|
||||||
join rbacpermission p on p.uuid = g.descendantuuid
|
join rbacpermission p on p.uuid = g.descendantuuid
|
||||||
join rbacobject o on o.uuid = p.objectuuid;
|
join rbacobject o on o.uuid = p.objectuuid;
|
||||||
grant all privileges on RbacOwnGrantedPermissions_rv to restricted;
|
grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
-- @formatter:om
|
-- @formatter:om
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
@ -104,7 +104,7 @@ begin
|
|||||||
create or replace view %1$s_iv as
|
create or replace view %1$s_iv as
|
||||||
select target.uuid, cleanIdentifier(%2$s) as idName
|
select target.uuid, cleanIdentifier(%2$s) as idName
|
||||||
from %1$s as target;
|
from %1$s as target;
|
||||||
grant all privileges on %1$s_iv to restricted;
|
grant all privileges on %1$s_iv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
$sql$, targetTable, idNameExpression);
|
$sql$, targetTable, idNameExpression);
|
||||||
execute sql;
|
execute sql;
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ begin
|
|||||||
from %1$s as target
|
from %1$s as target
|
||||||
where target.uuid in (select * from accessibleObjects)
|
where target.uuid in (select * from accessibleObjects)
|
||||||
order by %2$s;
|
order by %2$s;
|
||||||
grant all privileges on %1$s_rv to restricted;
|
grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
$sql$, targetTable, orderBy);
|
$sql$, targetTable, orderBy);
|
||||||
execute sql;
|
execute sql;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ create table Global
|
|||||||
);
|
);
|
||||||
create unique index Global_Singleton on Global ((0));
|
create unique index Global_Singleton on Global ((0));
|
||||||
|
|
||||||
grant select on global to restricted;
|
grant select on global to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ drop view if exists global_iv;
|
|||||||
create or replace view global_iv as
|
create or replace view global_iv as
|
||||||
select target.uuid, target.name as idName
|
select target.uuid, target.name as idName
|
||||||
from global as target;
|
from global as target;
|
||||||
grant all privileges on global_iv to restricted;
|
grant all privileges on global_iv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns the objectUuid for a given identifying name (in this case the idName).
|
Returns the objectUuid for a given identifying name (in this case the idName).
|
||||||
@ -99,7 +99,7 @@ commit;
|
|||||||
create or replace function globalAdmin()
|
create or replace function globalAdmin()
|
||||||
returns RbacRoleDescriptor
|
returns RbacRoleDescriptor
|
||||||
returns null on null input
|
returns null on null input
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType;
|
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType;
|
||||||
$$;
|
$$;
|
||||||
|
@ -93,7 +93,7 @@ call generateRbacIdentityView('test_package', 'target.name');
|
|||||||
-- from test_package as target
|
-- from test_package as target
|
||||||
-- where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids()))
|
-- where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids()))
|
||||||
-- order by target.name;
|
-- order by target.name;
|
||||||
-- grant all privileges on test_package_rv to restricted;
|
-- grant all privileges on test_package_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
|
|
||||||
call generateRbacRestrictedView('test_package', 'target.name',
|
call generateRbacRestrictedView('test_package', 'target.name',
|
||||||
$updates$
|
$updates$
|
||||||
|
@ -110,5 +110,5 @@ create or replace view test_domain_rv as
|
|||||||
select target.*
|
select target.*
|
||||||
from test_domain as target
|
from test_domain as target
|
||||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectsUuids()));
|
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectsUuids()));
|
||||||
grant all privileges on test_domain_rv to restricted;
|
grant all privileges on test_domain_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
create table if not exists hs_office_contact
|
create table if not exists hs_office_contact
|
||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
label varchar(96) not null,
|
label varchar(128) not null,
|
||||||
postalAddress text,
|
postalAddress text,
|
||||||
emailAddresses text, -- TODO.feat: change to json
|
emailAddresses text, -- TODO.feat: change to json
|
||||||
phoneNumbers text -- TODO.feat: change to json
|
phoneNumbers text -- TODO.feat: change to json
|
||||||
|
@ -26,9 +26,6 @@ create or replace function createRbacRolesForHsOfficeContact()
|
|||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
|
||||||
ownerRole uuid;
|
|
||||||
adminRole uuid;
|
|
||||||
begin
|
begin
|
||||||
if TG_OP <> 'INSERT' then
|
if TG_OP <> 'INSERT' then
|
||||||
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
@ -107,7 +104,7 @@ do language plpgsql $$
|
|||||||
declare
|
declare
|
||||||
addCustomerPermissions uuid[];
|
addCustomerPermissions uuid[];
|
||||||
globalObjectUuid uuid;
|
globalObjectUuid uuid;
|
||||||
globalAdminRoleUuid uuid ;
|
globalAdminRoleUuid uuid;
|
||||||
begin
|
begin
|
||||||
call defineContext('granting global new-contact permission to global admin role', null, null, null);
|
call defineContext('granting global new-contact permission to global admin role', null, null, null);
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
--changeset hs-office-person-MAIN-TABLE:1 endDelimiter:--//
|
--changeset hs-office-person-MAIN-TABLE:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE HsOfficePersonType AS ENUM ('NATURAL', 'LEGAL', 'SOLE_REPRESENTATION', 'JOINT_REPRESENTATION');
|
CREATE TYPE HsOfficePersonType AS ENUM ('UNKNOWN', 'NATURAL', 'LEGAL', 'SOLE_REPRESENTATION', 'JOINT_REPRESENTATION');
|
||||||
|
|
||||||
CREATE CAST (character varying as HsOfficePersonType) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as HsOfficePersonType) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ begin
|
|||||||
grantedByRole => globalAdmin()
|
grantedByRole => globalAdmin()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- TODO: who is admin? the person itself? is it allowed for the person itself or a representative to edit the data?
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficePersonAdmin(NEW),
|
hsOfficePersonAdmin(NEW),
|
||||||
permissions => array['edit'],
|
permissions => array['edit'],
|
||||||
|
@ -10,6 +10,7 @@ create table hs_office_partner_details
|
|||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
registrationOffice varchar(96),
|
registrationOffice varchar(96),
|
||||||
registrationNumber varchar(96),
|
registrationNumber varchar(96),
|
||||||
|
birthPlace varchar(96),
|
||||||
birthName varchar(96),
|
birthName varchar(96),
|
||||||
birthday date,
|
birthday date,
|
||||||
dateOfDeath date
|
dateOfDeath date
|
||||||
@ -31,6 +32,7 @@ call create_journal('hs_office_partner_details');
|
|||||||
create table hs_office_partner
|
create table hs_office_partner
|
||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
|
debitorNumberPrefix varchar(5),
|
||||||
personUuid uuid not null references hs_office_person(uuid),
|
personUuid uuid not null references hs_office_person(uuid),
|
||||||
contactUuid uuid not null references hs_office_contact(uuid),
|
contactUuid uuid not null references hs_office_contact(uuid),
|
||||||
detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade
|
detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade
|
||||||
|
@ -27,7 +27,6 @@ create or replace function hsOfficePartnerRbacRolesTrigger()
|
|||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
declare
|
||||||
hsOfficePartnerTenant RbacRoleDescriptor;
|
|
||||||
oldPerson hs_office_person;
|
oldPerson hs_office_person;
|
||||||
newPerson hs_office_person;
|
newPerson hs_office_person;
|
||||||
oldContact hs_office_contact;
|
oldContact hs_office_contact;
|
||||||
@ -166,6 +165,8 @@ execute procedure hsOfficePartnerRbacRolesTrigger();
|
|||||||
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityView('hs_office_partner', $idName$
|
call generateRbacIdentityView('hs_office_partner', $idName$
|
||||||
|
-- TODO: simplify by using just debitorNumberPrefix for the essential part
|
||||||
|
debitorNumberPrefix || ':' ||
|
||||||
(select idName from hs_office_person_iv p where p.uuid = target.personuuid)
|
(select idName from hs_office_person_iv p where p.uuid = target.personuuid)
|
||||||
|| '-' ||
|
|| '-' ||
|
||||||
(select idName from hs_office_contact_iv c where c.uuid = target.contactuuid)
|
(select idName from hs_office_contact_iv c where c.uuid = target.contactuuid)
|
||||||
@ -179,6 +180,7 @@ call generateRbacIdentityView('hs_office_partner', $idName$
|
|||||||
call generateRbacRestrictedView('hs_office_partner',
|
call generateRbacRestrictedView('hs_office_partner',
|
||||||
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
|
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
|
||||||
$updates$
|
$updates$
|
||||||
|
debitorNumberPrefix = new.debitorNumberPrefix,
|
||||||
personUuid = new.personUuid,
|
personUuid = new.personUuid,
|
||||||
contactUuid = new.contactUuid
|
contactUuid = new.contactUuid
|
||||||
$updates$);
|
$updates$);
|
||||||
|
@ -29,6 +29,7 @@ call generateRbacRestrictedView('hs_office_partner_details',
|
|||||||
$updates$
|
$updates$
|
||||||
registrationOffice = new.registrationOffice,
|
registrationOffice = new.registrationOffice,
|
||||||
registrationNumber = new.registrationNumber,
|
registrationNumber = new.registrationNumber,
|
||||||
|
birthPlace = new.birthPlace,
|
||||||
birthName = new.birthName,
|
birthName = new.birthName,
|
||||||
birthday = new.birthday,
|
birthday = new.birthday,
|
||||||
dateOfDeath = new.dateOfDeath
|
dateOfDeath = new.dateOfDeath
|
||||||
|
@ -8,7 +8,10 @@
|
|||||||
/*
|
/*
|
||||||
Creates a single partner test record.
|
Creates a single partner test record.
|
||||||
*/
|
*/
|
||||||
create or replace procedure createHsOfficePartnerTestData( personTradeOrFamilyName varchar, contactLabel varchar )
|
create or replace procedure createHsOfficePartnerTestData(
|
||||||
|
debitorNumberPrefix numeric(5),
|
||||||
|
personTradeOrFamilyName varchar,
|
||||||
|
contactLabel varchar )
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
@ -51,8 +54,8 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
insert
|
insert
|
||||||
into hs_office_partner (uuid, personuuid, contactuuid, detailsUuid)
|
into hs_office_partner (uuid, debitorNumberPrefix, personuuid, contactuuid, detailsUuid)
|
||||||
values (uuid_generate_v4(), relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
values (uuid_generate_v4(), debitorNumberPrefix, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -64,11 +67,11 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficePartnerTestData('First GmbH', 'first contact');
|
call createHsOfficePartnerTestData(10001, 'First GmbH', 'first contact');
|
||||||
call createHsOfficePartnerTestData('Second e.K.', 'second contact');
|
call createHsOfficePartnerTestData(10002, 'Second e.K.', 'second contact');
|
||||||
call createHsOfficePartnerTestData('Third OHG', 'third contact');
|
call createHsOfficePartnerTestData(10003, 'Third OHG', 'third contact');
|
||||||
call createHsOfficePartnerTestData('Fourth e.G.', 'forth contact');
|
call createHsOfficePartnerTestData(10004, 'Fourth e.G.', 'forth contact');
|
||||||
call createHsOfficePartnerTestData('Smith', 'fifth contact');
|
call createHsOfficePartnerTestData(10010, 'Smith', 'fifth contact');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -4,7 +4,13 @@
|
|||||||
--changeset hs-office-relationship-MAIN-TABLE:1 endDelimiter:--//
|
--changeset hs-office-relationship-MAIN-TABLE:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE HsOfficeRelationshipType AS ENUM ('SOLE_AGENT', 'JOINT_AGENT', 'CO_OWNER', 'ACCOUNTING_CONTACT', 'TECHNICAL_CONTACT');
|
CREATE TYPE HsOfficeRelationshipType AS ENUM (
|
||||||
|
'UNKNOWN',
|
||||||
|
'EX_PARTNER',
|
||||||
|
'REPRESENTATIVE',
|
||||||
|
'VIP_CONTACT',
|
||||||
|
'ACCOUNTING',
|
||||||
|
'OPERATIONS');
|
||||||
|
|
||||||
CREATE CAST (character varying as HsOfficeRelationshipType) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as HsOfficeRelationshipType) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ begin
|
|||||||
select p.* from hs_office_person p where tradeName = intToVarChar(t, 4) into person;
|
select p.* from hs_office_person p where tradeName = intToVarChar(t, 4) into person;
|
||||||
select c.* from hs_office_contact c where c.label = intToVarChar(t, 4) || '#' || t into contact;
|
select c.* from hs_office_contact c where c.label = intToVarChar(t, 4) || '#' || t into contact;
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData(person.uuid, contact.uuid, 'SOLE_AGENT');
|
call createHsOfficeRelationshipTestData(person.uuid, contact.uuid, 'REPRESENTATIVE');
|
||||||
commit;
|
commit;
|
||||||
end loop;
|
end loop;
|
||||||
end; $$;
|
end; $$;
|
||||||
@ -71,11 +71,11 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficeRelationshipTestData('First GmbH', 'Smith', 'SOLE_AGENT', 'first contact');
|
call createHsOfficeRelationshipTestData('First GmbH', 'Smith', 'REPRESENTATIVE', 'first contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Second e.K.', 'Smith', 'SOLE_AGENT', 'second contact');
|
call createHsOfficeRelationshipTestData('Second e.K.', 'Smith', 'REPRESENTATIVE', 'second contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'SOLE_AGENT', 'third contact');
|
call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'REPRESENTATIVE', 'third contact');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
create table hs_office_bankaccount
|
create table hs_office_bankaccount
|
||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
holder varchar(27) not null,
|
holder varchar(64) not null,
|
||||||
iban varchar(34) not null,
|
iban varchar(34) not null,
|
||||||
bic varchar(11) not null
|
bic varchar(11) not null
|
||||||
);
|
);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
CREATE TABLE hs_office_sepamandate_legacy_id
|
CREATE TABLE hs_office_sepamandate_legacy_id
|
||||||
(
|
(
|
||||||
uuid uuid NOT NULL REFERENCES hs_office_sepamandate(uuid),
|
uuid uuid NOT NULL REFERENCES hs_office_sepamandate(uuid),
|
||||||
sepa_mandat_id integer NOT NULL
|
sepa_mandate_id integer NOT NULL
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ CREATE TABLE hs_office_sepamandate_legacy_id
|
|||||||
CREATE SEQUENCE IF NOT EXISTS hs_office_sepamandate_legacy_id_seq
|
CREATE SEQUENCE IF NOT EXISTS hs_office_sepamandate_legacy_id_seq
|
||||||
AS integer
|
AS integer
|
||||||
START 1000000000
|
START 1000000000
|
||||||
OWNED BY hs_office_sepamandate_legacy_id.sepa_mandat_id;
|
OWNED BY hs_office_sepamandate_legacy_id.sepa_mandate_id;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ CREATE SEQUENCE IF NOT EXISTS hs_office_sepamandate_legacy_id_seq
|
|||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
ALTER TABLE hs_office_sepamandate_legacy_id
|
ALTER TABLE hs_office_sepamandate_legacy_id
|
||||||
ALTER COLUMN sepa_mandat_id
|
ALTER COLUMN sepa_mandate_id
|
||||||
SET DEFAULT nextVal('hs_office_sepamandate_legacy_id_seq');
|
SET DEFAULT nextVal('hs_office_sepamandate_legacy_id_seq');
|
||||||
|
|
||||||
--/
|
--/
|
||||||
@ -42,7 +42,7 @@ ALTER TABLE hs_office_sepamandate_legacy_id
|
|||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CALL defineContext('schema-migration');
|
CALL defineContext('schema-migration');
|
||||||
INSERT INTO hs_office_sepamandate_legacy_id(uuid, sepa_mandat_id)
|
INSERT INTO hs_office_sepamandate_legacy_id(uuid, sepa_mandate_id)
|
||||||
SELECT uuid, nextVal('hs_office_sepamandate_legacy_id_seq') FROM hs_office_sepamandate;
|
SELECT uuid, nextVal('hs_office_sepamandate_legacy_id_seq') FROM hs_office_sepamandate;
|
||||||
--/
|
--/
|
||||||
|
|
||||||
|
@ -8,12 +8,18 @@ create table hs_office_debitor
|
|||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
partnerUuid uuid not null references hs_office_partner(uuid),
|
partnerUuid uuid not null references hs_office_partner(uuid),
|
||||||
debitorNumber numeric(5) not null,
|
billable boolean not null default true,
|
||||||
|
debitorNumberSuffix numeric(2) not null,
|
||||||
billingContactUuid uuid not null references hs_office_contact(uuid),
|
billingContactUuid uuid not null references hs_office_contact(uuid),
|
||||||
vatId varchar(24), -- TODO.spec: here or in person?
|
vatId varchar(24), -- TODO.spec: here or in person?
|
||||||
vatCountryCode varchar(2),
|
vatCountryCode varchar(2),
|
||||||
vatBusiness boolean not null, -- TODO.spec: more of such?
|
vatBusiness boolean not null,
|
||||||
refundBankAccountUuid uuid references hs_office_bankaccount(uuid)
|
vatReverseCharge boolean not null,
|
||||||
|
refundBankAccountUuid uuid references hs_office_bankaccount(uuid),
|
||||||
|
defaultPrefix char(3) not null unique
|
||||||
|
constraint check_default_prefix check (
|
||||||
|
defaultPrefix::text ~ '^([a-z]{3}|al0|bh1|c4s|f3k|k8i|l3d|mh1|o13|p2m|s80|t4w)$'
|
||||||
|
)
|
||||||
-- TODO.impl: SEPA-mandate
|
-- TODO.impl: SEPA-mandate
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
@ -172,8 +172,10 @@ execute procedure hsOfficeDebitorRbacRolesTrigger();
|
|||||||
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityView('hs_office_debitor', $idName$
|
call generateRbacIdentityView('hs_office_debitor', $idName$
|
||||||
'#' || debitorNumber || ':' ||
|
'#' ||
|
||||||
(select idName from hs_office_partner_iv p where p.uuid = target.partnerUuid)
|
(select debitornumberprefix from hs_office_partner p where p.uuid = target.partnerUuid) ||
|
||||||
|
to_char(debitorNumberSuffix, 'fm00') ||
|
||||||
|
':' || (select split_part(idName, ':', 2) from hs_office_partner_iv pi where pi.uuid = target.partnerUuid)
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -181,14 +183,18 @@ call generateRbacIdentityView('hs_office_debitor', $idName$
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumber',
|
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumberSuffix',
|
||||||
$updates$
|
$updates$
|
||||||
partnerUuid = new.partnerUuid,
|
partnerUuid = new.partnerUuid, -- TODO: remove? should never do anything
|
||||||
|
billable = new.billable,
|
||||||
billingContactUuid = new.billingContactUuid,
|
billingContactUuid = new.billingContactUuid,
|
||||||
|
debitorNumberSuffix = new.debitorNumberSuffix, -- TODO: Should it be allowed to updated this value?
|
||||||
refundBankAccountUuid = new.refundBankAccountUuid,
|
refundBankAccountUuid = new.refundBankAccountUuid,
|
||||||
vatId = new.vatId,
|
vatId = new.vatId,
|
||||||
vatCountryCode = new.vatCountryCode,
|
vatCountryCode = new.vatCountryCode,
|
||||||
vatBusiness = new.vatBusiness
|
vatBusiness = new.vatBusiness,
|
||||||
|
vatreversecharge = new.vatreversecharge,
|
||||||
|
defaultPrefix = new.defaultPrefix -- TODO: Should it be allowed to updated this value?
|
||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
/*
|
/*
|
||||||
Creates a single debitor test record.
|
Creates a single debitor test record.
|
||||||
*/
|
*/
|
||||||
create or replace procedure createHsOfficeDebitorTestData( partnerTradeName varchar, billingContactLabel varchar )
|
create or replace procedure createHsOfficeDebitorTestData(
|
||||||
|
debitorNumberSuffix numeric(5),
|
||||||
|
partnerTradeName varchar,
|
||||||
|
billingContactLabel varchar,
|
||||||
|
defaultPrefix varchar
|
||||||
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
@ -16,7 +21,6 @@ declare
|
|||||||
relatedPartner hs_office_partner;
|
relatedPartner hs_office_partner;
|
||||||
relatedContact hs_office_contact;
|
relatedContact hs_office_contact;
|
||||||
relatedBankAccountUuid uuid;
|
relatedBankAccountUuid uuid;
|
||||||
newDebitorNumber numeric(6);
|
|
||||||
begin
|
begin
|
||||||
idName := cleanIdentifier( partnerTradeName|| '-' || billingContactLabel);
|
idName := cleanIdentifier( partnerTradeName|| '-' || billingContactLabel);
|
||||||
currentTask := 'creating debitor test-data ' || idName;
|
currentTask := 'creating debitor test-data ' || idName;
|
||||||
@ -28,14 +32,13 @@ begin
|
|||||||
where person.tradeName = partnerTradeName into relatedPartner;
|
where person.tradeName = partnerTradeName into relatedPartner;
|
||||||
select c.* from hs_office_contact c where c.label = billingContactLabel into relatedContact;
|
select c.* from hs_office_contact c where c.label = billingContactLabel into relatedContact;
|
||||||
select b.uuid from hs_office_bankaccount b where b.holder = partnerTradeName into relatedBankAccountUuid;
|
select b.uuid from hs_office_bankaccount b where b.holder = partnerTradeName into relatedBankAccountUuid;
|
||||||
select coalesce(max(debitorNumber)+1, 10001) from hs_office_debitor into newDebitorNumber;
|
|
||||||
|
|
||||||
raise notice 'creating test debitor: % (#%)', idName, newDebitorNumber;
|
raise notice 'creating test debitor: % (#%)', idName, debitorNumberSuffix;
|
||||||
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
||||||
raise notice '- using billingContact (%): %', relatedContact.uuid, relatedContact;
|
raise notice '- using billingContact (%): %', relatedContact.uuid, relatedContact;
|
||||||
insert
|
insert
|
||||||
into hs_office_debitor (uuid, partneruuid, debitornumber, billingcontactuuid, vatbusiness, refundbankaccountuuid)
|
into hs_office_debitor (uuid, partneruuid, debitornumbersuffix, billable, billingcontactuuid, vatbusiness, vatreversecharge, refundbankaccountuuid, defaultprefix)
|
||||||
values (uuid_generate_v4(), relatedPartner.uuid, newDebitorNumber, relatedContact.uuid, true, relatedBankAccountUuid);
|
values (uuid_generate_v4(), relatedPartner.uuid, debitorNumberSuffix, true, relatedContact.uuid, true, false, relatedBankAccountUuid, defaultPrefix);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -46,9 +49,9 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficeDebitorTestData('First GmbH', 'first contact');
|
call createHsOfficeDebitorTestData(11, 'First GmbH', 'first contact', 'fir');
|
||||||
call createHsOfficeDebitorTestData('Second e.K.', 'second contact');
|
call createHsOfficeDebitorTestData(12, 'Second e.K.', 'second contact', 'sec');
|
||||||
call createHsOfficeDebitorTestData('Third OHG', 'third contact');
|
call createHsOfficeDebitorTestData(13, 'Third OHG', 'third contact', 'thi');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
--changeset hs-office-membership-MAIN-TABLE:1 endDelimiter:--//
|
--changeset hs-office-membership-MAIN-TABLE:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE HsOfficeReasonForTermination AS ENUM ('NONE', 'CANCELLATION', 'TRANSFER', 'DEATH', 'LIQUIDATION', 'EXPULSION');
|
CREATE TYPE HsOfficeReasonForTermination AS ENUM ('NONE', 'CANCELLATION', 'TRANSFER', 'DEATH', 'LIQUIDATION', 'EXPULSION', 'UNKNOWN');
|
||||||
|
|
||||||
CREATE CAST (character varying as HsOfficeReasonForTermination) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as HsOfficeReasonForTermination) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
@ -15,7 +15,8 @@ create table if not exists hs_office_membership
|
|||||||
mainDebitorUuid uuid not null references hs_office_debitor(uuid),
|
mainDebitorUuid uuid not null references hs_office_debitor(uuid),
|
||||||
memberNumber numeric(5) not null unique,
|
memberNumber numeric(5) not null unique,
|
||||||
validity daterange not null,
|
validity daterange not null,
|
||||||
reasonForTermination HsOfficeReasonForTermination not null default 'NONE'
|
reasonForTermination HsOfficeReasonForTermination not null default 'NONE',
|
||||||
|
membershipFeeBillable boolean not null default true
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -92,7 +92,8 @@ execute procedure hsOfficeMembershipRbacRolesTrigger();
|
|||||||
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityView('hs_office_membership', idNameExpression => $idName$
|
call generateRbacIdentityView('hs_office_membership', idNameExpression => $idName$
|
||||||
target.memberNumber || (select idName from hs_office_partner_iv p where p.uuid = target.partnerUuid)
|
target.memberNumber ||
|
||||||
|
':' || (select split_part(idName, ':', 2) from hs_office_partner_iv p where p.uuid = target.partnerUuid)
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -104,7 +105,8 @@ call generateRbacRestrictedView('hs_office_membership',
|
|||||||
orderby => 'target.memberNumber',
|
orderby => 'target.memberNumber',
|
||||||
columnUpdates => $updates$
|
columnUpdates => $updates$
|
||||||
validity = new.validity,
|
validity = new.validity,
|
||||||
reasonForTermination = new.reasonForTermination
|
reasonForTermination = new.reasonForTermination,
|
||||||
|
membershipFeeBillable = new.membershipFeeBillable
|
||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ begin
|
|||||||
select partner.* from hs_office_partner partner
|
select partner.* from hs_office_partner partner
|
||||||
join hs_office_person person on person.uuid = partner.personUuid
|
join hs_office_person person on person.uuid = partner.personUuid
|
||||||
where person.tradeName = forPartnerTradeName into relatedPartner;
|
where person.tradeName = forPartnerTradeName into relatedPartner;
|
||||||
select d.* from hs_office_debitor d where d.debitorNumber = forMainDebitorNumber into relatedDebitor;
|
select d.* from hs_office_debitor d where d.debitorNumberSuffix = forMainDebitorNumber into relatedDebitor;
|
||||||
select coalesce(max(memberNumber)+1, 10001) from hs_office_membership into newMemberNumber;
|
select coalesce(max(memberNumber)+1, 10001) from hs_office_membership into newMemberNumber;
|
||||||
|
|
||||||
raise notice 'creating test Membership: %', idName;
|
raise notice 'creating test Membership: %', idName;
|
||||||
@ -44,9 +44,9 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficeMembershipTestData('First GmbH', 10001);
|
call createHsOfficeMembershipTestData('First GmbH', 11);
|
||||||
call createHsOfficeMembershipTestData('Second e.K.', 10002);
|
call createHsOfficeMembershipTestData('Second e.K.', 12);
|
||||||
call createHsOfficeMembershipTestData('Third OHG', 10003);
|
call createHsOfficeMembershipTestData('Third OHG', 13);
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -10,7 +10,8 @@ CREATE TYPE HsOfficeCoopAssetsTransactionType AS ENUM ('ADJUSTMENT',
|
|||||||
'TRANSFER',
|
'TRANSFER',
|
||||||
'ADOPTION',
|
'ADOPTION',
|
||||||
'CLEARING',
|
'CLEARING',
|
||||||
'LOSS');
|
'LOSS',
|
||||||
|
'LIMITATION');
|
||||||
|
|
||||||
CREATE CAST (character varying as HsOfficeCoopAssetsTransactionType) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as HsOfficeCoopAssetsTransactionType) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@ databaseChangeLog:
|
|||||||
file: db/changelog/005-uuid-ossp-extension.sql
|
file: db/changelog/005-uuid-ossp-extension.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/006-numeric-hash-functions.sql
|
file: db/changelog/006-numeric-hash-functions.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/009-check-environment.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/010-context.sql
|
file: db/changelog/010-context.sql
|
||||||
- include:
|
- include:
|
||||||
|
@ -30,16 +30,17 @@ public class ArchitectureTest {
|
|||||||
"..test.pac",
|
"..test.pac",
|
||||||
"..context",
|
"..context",
|
||||||
"..generated..",
|
"..generated..",
|
||||||
"..hs.office.person",
|
|
||||||
"..hs.office.partner",
|
|
||||||
"..hs.office.bankaccount",
|
"..hs.office.bankaccount",
|
||||||
"..hs.office.debitor",
|
|
||||||
"..hs.office.relationship",
|
|
||||||
"..hs.office.contact",
|
"..hs.office.contact",
|
||||||
"..hs.office.sepamandate",
|
|
||||||
"..hs.office.coopassets",
|
"..hs.office.coopassets",
|
||||||
"..hs.office.coopshares",
|
"..hs.office.coopshares",
|
||||||
|
"..hs.office.debitor",
|
||||||
"..hs.office.membership",
|
"..hs.office.membership",
|
||||||
|
"..hs.office.migration",
|
||||||
|
"..hs.office.partner",
|
||||||
|
"..hs.office.person",
|
||||||
|
"..hs.office.relationship",
|
||||||
|
"..hs.office.sepamandate",
|
||||||
"..errors",
|
"..errors",
|
||||||
"..mapper",
|
"..mapper",
|
||||||
"..ping",
|
"..ping",
|
||||||
@ -121,14 +122,19 @@ public class ArchitectureTest {
|
|||||||
public static final ArchRule hsOfficeBankAccountPackageRule = classes()
|
public static final ArchRule hsOfficeBankAccountPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.bankaccount..")
|
.that().resideInAPackage("..hs.office.bankaccount..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.bankaccount..", "..hs.office.sepamandate..", "..hs.office.debitor..");
|
.resideInAnyPackage("..hs.office.bankaccount..",
|
||||||
|
"..hs.office.sepamandate..",
|
||||||
|
"..hs.office.debitor..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficeSepaMandatePackageRule = classes()
|
public static final ArchRule hsOfficeSepaMandatePackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.sepamandate..")
|
.that().resideInAPackage("..hs.office.sepamandate..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.sepamandate..", "..hs.office.debitor..");
|
.resideInAnyPackage("..hs.office.sepamandate..",
|
||||||
|
"..hs.office.debitor..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -136,7 +142,10 @@ public class ArchitectureTest {
|
|||||||
.that().resideInAPackage("..hs.office.contact..")
|
.that().resideInAPackage("..hs.office.contact..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.contact..", "..hs.office.relationship..",
|
.resideInAnyPackage("..hs.office.contact..", "..hs.office.relationship..",
|
||||||
"..hs.office.partner..", "..hs.office.debitor..", "..hs.office.membership..");
|
"..hs.office.partner..",
|
||||||
|
"..hs.office.debitor..",
|
||||||
|
"..hs.office.membership..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -144,42 +153,63 @@ public class ArchitectureTest {
|
|||||||
.that().resideInAPackage("..hs.office.person..")
|
.that().resideInAPackage("..hs.office.person..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.person..", "..hs.office.relationship..",
|
.resideInAnyPackage("..hs.office.person..", "..hs.office.relationship..",
|
||||||
"..hs.office.partner..", "..hs.office.debitor..", "..hs.office.membership..");
|
"..hs.office.partner..",
|
||||||
|
"..hs.office.debitor..",
|
||||||
|
"..hs.office.membership..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficeRelationshipPackageRule = classes()
|
public static final ArchRule hsOfficeRelationshipPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.relationship..")
|
.that().resideInAPackage("..hs.office.relationship..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.relationship..");
|
.resideInAnyPackage("..hs.office.relationship..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficePartnerPackageRule = classes()
|
public static final ArchRule hsOfficePartnerPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.partner..")
|
.that().resideInAPackage("..hs.office.partner..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.partner..", "..hs.office.debitor..", "..hs.office.membership..");
|
.resideInAnyPackage("..hs.office.partner..",
|
||||||
|
"..hs.office.debitor..",
|
||||||
|
"..hs.office.membership..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficeMembershipPackageRule = classes()
|
public static final ArchRule hsOfficeMembershipPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.membership..")
|
.that().resideInAPackage("..hs.office.membership..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.membership..", "..hs.office.coopassets..", "..hs.office.coopshares..");
|
.resideInAnyPackage("..hs.office.membership..",
|
||||||
|
"..hs.office.coopassets..",
|
||||||
|
"..hs.office.coopshares..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficeCoopAssetsPackageRule = classes()
|
public static final ArchRule hsOfficeCoopAssetsPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.coopassets..")
|
.that().resideInAPackage("..hs.office.coopassets..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.coopassets..");
|
.resideInAnyPackage(
|
||||||
|
"..hs.office.coopassets..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficeCoopSharesPackageRule = classes()
|
public static final ArchRule hsOfficeCoopSharesPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.coopshares..")
|
.that().resideInAPackage("..hs.office.coopshares..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.coopshares..");
|
.resideInAnyPackage(
|
||||||
|
"..hs.office.coopshares..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
|
@ArchTest
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static final ArchRule hsOfficeMigrationPackageRule = classes()
|
||||||
|
.that().resideInAPackage("..hs.office.migration..")
|
||||||
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
|
.resideInAnyPackage("..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -197,7 +227,7 @@ public class ArchitectureTest {
|
|||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule doNotUsejakartaTransactionAnnotationAtClassLevel = noClasses()
|
public static final ArchRule doNotUseJakartaTransactionAnnotationAtClassLevel = noClasses()
|
||||||
.should().beAnnotatedWith(jakarta.transaction.Transactional.class.getName())
|
.should().beAnnotatedWith(jakarta.transaction.Transactional.class.getName())
|
||||||
.as("Use @%s instead of @%s.".formatted(
|
.as("Use @%s instead of @%s.".formatted(
|
||||||
org.springframework.transaction.annotation.Transactional.class.getName(),
|
org.springframework.transaction.annotation.Transactional.class.getName(),
|
||||||
@ -205,7 +235,7 @@ public class ArchitectureTest {
|
|||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule doNotUsejakartaTransactionAnnotationAtMethodLevel = noMethods()
|
public static final ArchRule doNotUseJakartaTransactionAnnotationAtMethodLevel = noMethods()
|
||||||
.should().beAnnotatedWith(jakarta.transaction.Transactional.class)
|
.should().beAnnotatedWith(jakarta.transaction.Transactional.class)
|
||||||
.as("Use @%s instead of @%s.".formatted(
|
.as("Use @%s instead of @%s.".formatted(
|
||||||
org.springframework.transaction.annotation.Transactional.class.getName(),
|
org.springframework.transaction.annotation.Transactional.class.getName(),
|
||||||
|
@ -17,6 +17,7 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest {
|
|||||||
.transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT)
|
.transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT)
|
||||||
.assetValue(new BigDecimal("128.00"))
|
.assetValue(new BigDecimal("128.00"))
|
||||||
.build();
|
.build();
|
||||||
|
final HsOfficeCoopAssetsTransactionEntity givenEmptyCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder().build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toStringContainsAlmostAllPropertiesAccount() {
|
void toStringContainsAlmostAllPropertiesAccount() {
|
||||||
@ -31,4 +32,18 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest {
|
|||||||
|
|
||||||
assertThat(result).isEqualTo("300001+128.00");
|
assertThat(result).isEqualTo("300001+128.00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toStringWithEmptyTransactionDoesNotThrowException() {
|
||||||
|
final var result = givenEmptyCoopAssetsTransaction.toString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("CoopAssetsTransaction()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toShortStringEmptyTransactionDoesNotThrowException() {
|
||||||
|
final var result = givenEmptyCoopAssetsTransaction.toShortString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("nullnu");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm view on coopassetstransaction#temprefB to role membership#10001....tenant by system and assume }",
|
"{ grant perm view on coopassetstransaction#temprefB to role membership#10001:....tenant by system and assume }",
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,17 +144,17 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then
|
// then
|
||||||
allTheseCoopAssetsTransactionsAreReturned(
|
allTheseCoopAssetsTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1)",
|
"CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1, initial deposit)",
|
||||||
"CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2)",
|
"CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2, partial disbursal)",
|
||||||
"CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3)",
|
"CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3, some adjustment)",
|
||||||
|
|
||||||
"CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1)",
|
"CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1, initial deposit)",
|
||||||
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2)",
|
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)",
|
||||||
"CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3)",
|
"CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3, some adjustment)",
|
||||||
|
|
||||||
"CoopAssetsTransaction(10003, 2010-03-15, DEPOSIT, 320.00, ref 10003-1)",
|
"CoopAssetsTransaction(10003, 2010-03-15, DEPOSIT, 320.00, ref 10003-1, initial deposit)",
|
||||||
"CoopAssetsTransaction(10003, 2021-09-01, DISBURSAL, -128.00, ref 10003-2)",
|
"CoopAssetsTransaction(10003, 2021-09-01, DISBURSAL, -128.00, ref 10003-2, partial disbursal)",
|
||||||
"CoopAssetsTransaction(10003, 2022-10-20, ADJUSTMENT, 128.00, ref 10003-3)");
|
"CoopAssetsTransaction(10003, 2022-10-20, ADJUSTMENT, 128.00, ref 10003-3, some adjustment)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -173,9 +173,9 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then
|
// then
|
||||||
allTheseCoopAssetsTransactionsAreReturned(
|
allTheseCoopAssetsTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1)",
|
"CoopAssetsTransaction(10002, 2010-03-15, DEPOSIT, 320.00, ref 10002-1, initial deposit)",
|
||||||
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2)",
|
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)",
|
||||||
"CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3)");
|
"CoopAssetsTransaction(10002, 2022-10-20, ADJUSTMENT, 128.00, ref 10002-3, some adjustment)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -194,14 +194,13 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then
|
// then
|
||||||
allTheseCoopAssetsTransactionsAreReturned(
|
allTheseCoopAssetsTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2)");
|
"CoopAssetsTransaction(10002, 2021-09-01, DISBURSAL, -128.00, ref 10002-2, partial disbursal)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewOnlyRelatedCoopAssetsTransactions() {
|
public void normalUser_canViewOnlyRelatedCoopAssetsTransactions() {
|
||||||
// given:
|
// given:
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.admin");
|
||||||
// "hs_office_person#FirstGmbH.admin",
|
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
|
final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
@ -212,9 +211,9 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseCoopAssetsTransactionsAreReturned(
|
exactlyTheseCoopAssetsTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1)",
|
"CoopAssetsTransaction(10001, 2010-03-15, DEPOSIT, 320.00, ref 10001-1, initial deposit)",
|
||||||
"CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2)",
|
"CoopAssetsTransaction(10001, 2021-09-01, DISBURSAL, -128.00, ref 10001-2, partial disbursal)",
|
||||||
"CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3)");
|
"CoopAssetsTransaction(10001, 2022-10-20, ADJUSTMENT, 128.00, ref 10001-3, some adjustment)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ class HsOfficeCoopSharesTransactionEntityUnitTest {
|
|||||||
.transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION)
|
.transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION)
|
||||||
.shareCount(4)
|
.shareCount(4)
|
||||||
.build();
|
.build();
|
||||||
|
final HsOfficeCoopSharesTransactionEntity givenEmptyCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder().build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toStringContainsAlmostAllPropertiesAccount() {
|
void toStringContainsAlmostAllPropertiesAccount() {
|
||||||
@ -25,9 +26,23 @@ class HsOfficeCoopSharesTransactionEntityUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsOnlyMemberNumberAndshareCountOnly() {
|
void toShortStringContainsOnlyMemberNumberAndShareCountOnly() {
|
||||||
final var result = givenCoopSharesTransaction.toShortString();
|
final var result = givenCoopSharesTransaction.toShortString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("300001+4");
|
assertThat(result).isEqualTo("300001+4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toStringEmptyTransactionDoesNotThrowException() {
|
||||||
|
final var result = givenEmptyCoopSharesTransaction.toString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("CoopShareTransaction(0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toShortStringEmptyTransactionDoesNotThrowException() {
|
||||||
|
final var result = givenEmptyCoopSharesTransaction.toShortString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("null+0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm view on coopsharestransaction#temprefB to role membership#10001....tenant by system and assume }",
|
"{ grant perm view on coopsharestransaction#temprefB to role membership#10001:....tenant by system and assume }",
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,17 +143,17 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then
|
// then
|
||||||
allTheseCoopSharesTransactionsAreReturned(
|
allTheseCoopSharesTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1)",
|
"CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1, initial subscription)",
|
||||||
"CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2)",
|
"CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2, cancelling some)",
|
||||||
"CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3)",
|
"CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3, some adjustment)",
|
||||||
|
|
||||||
"CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1)",
|
"CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1, initial subscription)",
|
||||||
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2)",
|
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)",
|
||||||
"CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3)",
|
"CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3, some adjustment)",
|
||||||
|
|
||||||
"CoopShareTransaction(10003, 2010-03-15, SUBSCRIPTION, 4, ref 10003-1)",
|
"CoopShareTransaction(10003, 2010-03-15, SUBSCRIPTION, 4, ref 10003-1, initial subscription)",
|
||||||
"CoopShareTransaction(10003, 2021-09-01, CANCELLATION, -2, ref 10003-2)",
|
"CoopShareTransaction(10003, 2021-09-01, CANCELLATION, -2, ref 10003-2, cancelling some)",
|
||||||
"CoopShareTransaction(10003, 2022-10-20, ADJUSTMENT, 2, ref 10003-3)");
|
"CoopShareTransaction(10003, 2022-10-20, ADJUSTMENT, 2, ref 10003-3, some adjustment)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -172,9 +172,9 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then
|
// then
|
||||||
allTheseCoopSharesTransactionsAreReturned(
|
allTheseCoopSharesTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1)",
|
"CoopShareTransaction(10002, 2010-03-15, SUBSCRIPTION, 4, ref 10002-1, initial subscription)",
|
||||||
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2)",
|
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)",
|
||||||
"CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3)");
|
"CoopShareTransaction(10002, 2022-10-20, ADJUSTMENT, 2, ref 10002-3, some adjustment)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -193,14 +193,13 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then
|
// then
|
||||||
allTheseCoopSharesTransactionsAreReturned(
|
allTheseCoopSharesTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2)");
|
"CoopShareTransaction(10002, 2021-09-01, CANCELLATION, -2, ref 10002-2, cancelling some)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewOnlyRelatedCoopSharesTransactions() {
|
public void normalUser_canViewOnlyRelatedCoopSharesTransactions() {
|
||||||
// given:
|
// given:
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.admin");
|
||||||
// "hs_office_person#FirstGmbH.admin",
|
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
@ -211,9 +210,9 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseCoopSharesTransactionsAreReturned(
|
exactlyTheseCoopSharesTransactionsAreReturned(
|
||||||
result,
|
result,
|
||||||
"CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1)",
|
"CoopShareTransaction(10001, 2010-03-15, SUBSCRIPTION, 4, ref 10001-1, initial subscription)",
|
||||||
"CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2)",
|
"CoopShareTransaction(10001, 2021-09-01, CANCELLATION, -2, ref 10001-2, cancelling some)",
|
||||||
"CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3)");
|
"CoopShareTransaction(10001, 2022-10-20, ADJUSTMENT, 2, ref 10001-3, some adjustment)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ import static org.hamcrest.Matchers.*;
|
|||||||
@Transactional
|
@Transactional
|
||||||
class HsOfficeDebitorControllerAcceptanceTest {
|
class HsOfficeDebitorControllerAcceptanceTest {
|
||||||
|
|
||||||
private static final int LOWEST_TEMP_DEBITOR_NUMBER = 20000;
|
private static final int LOWEST_TEMP_DEBITOR_SUFFIX = 90;
|
||||||
private static int nextDebitorNumber = LOWEST_TEMP_DEBITOR_NUMBER;
|
private static byte nextDebitorSuffix = LOWEST_TEMP_DEBITOR_SUFFIX;
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
private Integer port;
|
private Integer port;
|
||||||
@ -81,7 +81,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
|
"debitorNumberSuffix": 11,
|
||||||
"partner": { "person": { "personType": "LEGAL" } },
|
"partner": { "person": { "personType": "LEGAL" } },
|
||||||
"billingContact": { "label": "first contact" },
|
"billingContact": { "label": "first contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -90,7 +91,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
"refundBankAccount": { "holder": "First GmbH" }
|
"refundBankAccount": { "holder": "First GmbH" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitorNumber": 10002,
|
"debitorNumber": 1000212,
|
||||||
|
"debitorNumberSuffix": 12,
|
||||||
"partner": { "person": { "tradeName": "Second e.K." } },
|
"partner": { "person": { "tradeName": "Second e.K." } },
|
||||||
"billingContact": { "label": "second contact" },
|
"billingContact": { "label": "second contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -99,7 +101,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
"refundBankAccount": { "holder": "Second e.K." }
|
"refundBankAccount": { "holder": "Second e.K." }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitorNumber": 10003,
|
"debitorNumber": 1000313,
|
||||||
|
"debitorNumberSuffix": 13,
|
||||||
"partner": { "person": { "tradeName": "Third OHG" } },
|
"partner": { "person": { "tradeName": "Third OHG" } },
|
||||||
"billingContact": { "label": "third contact" },
|
"billingContact": { "label": "third contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -120,14 +123,14 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors?debitorNumber=10002")
|
.get("http://localhost/api/hs/office/debitors?debitorNumber=1000212")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitorNumber": 10002,
|
"debitorNumber": 1000212,
|
||||||
"partner": { "person": { "tradeName": "Second e.K." } },
|
"partner": { "person": { "tradeName": "Second e.K." } },
|
||||||
"billingContact": { "label": "second contact" },
|
"billingContact": { "label": "second contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -160,13 +163,16 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s",
|
"debitorNumberSuffix": "%s",
|
||||||
|
"billable": "true",
|
||||||
"vatId": "VAT123456",
|
"vatId": "VAT123456",
|
||||||
"vatCountryCode": "DE",
|
"vatCountryCode": "DE",
|
||||||
"vatBusiness": true,
|
"vatBusiness": true,
|
||||||
"refundBankAccountUuid": "%s"
|
"vatReverseCharge": "false",
|
||||||
|
"refundBankAccountUuid": "%s",
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber, givenBankAccount.getUuid()))
|
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorSuffix, givenBankAccount.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -175,6 +181,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("vatId", is("VAT123456"))
|
.body("vatId", is("VAT123456"))
|
||||||
|
.body("defaultPrefix", is("for"))
|
||||||
.body("billingContact.label", is(givenContact.getLabel()))
|
.body("billingContact.label", is(givenContact.getLabel()))
|
||||||
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName()))
|
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName()))
|
||||||
.body("refundBankAccount.holder", is(givenBankAccount.getHolder()))
|
.body("refundBankAccount.holder", is(givenBankAccount.getHolder()))
|
||||||
@ -202,9 +209,12 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s"
|
"debitorNumberSuffix": "%s",
|
||||||
|
"defaultPrefix": "for",
|
||||||
|
"billable": "true",
|
||||||
|
"vatReverseCharge": "false"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber))
|
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorSuffix))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -218,6 +228,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.body("vatCountryCode", equalTo(null))
|
.body("vatCountryCode", equalTo(null))
|
||||||
.body("vatBusiness", equalTo(false))
|
.body("vatBusiness", equalTo(false))
|
||||||
.body("refundBankAccount", equalTo(null))
|
.body("refundBankAccount", equalTo(null))
|
||||||
|
.body("defaultPrefix", equalTo("for"))
|
||||||
.header("Location", startsWith("http://localhost"))
|
.header("Location", startsWith("http://localhost"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
@ -242,12 +253,16 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s",
|
"debitorNumberSuffix": "%s",
|
||||||
|
"billable": "true",
|
||||||
"vatId": "VAT123456",
|
"vatId": "VAT123456",
|
||||||
"vatCountryCode": "DE",
|
"vatCountryCode": "DE",
|
||||||
"vatBusiness": true
|
"vatBusiness": true,
|
||||||
|
"vatReverseCharge": "false",
|
||||||
|
"defaultPrefix": "thi"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorNumber))
|
"""
|
||||||
|
.formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorSuffix))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -272,12 +287,15 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s",
|
"debitorNumberSuffix": "%s",
|
||||||
|
"billable": "true",
|
||||||
"vatId": "VAT123456",
|
"vatId": "VAT123456",
|
||||||
"vatCountryCode": "DE",
|
"vatCountryCode": "DE",
|
||||||
"vatBusiness": true
|
"vatBusiness": true,
|
||||||
|
"vatReverseCharge": "false",
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorNumber))
|
""".formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorSuffix))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -375,7 +393,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"vatId": "VAT222222",
|
"vatId": "VAT222222",
|
||||||
"vatCountryCode": "AA",
|
"vatCountryCode": "AA",
|
||||||
"vatBusiness": true
|
"vatBusiness": true,
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted(givenContact.getUuid()))
|
""".formatted(givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -388,6 +407,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.body("vatId", is("VAT222222"))
|
.body("vatId", is("VAT222222"))
|
||||||
.body("vatCountryCode", is("AA"))
|
.body("vatCountryCode", is("AA"))
|
||||||
.body("vatBusiness", is(true))
|
.body("vatBusiness", is(true))
|
||||||
|
.body("defaultPrefix", is("for"))
|
||||||
.body("billingContact.label", is(givenContact.getLabel()))
|
.body("billingContact.label", is(givenContact.getLabel()))
|
||||||
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName()));
|
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName()));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
@ -522,9 +542,12 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(++nextDebitorNumber)
|
.debitorNumberSuffix(++nextDebitorSuffix)
|
||||||
|
.billable(true)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
|
.defaultPrefix("abc")
|
||||||
|
.vatReverseCharge(false)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
@ -537,7 +560,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var count = em.createQuery(
|
final var count = em.createQuery(
|
||||||
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumber > " + LOWEST_TEMP_DEBITOR_NUMBER)
|
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX)
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
System.out.printf("deleted %d entities%n", count);
|
System.out.printf("deleted %d entities%n", count);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.debitor;
|
package net.hostsharing.hsadminng.hs.office.debitor;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
@ -31,10 +32,20 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
||||||
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
||||||
|
|
||||||
|
private static final String PATCHED_DEFAULT_PREFIX = "xyz";
|
||||||
private static final String PATCHED_VAT_COUNTRY_CODE = "ZZ";
|
private static final String PATCHED_VAT_COUNTRY_CODE = "ZZ";
|
||||||
|
|
||||||
private static final boolean PATCHED_VAT_BUSINESS = false;
|
private static final boolean PATCHED_VAT_BUSINESS = false;
|
||||||
|
|
||||||
|
private static final boolean INITIAL_BILLABLE = false;
|
||||||
|
private static final boolean PATCHED_BILLABLE = true;
|
||||||
|
|
||||||
|
private static final boolean INITIAL_VAT_REVERSE_CHARGE = true;
|
||||||
|
private static final boolean PATCHED_VAT_REVERSE_CHARGE = false;
|
||||||
|
|
||||||
|
private static final UUID INITIAL_REFUND_BANK_ACCOUNT_UUID = UUID.randomUUID();
|
||||||
|
private static final UUID PATCHED_REFUND_BANK_ACCOUNT_UUID = UUID.randomUUID();
|
||||||
|
|
||||||
private final HsOfficePartnerEntity givenInitialPartner = HsOfficePartnerEntity.builder()
|
private final HsOfficePartnerEntity givenInitialPartner = HsOfficePartnerEntity.builder()
|
||||||
.uuid(INITIAL_PARTNER_UUID)
|
.uuid(INITIAL_PARTNER_UUID)
|
||||||
.build();
|
.build();
|
||||||
@ -42,6 +53,10 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
private final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
|
private final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
|
||||||
.uuid(INITIAL_CONTACT_UUID)
|
.uuid(INITIAL_CONTACT_UUID)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
private final HsOfficeBankAccountEntity givenInitialBankAccount = HsOfficeBankAccountEntity.builder()
|
||||||
|
.uuid(INITIAL_REFUND_BANK_ACCOUNT_UUID)
|
||||||
|
.build();
|
||||||
@Mock
|
@Mock
|
||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
|
|
||||||
@ -49,8 +64,8 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
void initMocks() {
|
void initMocks() {
|
||||||
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
|
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
|
||||||
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
|
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
|
lenient().when(em.getReference(eq(HsOfficeBankAccountEntity.class), any())).thenAnswer(invocation ->
|
||||||
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
|
HsOfficeBankAccountEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -59,9 +74,13 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
entity.setUuid(INITIAL_DEBITOR_UUID);
|
entity.setUuid(INITIAL_DEBITOR_UUID);
|
||||||
entity.setPartner(givenInitialPartner);
|
entity.setPartner(givenInitialPartner);
|
||||||
entity.setBillingContact(givenInitialContact);
|
entity.setBillingContact(givenInitialContact);
|
||||||
|
entity.setBillable(INITIAL_BILLABLE);
|
||||||
entity.setVatId("initial VAT-ID");
|
entity.setVatId("initial VAT-ID");
|
||||||
entity.setVatCountryCode("AA");
|
entity.setVatCountryCode("AA");
|
||||||
entity.setVatBusiness(true);
|
entity.setVatBusiness(true);
|
||||||
|
entity.setVatReverseCharge(INITIAL_VAT_REVERSE_CHARGE);
|
||||||
|
entity.setDefaultPrefix("abc");
|
||||||
|
entity.setRefundBankAccount(givenInitialBankAccount);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +104,12 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
HsOfficeDebitorEntity::setBillingContact,
|
HsOfficeDebitorEntity::setBillingContact,
|
||||||
newBillingContact(PATCHED_CONTACT_UUID))
|
newBillingContact(PATCHED_CONTACT_UUID))
|
||||||
.notNullable(),
|
.notNullable(),
|
||||||
|
new SimpleProperty<>(
|
||||||
|
"billable",
|
||||||
|
HsOfficeDebitorPatchResource::setBillable,
|
||||||
|
PATCHED_BILLABLE,
|
||||||
|
HsOfficeDebitorEntity::setBillable)
|
||||||
|
.notNullable(),
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"vatId",
|
"vatId",
|
||||||
HsOfficeDebitorPatchResource::setVatId,
|
HsOfficeDebitorPatchResource::setVatId,
|
||||||
@ -95,11 +120,30 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
HsOfficeDebitorPatchResource::setVatCountryCode,
|
HsOfficeDebitorPatchResource::setVatCountryCode,
|
||||||
PATCHED_VAT_COUNTRY_CODE,
|
PATCHED_VAT_COUNTRY_CODE,
|
||||||
HsOfficeDebitorEntity::setVatCountryCode),
|
HsOfficeDebitorEntity::setVatCountryCode),
|
||||||
new JsonNullableProperty<>(
|
new SimpleProperty<>(
|
||||||
"vatBusiness",
|
"vatBusiness",
|
||||||
HsOfficeDebitorPatchResource::setVatBusiness,
|
HsOfficeDebitorPatchResource::setVatBusiness,
|
||||||
PATCHED_VAT_BUSINESS,
|
PATCHED_VAT_BUSINESS,
|
||||||
HsOfficeDebitorEntity::setVatBusiness)
|
HsOfficeDebitorEntity::setVatBusiness)
|
||||||
|
.notNullable(),
|
||||||
|
new SimpleProperty<>(
|
||||||
|
"vatReverseCharge",
|
||||||
|
HsOfficeDebitorPatchResource::setVatReverseCharge,
|
||||||
|
PATCHED_BILLABLE,
|
||||||
|
HsOfficeDebitorEntity::setVatReverseCharge)
|
||||||
|
.notNullable(),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"defaultPrefix",
|
||||||
|
HsOfficeDebitorPatchResource::setDefaultPrefix,
|
||||||
|
PATCHED_DEFAULT_PREFIX,
|
||||||
|
HsOfficeDebitorEntity::setDefaultPrefix)
|
||||||
|
.notNullable(),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"refundBankAccount",
|
||||||
|
HsOfficeDebitorPatchResource::setRefundBankAccountUuid,
|
||||||
|
PATCHED_REFUND_BANK_ACCOUNT_UUID,
|
||||||
|
HsOfficeDebitorEntity::setRefundBankAccount,
|
||||||
|
newBankAccount(PATCHED_REFUND_BANK_ACCOUNT_UUID))
|
||||||
.notNullable()
|
.notNullable()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -109,4 +153,10 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
newContact.setUuid(uuid);
|
newContact.setUuid(uuid);
|
||||||
return newContact;
|
return newContact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HsOfficeBankAccountEntity newBankAccount(final UUID uuid) {
|
||||||
|
final var newBankAccount = new HsOfficeBankAccountEntity();
|
||||||
|
newBankAccount.setUuid(uuid);
|
||||||
|
return newBankAccount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -13,30 +14,52 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void toStringContainsPartnerAndContact() {
|
void toStringContainsPartnerAndContact() {
|
||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(123456)
|
.debitorNumberSuffix((byte)67)
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerEntity.builder()
|
||||||
.person(HsOfficePersonEntity.builder()
|
.person(HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.LEGAL)
|
||||||
.tradeName("some trade name")
|
.tradeName("some trade name")
|
||||||
.build())
|
.build())
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
|
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
|
||||||
|
.debitorNumberPrefix(12345)
|
||||||
|
.build())
|
||||||
|
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
|
||||||
|
.defaultPrefix("som")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final var result = given.toString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("debitor(1234567: LEGAL some trade name: som)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toStringWithoutPersonContainsDebitorNumber() {
|
||||||
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
|
.debitorNumberSuffix((byte)67)
|
||||||
|
.partner(HsOfficePartnerEntity.builder()
|
||||||
|
.person(null)
|
||||||
|
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
|
||||||
|
.debitorNumberPrefix(12345)
|
||||||
.build())
|
.build())
|
||||||
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
|
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.toString();
|
final var result = given.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("debitor(123456: some trade name)");
|
assertThat(result).isEqualTo("debitor(1234567: <person=null>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsPartnerAndContact() {
|
void toShortStringContainsDebitorNumber() {
|
||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(123456)
|
.partner(HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(12345)
|
||||||
|
.build())
|
||||||
|
.debitorNumberSuffix((byte)67)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.toShortString();
|
final var result = given.toShortString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("123456");
|
assertThat(result).isEqualTo("1234567");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
|||||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||||
import net.hostsharing.test.Array;
|
import net.hostsharing.test.Array;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
@ -20,14 +18,13 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
|||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
|
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
|
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
|
||||||
@ -65,8 +62,6 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
@MockBean
|
@MockBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
Set<HsOfficeDebitorEntity> tempDebitors = new HashSet<>();
|
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class CreateDebitor {
|
class CreateDebitor {
|
||||||
|
|
||||||
@ -81,9 +76,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(20001)
|
.debitorNumberSuffix((byte)21)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
|
.defaultPrefix("abc")
|
||||||
|
.billable(false)
|
||||||
.build();
|
.build();
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
});
|
});
|
||||||
@ -95,14 +92,43 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
assertThat(debitorRepo.count()).isEqualTo(count + 1);
|
assertThat(debitorRepo.count()).isEqualTo(count + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {"", "a", "ab", "a12", "123", "12a"})
|
||||||
|
@Transactional
|
||||||
|
public void canNotCreateNewDebitorWithInvalidDefaultPrefix(final String givenPrefix) {
|
||||||
|
// given
|
||||||
|
context("superuser-alex@hostsharing.net");
|
||||||
|
final var count = debitorRepo.count();
|
||||||
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First GmbH").get(0);
|
||||||
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = attempt(em, () -> {
|
||||||
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
|
.debitorNumberSuffix((byte)21)
|
||||||
|
.partner(givenPartner)
|
||||||
|
.billingContact(givenContact)
|
||||||
|
.billable(true)
|
||||||
|
.vatReverseCharge(false)
|
||||||
|
.vatBusiness(false)
|
||||||
|
.defaultPrefix(givenPrefix)
|
||||||
|
.build();
|
||||||
|
return debitorRepo.save(newDebitor);
|
||||||
|
});
|
||||||
|
|
||||||
|
// then
|
||||||
|
result.assertExceptionWithRootCauseMessage(org.hibernate.exception.ConstraintViolationException.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createsAndGrantsRoles() {
|
public void createsAndGrantsRoles() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
|
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
|
||||||
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll()).stream()
|
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll()).stream()
|
||||||
|
// some search+replace to make the output fit into the screen width
|
||||||
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
||||||
.map(s -> s.replace("20002Fourthe.G.-forthcontact", "FeG"))
|
.map(s -> s.replace("22Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("forthcontact", "4th"))
|
.map(s -> s.replace("forthcontact", "4th"))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
@ -113,9 +139,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(20002)
|
.debitorNumberSuffix((byte)22)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
|
.defaultPrefix("abc")
|
||||||
|
.billable(false)
|
||||||
.build();
|
.build();
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
@ -123,42 +151,42 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.owner",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.owner",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.admin",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.admin",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.agent",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.agent",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.tenant",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.tenant",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.guest"));
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.guest"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
||||||
.map(s -> s.replace("20002Fourthe.G.-forthcontact", "FeG"))
|
.map(s -> s.replace("22Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("forthcontact", "4th"))
|
.map(s -> s.replace("forthcontact", "4th"))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on debitor#FeG to role debitor#FeG.owner by system and assume }",
|
"{ grant perm * on debitor#1000422:FeG to role debitor#1000422:FeG.owner by system and assume }",
|
||||||
"{ grant role debitor#FeG.owner to role global#global.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.owner to role global#global.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.owner to user superuser-alex by global#global.admin and assume }",
|
"{ grant role debitor#1000422:FeG.owner to user superuser-alex by global#global.admin and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on debitor#FeG to role debitor#FeG.admin by system and assume }",
|
"{ grant perm edit on debitor#1000422:FeG to role debitor#1000422:FeG.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.admin to role debitor#FeG.owner by system and assume }",
|
"{ grant role debitor#1000422:FeG.admin to role debitor#1000422:FeG.owner by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role debitor#FeG.agent to role debitor#FeG.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.agent to role debitor#1000422:FeG.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.agent to role contact#4th.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.agent to role contact#4th.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.agent to role partner#FeG.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.agent to role partner#10004:FeG.admin by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role contact#4th.guest to role debitor#FeG.tenant by system and assume }",
|
"{ grant role contact#4th.guest to role debitor#1000422:FeG.tenant by system and assume }",
|
||||||
"{ grant role debitor#FeG.tenant to role debitor#FeG.agent by system and assume }",
|
"{ grant role debitor#1000422:FeG.tenant to role debitor#1000422:FeG.agent by system and assume }",
|
||||||
"{ grant role debitor#FeG.tenant to role partner#FeG.agent by system and assume }",
|
"{ grant role debitor#1000422:FeG.tenant to role partner#10004:FeG.agent by system and assume }",
|
||||||
"{ grant role partner#FeG.tenant to role debitor#FeG.tenant by system and assume }",
|
"{ grant role partner#10004:FeG.tenant to role debitor#1000422:FeG.tenant by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on debitor#FeG to role debitor#FeG.guest by system and assume }",
|
"{ grant perm view on debitor#1000422:FeG to role debitor#1000422:FeG.guest by system and assume }",
|
||||||
"{ grant role debitor#FeG.guest to role debitor#FeG.tenant by system and assume }",
|
"{ grant role debitor#1000422:FeG.guest to role debitor#1000422:FeG.tenant by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -183,14 +211,14 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
allTheseDebitorsAreReturned(
|
allTheseDebitorsAreReturned(
|
||||||
result,
|
result,
|
||||||
"debitor(10001: First GmbH)",
|
"debitor(1000111: LEGAL First GmbH: fir)",
|
||||||
"debitor(10002: Second e.K.)",
|
"debitor(1000212: LEGAL Second e.K.: sec)",
|
||||||
"debitor(10003: Third OHG)");
|
"debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {
|
@ValueSource(strings = {
|
||||||
"hs_office_partner#FirstGmbH-firstcontact.admin",
|
"hs_office_partner#10001:FirstGmbH-firstcontact.admin",
|
||||||
"hs_office_person#FirstGmbH.admin",
|
"hs_office_person#FirstGmbH.admin",
|
||||||
"hs_office_contact#firstcontact.admin",
|
"hs_office_contact#firstcontact.admin",
|
||||||
})
|
})
|
||||||
@ -202,7 +230,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
|
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseDebitorsAreReturned(result, "debitor(10001: First GmbH)");
|
exactlyTheseDebitorsAreReturned(result,
|
||||||
|
"debitor(1000111: LEGAL First GmbH: fir)",
|
||||||
|
"debitor(1000120: LEGAL First GmbH: fif)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -227,10 +257,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = debitorRepo.findDebitorByDebitorNumber(10003);
|
final var result = debitorRepo.findDebitorByDebitorNumber(1000313);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
|
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +276,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
|
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
|
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +287,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canUpdateArbitraryDebitor() {
|
public void globalAdmin_canUpdateArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fif");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
final var givenNewPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0);
|
final var givenNewPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0);
|
||||||
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
|
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
|
||||||
@ -290,10 +320,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// ... partner role was reassigned:
|
// ... partner role was reassigned:
|
||||||
assertThatDebitorIsNotVisibleForUserWithRole(
|
assertThatDebitorIsNotVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.agent");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.agent");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office_partner#FirstGmbH-firstcontact.agent");
|
"hs_office_partner#10001:FirstGmbH-firstcontact.agent");
|
||||||
|
|
||||||
// ... contact role was reassigned:
|
// ... contact role was reassigned:
|
||||||
assertThatDebitorIsNotVisibleForUserWithRole(
|
assertThatDebitorIsNotVisibleForUserWithRole(
|
||||||
@ -316,10 +346,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canUpdateNullRefundBankAccountToNotNullBankAccountForArbitraryDebitor() {
|
public void globalAdmin_canUpdateNullRefundBankAccountToNotNullBankAccountForArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null);
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fig");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0);
|
final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0);
|
||||||
|
|
||||||
@ -346,10 +376,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canUpdateRefundBankAccountToNullForArbitraryDebitor() {
|
public void globalAdmin_canUpdateRefundBankAccountToNullForArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fih");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -375,15 +405,15 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void partnerAdmin_canNotUpdateRelatedDebitor() {
|
public void partnerAdmin_canNotUpdateRelatedDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#Fourthe.G.-forthcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
givenDebitor.setVatId("NEW-VAT-ID");
|
givenDebitor.setVatId("NEW-VAT-ID");
|
||||||
return debitorRepo.save(givenDebitor);
|
return debitorRepo.save(givenDebitor);
|
||||||
});
|
});
|
||||||
@ -397,7 +427,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void contactAdmin_canNotUpdateRelatedDebitor() {
|
public void contactAdmin_canNotUpdateRelatedDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth", "nin");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_contact#ninthcontact.admin");
|
"hs_office_contact#ninthcontact.admin");
|
||||||
@ -448,7 +478,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canDeleteAnyDebitor() {
|
public void globalAdmin_canDeleteAnyDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth", "Fourth", "ten");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -468,7 +498,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void relatedPerson_canNotDeleteTheirRelatedDebitor() {
|
public void relatedPerson_canNotDeleteTheirRelatedDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth", "ele");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -494,7 +524,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
||||||
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth", "Fourth", "twe");
|
||||||
assertThat(rawRoleRepo.findAll().size()).as("precondition failed: unexpected number of roles created")
|
assertThat(rawRoleRepo.findAll().size()).as("precondition failed: unexpected number of roles created")
|
||||||
.isEqualTo(initialRoleNames.length + 5);
|
.isEqualTo(initialRoleNames.length + 5);
|
||||||
assertThat(rawGrantRepo.findAll().size()).as("precondition failed: unexpected number of grants created")
|
assertThat(rawGrantRepo.findAll().size()).as("precondition failed: unexpected number of grants created")
|
||||||
@ -536,7 +566,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
private HsOfficeDebitorEntity givenSomeTemporaryDebitor(
|
private HsOfficeDebitorEntity givenSomeTemporaryDebitor(
|
||||||
final String partner,
|
final String partner,
|
||||||
final String contact,
|
final String contact,
|
||||||
final String bankAccount) {
|
final String bankAccount,
|
||||||
|
final String defaultPrefix) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0);
|
||||||
@ -544,23 +575,18 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenBankAccount =
|
final var givenBankAccount =
|
||||||
bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null;
|
bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null;
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(20000)
|
.debitorNumberSuffix((byte)20)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
.refundBankAccount(givenBankAccount)
|
.refundBankAccount(givenBankAccount)
|
||||||
|
.defaultPrefix(defaultPrefix)
|
||||||
|
.billable(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@AfterEach
|
|
||||||
void cleanup() {
|
|
||||||
context("superuser-alex@hostsharing.net");
|
|
||||||
em.createQuery("DELETE FROM HsOfficeDebitorEntity d where d.debitorNumber >= 20000").executeUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void exactlyTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
|
void exactlyTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(HsOfficeDebitorEntity::toString)
|
.extracting(HsOfficeDebitorEntity::toString)
|
||||||
|
@ -9,8 +9,10 @@ import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TE
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class TestHsOfficeDebitor {
|
public class TestHsOfficeDebitor {
|
||||||
|
|
||||||
|
public byte DEFAULT_DEBITOR_SUFFIX = 0;
|
||||||
|
|
||||||
public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder()
|
public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(10001)
|
.debitorNumberSuffix(DEFAULT_DEBITOR_SUFFIX)
|
||||||
.partner(TEST_PARTNER)
|
.partner(TEST_PARTNER)
|
||||||
.billingContact(TEST_CONTACT)
|
.billingContact(TEST_CONTACT)
|
||||||
.build();
|
.build();
|
||||||
|
@ -83,7 +83,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "First GmbH" } },
|
"partner": { "person": { "tradeName": "First GmbH" } },
|
||||||
"mainDebitor": { "debitorNumber": 10001 },
|
"mainDebitor": { "debitorNumber": 1000111 },
|
||||||
"memberNumber": 10001,
|
"memberNumber": 10001,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -91,7 +91,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "Second e.K." } },
|
"partner": { "person": { "tradeName": "Second e.K." } },
|
||||||
"mainDebitor": { "debitorNumber": 10002 },
|
"mainDebitor": { "debitorNumber": 1000212 },
|
||||||
"memberNumber": 10002,
|
"memberNumber": 10002,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -99,7 +99,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "Third OHG" } },
|
"partner": { "person": { "tradeName": "Third OHG" } },
|
||||||
"mainDebitor": { "debitorNumber": 10003 },
|
"mainDebitor": { "debitorNumber": 1000313 },
|
||||||
"memberNumber": 10003,
|
"memberNumber": 10003,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -131,7 +131,8 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"mainDebitorUuid": "%s",
|
"mainDebitorUuid": "%s",
|
||||||
"memberNumber": 20001,
|
"memberNumber": 20001,
|
||||||
"validFrom": "2022-10-13"
|
"validFrom": "2022-10-13",
|
||||||
|
"membershipFeeBillable": "true"
|
||||||
}
|
}
|
||||||
""".formatted(givenPartner.getUuid(), givenDebitor.getUuid()))
|
""".formatted(givenPartner.getUuid(), givenDebitor.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -142,6 +143,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumber()))
|
.body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumber()))
|
||||||
|
.body("mainDebitor.debitorNumberSuffix", is((int) givenDebitor.getDebitorNumberSuffix()))
|
||||||
.body("partner.person.tradeName", is("Third OHG"))
|
.body("partner.person.tradeName", is("Third OHG"))
|
||||||
.body("memberNumber", is(20001))
|
.body("memberNumber", is(20001))
|
||||||
.body("validFrom", is("2022-10-13"))
|
.body("validFrom", is("2022-10-13"))
|
||||||
@ -182,7 +184,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "First GmbH" } },
|
"partner": { "person": { "tradeName": "First GmbH" } },
|
||||||
"mainDebitor": { "debitorNumber": 10001 },
|
"mainDebitor": { "debitorNumber": 1000111 },
|
||||||
"memberNumber": 10001,
|
"memberNumber": 10001,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -224,7 +226,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.header("assumed-roles", "hs_office_debitor#10003ThirdOHG-thirdcontact.agent")
|
.header("assumed-roles", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.agent")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
||||||
@ -235,7 +237,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "Third OHG" } },
|
"partner": { "person": { "tradeName": "Third OHG" } },
|
||||||
"mainDebitor": {
|
"mainDebitor": {
|
||||||
"debitorNumber": 10003,
|
"debitorNumber": 1000313,
|
||||||
"billingContact": { "label": "third contact" }
|
"billingContact": { "label": "third contact" }
|
||||||
},
|
},
|
||||||
"memberNumber": 10003,
|
"memberNumber": 10003,
|
||||||
@ -276,6 +278,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
||||||
.body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber()))
|
.body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber()))
|
||||||
|
.body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix()))
|
||||||
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
||||||
.body("validFrom", is("2022-11-01"))
|
.body("validFrom", is("2022-11-01"))
|
||||||
.body("validTo", is("2023-12-31"))
|
.body("validTo", is("2023-12-31"))
|
||||||
@ -285,7 +288,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
// finally, the Membership is actually updated
|
// finally, the Membership is actually updated
|
||||||
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
|
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getPartner().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
|
||||||
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
|
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
|
||||||
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
|
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
|
||||||
@ -299,7 +302,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
||||||
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(10003).get(0);
|
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(1000313).get(0);
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -318,7 +321,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
||||||
.body("mainDebitor.debitorNumber", is(10003))
|
.body("mainDebitor.debitorNumber", is(1000313))
|
||||||
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
||||||
.body("validFrom", is("2022-11-01"))
|
.body("validFrom", is("2022-11-01"))
|
||||||
.body("validTo", nullValue())
|
.body("validTo", nullValue())
|
||||||
@ -328,7 +331,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
// finally, the Membership is actually updated
|
// finally, the Membership is actually updated
|
||||||
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
|
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getPartner().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
|
||||||
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
|
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
|
||||||
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
|
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");
|
||||||
@ -340,13 +343,13 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
@Test
|
@Test
|
||||||
void partnerAgent_canViewButNotPatchValidityOfRelatedMembership() {
|
void partnerAgent_canViewButNotPatchValidityOfRelatedMembership() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.agent");
|
context.define("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.agent");
|
||||||
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.header("assumed-roles", "hs_office_partner#FirstGmbH-firstcontact.agent")
|
.header("assumed-roles", "hs_office_partner#10001:FirstGmbH-firstcontact.agent")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@ -444,6 +447,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.memberNumber(++tempMemberNumber)
|
.memberNumber(++tempMemberNumber)
|
||||||
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
||||||
.reasonForTermination(NONE)
|
.reasonForTermination(NONE)
|
||||||
|
.membershipFeeBillable(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return membershipRepo.save(newMembership);
|
return membershipRepo.save(newMembership);
|
||||||
|
@ -72,7 +72,8 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
"partnerUuid": null,
|
"partnerUuid": null,
|
||||||
"mainDebitorUuid": "%s",
|
"mainDebitorUuid": "%s",
|
||||||
"memberNumber": 20001,
|
"memberNumber": 20001,
|
||||||
"validFrom": "2022-10-13"
|
"validFrom": "2022-10-13",
|
||||||
|
"membershipFeeBillable": "true"
|
||||||
}
|
}
|
||||||
""".formatted(UUID.randomUUID()))
|
""".formatted(UUID.randomUUID()))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
@ -97,7 +98,8 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"mainDebitorUuid": null,
|
"mainDebitorUuid": null,
|
||||||
"memberNumber": 20001,
|
"memberNumber": 20001,
|
||||||
"validFrom": "2022-10-13"
|
"validFrom": "2022-10-13",
|
||||||
|
"membershipFeeBillable": "true"
|
||||||
}
|
}
|
||||||
""".formatted(UUID.randomUUID()))
|
""".formatted(UUID.randomUUID()))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
@ -128,7 +130,8 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"mainDebitorUuid": "%s",
|
"mainDebitorUuid": "%s",
|
||||||
"memberNumber": 20001,
|
"memberNumber": 20001,
|
||||||
"validFrom": "2022-10-13"
|
"validFrom": "2022-10-13",
|
||||||
|
"membershipFeeBillable": "true"
|
||||||
}
|
}
|
||||||
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
|
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
@ -159,7 +162,8 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"mainDebitorUuid": "%s",
|
"mainDebitorUuid": "%s",
|
||||||
"memberNumber": 20001,
|
"memberNumber": 20001,
|
||||||
"validFrom": "2022-10-13"
|
"validFrom": "2022-10-13",
|
||||||
|
"membershipFeeBillable": "true"
|
||||||
}
|
}
|
||||||
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
|
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
@ -36,6 +36,9 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
private static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-04-15");
|
private static final LocalDate GIVEN_VALID_FROM = LocalDate.parse("2020-04-15");
|
||||||
private static final LocalDate PATCHED_VALID_TO = LocalDate.parse("2022-12-31");
|
private static final LocalDate PATCHED_VALID_TO = LocalDate.parse("2022-12-31");
|
||||||
|
|
||||||
|
private static final Boolean GIVEN_MEMBERSHIP_FEE_BILLABLE = true;
|
||||||
|
private static final Boolean PATCHED_MEMBERSHIP_FEE_BILLABLE = false;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
|
|
||||||
@ -56,6 +59,7 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
entity.setMainDebitor(TEST_DEBITOR);
|
entity.setMainDebitor(TEST_DEBITOR);
|
||||||
entity.setPartner(TEST_PARTNER);
|
entity.setPartner(TEST_PARTNER);
|
||||||
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
|
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
|
||||||
|
entity.setMembershipFeeBillable(GIVEN_MEMBERSHIP_FEE_BILLABLE);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +94,12 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
HsOfficeReasonForTerminationResource.CANCELLATION,
|
HsOfficeReasonForTerminationResource.CANCELLATION,
|
||||||
HsOfficeMembershipEntity::setReasonForTermination,
|
HsOfficeMembershipEntity::setReasonForTermination,
|
||||||
HsOfficeReasonForTermination.CANCELLATION)
|
HsOfficeReasonForTermination.CANCELLATION)
|
||||||
.notNullable()
|
.notNullable(),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"membershipFeeBillable",
|
||||||
|
HsOfficeMembershipPatchResource::setMembershipFeeBillable,
|
||||||
|
PATCHED_MEMBERSHIP_FEE_BILLABLE,
|
||||||
|
HsOfficeMembershipEntity::setMembershipFeeBillable)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,10 +108,4 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
newDebitor.setUuid(uuid);
|
newDebitor.setUuid(uuid);
|
||||||
return newDebitor;
|
return newDebitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficeMembershipEntity newMembership(final UUID uuid) {
|
|
||||||
final var newMembership = new HsOfficeMembershipEntity();
|
|
||||||
newMembership.setUuid(uuid);
|
|
||||||
return newMembership;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class HsOfficeMembershipEntityUnitTest {
|
|||||||
void toStringContainsAllProps() {
|
void toStringContainsAllProps() {
|
||||||
final var result = givenMembership.toString();
|
final var result = givenMembership.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("Membership(10001, Test Ltd., 10001, [2020-01-01,))");
|
assertThat(result).isEqualTo("Membership(10001, LEGAL Test Ltd., 1000100, [2020-01-01,))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -81,6 +81,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.mainDebitor(givenDebitor)
|
.mainDebitor(givenDebitor)
|
||||||
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
|
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
|
||||||
|
.membershipFeeBillable(true)
|
||||||
.build());
|
.build());
|
||||||
return membershipRepo.save(newMembership);
|
return membershipRepo.save(newMembership);
|
||||||
});
|
});
|
||||||
@ -111,6 +112,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.mainDebitor(givenDebitor)
|
.mainDebitor(givenDebitor)
|
||||||
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
|
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
|
||||||
|
.membershipFeeBillable(true)
|
||||||
.build());
|
.build());
|
||||||
return membershipRepo.save(newMembership);
|
return membershipRepo.save(newMembership);
|
||||||
});
|
});
|
||||||
@ -119,11 +121,11 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var all = rawRoleRepo.findAll();
|
final var all = rawRoleRepo.findAll();
|
||||||
assertThat(roleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.admin",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.admin",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.agent",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.agent",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.guest",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.guest",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.owner",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.owner",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.tenant"));
|
"hs_office_membership#20002:FirstGmbH-firstcontact.tenant"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("GmbH-firstcontact", ""))
|
.map(s -> s.replace("GmbH-firstcontact", ""))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
@ -131,32 +133,33 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on membership#20002First to role membership#20002First.owner by system and assume }",
|
"{ grant perm * on membership#20002:First to role membership#20002:First.owner by system and assume }",
|
||||||
"{ grant role membership#20002First.owner to role global#global.admin by system and assume }",
|
"{ grant role membership#20002:First.owner to role global#global.admin by system and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on membership#20002First to role membership#20002First.admin by system and assume }",
|
"{ grant perm edit on membership#20002:First to role membership#20002:First.admin by system and assume }",
|
||||||
"{ grant role membership#20002First.admin to role membership#20002First.owner by system and assume }",
|
"{ grant role membership#20002:First.admin to role membership#20002:First.owner by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role membership#20002First.agent to role membership#20002First.admin by system and assume }",
|
"{ grant role membership#20002:First.agent to role membership#20002:First.admin by system and assume }",
|
||||||
"{ grant role partner#First.tenant to role membership#20002First.agent by system and assume }",
|
"{ grant role partner#10001:First.tenant to role membership#20002:First.agent by system and assume }",
|
||||||
"{ grant role membership#20002First.agent to role debitor#10001First.admin by system and assume }",
|
"{ grant role membership#20002:First.agent to role debitor#1000111:First.admin by system and assume }",
|
||||||
"{ grant role membership#20002First.agent to role partner#First.admin by system and assume }",
|
"{ grant role membership#20002:First.agent to role partner#10001:First.admin by system and assume }",
|
||||||
"{ grant role debitor#10001First.tenant to role membership#20002First.agent by system and assume }",
|
"{ grant role debitor#1000111:First.tenant to role membership#20002:First.agent by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role membership#20002First.tenant to role membership#20002First.agent by system and assume }",
|
"{ grant role membership#20002:First.tenant to role membership#20002:First.agent by system and assume }",
|
||||||
"{ grant role partner#First.guest to role membership#20002First.tenant by system and assume }",
|
"{ grant role partner#10001:First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
"{ grant role debitor#10001First.guest to role membership#20002First.tenant by system and assume }",
|
"{ grant role debitor#1000111:First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
"{ grant role membership#20002First.tenant to role debitor#10001First.agent by system and assume }",
|
"{ grant role membership#20002:First.tenant to role debitor#1000111:First.agent by system and assume }",
|
||||||
"{ grant role membership#20002First.tenant to role partner#First.agent by system and assume }",
|
|
||||||
|
"{ grant role membership#20002:First.tenant to role partner#10001:First.agent by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on membership#20002First to role membership#20002First.guest by system and assume }",
|
"{ grant perm view on membership#20002:First to role membership#20002:First.guest by system and assume }",
|
||||||
"{ grant role membership#20002First.guest to role membership#20002First.tenant by system and assume }",
|
"{ grant role membership#20002:First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
"{ grant role membership#20002First.guest to role partner#First.tenant by system and assume }",
|
"{ grant role membership#20002:First.guest to role partner#10001:First.tenant by system and assume }",
|
||||||
"{ grant role membership#20002First.guest to role debitor#10001First.tenant by system and assume }",
|
"{ grant role membership#20002:First.guest to role debitor#1000111:First.tenant by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -181,9 +184,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(
|
exactlyTheseMembershipsAreReturned(
|
||||||
result,
|
result,
|
||||||
"Membership(10001, First GmbH, 10001, [2022-10-01,), NONE)",
|
"Membership(10001, LEGAL First GmbH, 1000111, [2022-10-01,), NONE)",
|
||||||
"Membership(10002, Second e.K., 10002, [2022-10-01,), NONE)",
|
"Membership(10002, LEGAL Second e.K., 1000212, [2022-10-01,), NONE)",
|
||||||
"Membership(10003, Third OHG, 10003, [2022-10-01,), NONE)");
|
"Membership(10003, SOLE_REPRESENTATION Third OHG, 1000313, [2022-10-01,), NONE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -198,7 +201,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
null);
|
null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(result, "Membership(10001, First GmbH, 10001, [2022-10-01,), NONE)");
|
exactlyTheseMembershipsAreReturned(result, "Membership(10001, LEGAL First GmbH, 1000111, [2022-10-01,), NONE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -210,7 +213,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002);
|
final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(result, "Membership(10002, Second e.K., 10002, [2022-10-01,), NONE)");
|
exactlyTheseMembershipsAreReturned(result, "Membership(10002, LEGAL Second e.K., 1000212, [2022-10-01,), NONE)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +227,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
||||||
assertThatMembershipIsVisibleForUserWithRole(
|
assertThatMembershipIsVisibleForUserWithRole(
|
||||||
givenMembership,
|
givenMembership,
|
||||||
"hs_office_debitor#10001FirstGmbH-firstcontact.admin");
|
"hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
|
||||||
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
||||||
final var newValidityEnd = LocalDate.now();
|
final var newValidityEnd = LocalDate.now();
|
||||||
|
|
||||||
@ -251,13 +254,13 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
||||||
assertThatMembershipIsVisibleForUserWithRole(
|
assertThatMembershipIsVisibleForUserWithRole(
|
||||||
givenMembership,
|
givenMembership,
|
||||||
"hs_office_debitor#10001FirstGmbH-firstcontact.admin");
|
"hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
|
||||||
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
||||||
final var newValidityEnd = LocalDate.now();
|
final var newValidityEnd = LocalDate.now();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_debitor#10001FirstGmbH-firstcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
|
||||||
givenMembership.setValidity(Range.closedOpen(
|
givenMembership.setValidity(Range.closedOpen(
|
||||||
givenMembership.getValidity().lower(), newValidityEnd));
|
givenMembership.getValidity().lower(), newValidityEnd));
|
||||||
return membershipRepo.save(givenMembership);
|
return membershipRepo.save(givenMembership);
|
||||||
@ -325,7 +328,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_debitor#10003ThirdOHG-thirdcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.admin");
|
||||||
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
|
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
|
||||||
|
|
||||||
membershipRepo.deleteByUuid(givenMembership.getUuid());
|
membershipRepo.deleteByUuid(givenMembership.getUuid());
|
||||||
@ -382,8 +385,8 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
||||||
"[creating Membership test-data FirstGmbH10001, hs_office_membership, INSERT]",
|
"[creating Membership test-data FirstGmbH11, hs_office_membership, INSERT]",
|
||||||
"[creating Membership test-data Seconde.K.10002, hs_office_membership, INSERT]");
|
"[creating Membership test-data Seconde.K.12, hs_office_membership, INSERT]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@ -412,6 +415,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.mainDebitor(givenDebitor)
|
.mainDebitor(givenDebitor)
|
||||||
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
|
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
|
||||||
|
.membershipFeeBillable(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
toCleanup(newMembership);
|
toCleanup(newMembership);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -125,6 +125,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
|
"debitorNumberPrefix": "12345",
|
||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
"details": {
|
"details": {
|
||||||
@ -166,6 +167,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
|
"debitorNumberPrefix": "12345",
|
||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
"details": {}
|
"details": {}
|
||||||
@ -193,6 +195,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
|
"debitorNumberPrefix": "12345",
|
||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
"details": {}
|
"details": {}
|
||||||
@ -294,6 +297,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
|
"debitorNumberPrefix": "12345",
|
||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
"details": {
|
"details": {
|
||||||
|
@ -28,8 +28,9 @@ class HsOfficePartnerDetailsEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
> {
|
> {
|
||||||
|
|
||||||
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
|
||||||
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
|
||||||
private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID();
|
private static final String INITIAL_BIRTHPLACE = null;
|
||||||
|
private static final String PATCHED_BIRTHPLACE = "Essen (Ruhr)";
|
||||||
|
|
||||||
private static final LocalDate INITIAL_BIRTHDAY = LocalDate.parse("1900-01-01");
|
private static final LocalDate INITIAL_BIRTHDAY = LocalDate.parse("1900-01-01");
|
||||||
private static final LocalDate PATCHED_BIRTHDAY = LocalDate.parse("1990-12-31");
|
private static final LocalDate PATCHED_BIRTHDAY = LocalDate.parse("1990-12-31");
|
||||||
@ -54,6 +55,7 @@ class HsOfficePartnerDetailsEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
entity.setUuid(INITIAL_PARTNER_UUID);
|
entity.setUuid(INITIAL_PARTNER_UUID);
|
||||||
entity.setRegistrationOffice("initial Reg-Office");
|
entity.setRegistrationOffice("initial Reg-Office");
|
||||||
entity.setRegistrationNumber("initial Reg-Number");
|
entity.setRegistrationNumber("initial Reg-Number");
|
||||||
|
entity.setBirthPlace(INITIAL_BIRTHPLACE);
|
||||||
entity.setBirthday(INITIAL_BIRTHDAY);
|
entity.setBirthday(INITIAL_BIRTHDAY);
|
||||||
entity.setBirthName("initial birth name");
|
entity.setBirthName("initial birth name");
|
||||||
entity.setDateOfDeath(INITIAL_DAY_OF_DEATH);
|
entity.setDateOfDeath(INITIAL_DAY_OF_DEATH);
|
||||||
@ -78,6 +80,16 @@ class HsOfficePartnerDetailsEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
HsOfficePartnerDetailsPatchResource::setRegistrationOffice,
|
HsOfficePartnerDetailsPatchResource::setRegistrationOffice,
|
||||||
"patched Reg-Office",
|
"patched Reg-Office",
|
||||||
HsOfficePartnerDetailsEntity::setRegistrationOffice),
|
HsOfficePartnerDetailsEntity::setRegistrationOffice),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"birthplace",
|
||||||
|
HsOfficePartnerDetailsPatchResource::setBirthPlace,
|
||||||
|
PATCHED_BIRTHPLACE,
|
||||||
|
HsOfficePartnerDetailsEntity::setBirthPlace),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"birthname",
|
||||||
|
HsOfficePartnerDetailsPatchResource::setBirthName,
|
||||||
|
"patched birth name",
|
||||||
|
HsOfficePartnerDetailsEntity::setBirthName),
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"birthday",
|
"birthday",
|
||||||
HsOfficePartnerDetailsPatchResource::setBirthday,
|
HsOfficePartnerDetailsPatchResource::setBirthday,
|
||||||
|
@ -21,7 +21,8 @@ class HsOfficePartnerDetailsEntityUnitTest {
|
|||||||
|
|
||||||
final var result = given.toString();
|
final var result = given.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("partnerDetails(Hamburg, 12345, 2002-01-15, 2002-01-15, 2081-12-21)");
|
assertThat(result).isEqualTo(
|
||||||
|
"partnerDetails(Hamburg, 12345, 2002-01-15, Melly Miller, 2081-12-21)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -11,24 +12,30 @@ class HsOfficePartnerEntityUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void toStringContainsPersonAndContact() {
|
void toStringContainsPersonAndContact() {
|
||||||
final var given = HsOfficePartnerEntity.builder()
|
final var given = HsOfficePartnerEntity.builder()
|
||||||
.person(HsOfficePersonEntity.builder().tradeName("some trade name").build())
|
.person(HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.LEGAL)
|
||||||
|
.tradeName("some trade name")
|
||||||
|
.build())
|
||||||
.contact(HsOfficeContactEntity.builder().label("some label").build())
|
.contact(HsOfficeContactEntity.builder().label("some label").build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.toString();
|
final var result = given.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("partner(some trade name: some label)");
|
assertThat(result).isEqualTo("partner(LEGAL some trade name: some label)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsPersonAndContact() {
|
void toShortStringContainsPersonAndContact() {
|
||||||
final var given = HsOfficePartnerEntity.builder()
|
final var given = HsOfficePartnerEntity.builder()
|
||||||
.person(HsOfficePersonEntity.builder().tradeName("some trade name").build())
|
.person(HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.LEGAL)
|
||||||
|
.tradeName("some trade name")
|
||||||
|
.build())
|
||||||
.contact(HsOfficeContactEntity.builder().label("some label").build())
|
.contact(HsOfficeContactEntity.builder().label("some label").build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.toShortString();
|
final var result = given.toShortString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("some trade name");
|
assertThat(result).isEqualTo("LEGAL some trade name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||||
final var newPartner = toCleanup(HsOfficePartnerEntity.builder()
|
final var newPartner = toCleanup(HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(22222)
|
||||||
.person(givenPerson)
|
.person(givenPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
@ -115,11 +116,11 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.admin",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.admin",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.agent",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.agent",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.owner",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.owner",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.tenant",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.tenant",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.guest"));
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.guest"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("ErbenBesslerMelBessler", "EBess"))
|
.map(s -> s.replace("ErbenBesslerMelBessler", "EBess"))
|
||||||
.map(s -> s.replace("forthcontact", "4th"))
|
.map(s -> s.replace("forthcontact", "4th"))
|
||||||
@ -127,31 +128,31 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on partner#EBess-4th to role partner#EBess-4th.owner by system and assume }",
|
"{ grant perm * on partner#22222:EBess-4th to role partner#22222:EBess-4th.owner by system and assume }",
|
||||||
"{ grant perm * on partner_details#EBess-4th-details to role partner#EBess-4th.owner by system and assume }",
|
"{ grant perm * on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.owner by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.owner to role global#global.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.owner to role global#global.admin by system and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on partner#EBess-4th to role partner#EBess-4th.admin by system and assume }",
|
"{ grant perm edit on partner#22222:EBess-4th to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant perm edit on partner_details#EBess-4th-details to role partner#EBess-4th.admin by system and assume }",
|
"{ grant perm edit on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.admin to role partner#EBess-4th.owner by system and assume }",
|
"{ grant role partner#22222:EBess-4th.admin to role partner#22222:EBess-4th.owner by system and assume }",
|
||||||
"{ grant role person#EBess.tenant to role partner#EBess-4th.admin by system and assume }",
|
"{ grant role person#EBess.tenant to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role contact#4th.tenant to role partner#EBess-4th.admin by system and assume }",
|
"{ grant role contact#4th.tenant to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant perm view on partner_details#EBess-4th-details to role partner#EBess-4th.agent by system and assume }",
|
"{ grant perm view on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.agent by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.agent to role partner#EBess-4th.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.agent to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.agent to role person#EBess.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.agent to role person#EBess.admin by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.agent to role contact#4th.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.agent to role contact#4th.admin by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role partner#EBess-4th.tenant to role partner#EBess-4th.agent by system and assume }",
|
"{ grant role partner#22222:EBess-4th.tenant to role partner#22222:EBess-4th.agent by system and assume }",
|
||||||
"{ grant role person#EBess.guest to role partner#EBess-4th.tenant by system and assume }",
|
"{ grant role person#EBess.guest to role partner#22222:EBess-4th.tenant by system and assume }",
|
||||||
"{ grant role contact#4th.guest to role partner#EBess-4th.tenant by system and assume }",
|
"{ grant role contact#4th.guest to role partner#22222:EBess-4th.tenant by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on partner#EBess-4th to role partner#EBess-4th.guest by system and assume }",
|
"{ grant perm view on partner#22222:EBess-4th to role partner#22222:EBess-4th.guest by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.guest to role partner#EBess-4th.tenant by system and assume }",
|
"{ grant role partner#22222:EBess-4th.guest to role partner#22222:EBess-4th.tenant by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -176,9 +177,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
allThesePartnersAreReturned(
|
allThesePartnersAreReturned(
|
||||||
result,
|
result,
|
||||||
"partner(Third OHG: third contact)",
|
"partner(SOLE_REPRESENTATION Third OHG: third contact)",
|
||||||
"partner(Second e.K.: second contact)",
|
"partner(LEGAL Second e.K.: second contact)",
|
||||||
"partner(First GmbH: first contact)");
|
"partner(LEGAL First GmbH: first contact)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -190,7 +191,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyThesePartnersAreReturned(result, "partner(First GmbH: first contact)");
|
exactlyThesePartnersAreReturned(result, "partner(LEGAL First GmbH: first contact)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
|
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyThesePartnersAreReturned(result, "partner(Third OHG: third contact)");
|
exactlyThesePartnersAreReturned(result, "partner(SOLE_REPRESENTATION Third OHG: third contact)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,10 +218,10 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryPartner() {
|
public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("fifth contact");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "fifth contact");
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office_person#ErbenBesslerMelBessler.admin");
|
"hs_office_partner#22222:ErbenBesslerMelBessler-fifthcontact.admin");
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0);
|
final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0);
|
||||||
@ -253,16 +254,16 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void partnerAgent_canNotUpdateRelatedPartner() {
|
public void partnerAgent_canNotUpdateRelatedPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("ninth");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "ninth");
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-ninthcontact.agent");
|
"hs_office_partner#22222:ErbenBesslerMelBessler-ninthcontact.agent");
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("tenth").get(0);
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#ErbenBesslerMelBessler-ninthcontact.agent");
|
context("superuser-alex@hostsharing.net",
|
||||||
|
"hs_office_partner#22222:ErbenBesslerMelBessler-ninthcontact.agent");
|
||||||
givenPartner.getDetails().setBirthName("new birthname");
|
givenPartner.getDetails().setBirthName("new birthname");
|
||||||
return partnerRepo.save(givenPartner);
|
return partnerRepo.save(givenPartner);
|
||||||
});
|
});
|
||||||
@ -304,7 +305,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() {
|
public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("tenth");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "tenth");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -324,7 +325,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
|
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("eleventh");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "eleventh");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -350,7 +351,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
||||||
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("twelfth");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "twelfth");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -394,12 +395,14 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final String contact) {
|
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(
|
||||||
|
final Integer debitorNumberPrefix, final String person, final String contact) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenPerson = personRepo.findPersonByOptionalNameLike(person).get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(debitorNumberPrefix)
|
||||||
.person(givenPerson)
|
.person(givenPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
|
@ -8,10 +8,11 @@ import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGA
|
|||||||
|
|
||||||
public class TestHsOfficePartner {
|
public class TestHsOfficePartner {
|
||||||
|
|
||||||
public static final HsOfficePartnerEntity TEST_PARTNER = HsOfficePartnerWithLegalPerson("Test Ltd.");
|
public static final HsOfficePartnerEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
|
||||||
|
|
||||||
static public HsOfficePartnerEntity HsOfficePartnerWithLegalPerson(final String tradeName) {
|
static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
|
||||||
return HsOfficePartnerEntity.builder()
|
return HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(10001)
|
||||||
.person(HsOfficePersonEntity.builder()
|
.person(HsOfficePersonEntity.builder()
|
||||||
.personType(LEGAL)
|
.personType(LEGAL)
|
||||||
.tradeName(tradeName)
|
.tradeName(tradeName)
|
||||||
|
@ -11,29 +11,32 @@ class HsOfficePersonEntityUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void getDisplayReturnsTradeNameIfAvailable() {
|
void getDisplayReturnsTradeNameIfAvailable() {
|
||||||
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.LEGAL)
|
||||||
.tradeName("some trade name")
|
.tradeName("some trade name")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var actualDisplay = givenPersonEntity.toShortString();
|
final var actualDisplay = givenPersonEntity.toShortString();
|
||||||
|
|
||||||
assertThat(actualDisplay).isEqualTo("some trade name");
|
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getDisplayReturnsFamilyAndGivenNameIfNoTradeNameAvailable() {
|
void getDisplayReturnsFamilyAndGivenNameIfNoTradeNameAvailable() {
|
||||||
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.NATURAL)
|
||||||
.familyName("some family name")
|
.familyName("some family name")
|
||||||
.givenName("some given name")
|
.givenName("some given name")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var actualDisplay = givenPersonEntity.toShortString();
|
final var actualDisplay = givenPersonEntity.toShortString();
|
||||||
|
|
||||||
assertThat(actualDisplay).isEqualTo("some family name, some given name");
|
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringWithTradeNameReturnsTradeName() {
|
void toShortStringWithTradeNameReturnsTradeName() {
|
||||||
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.LEGAL)
|
||||||
.tradeName("some trade name")
|
.tradeName("some trade name")
|
||||||
.familyName("some family name")
|
.familyName("some family name")
|
||||||
.givenName("some given name")
|
.givenName("some given name")
|
||||||
@ -41,19 +44,20 @@ class HsOfficePersonEntityUnitTest {
|
|||||||
|
|
||||||
final var actualDisplay = givenPersonEntity.toShortString();
|
final var actualDisplay = givenPersonEntity.toShortString();
|
||||||
|
|
||||||
assertThat(actualDisplay).isEqualTo("some trade name");
|
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringWithoutTradeNameReturnsFamilyAndGivenName() {
|
void toShortStringWithoutTradeNameReturnsFamilyAndGivenName() {
|
||||||
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
final var givenPersonEntity = HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.NATURAL)
|
||||||
.familyName("some family name")
|
.familyName("some family name")
|
||||||
.givenName("some given name")
|
.givenName("some given name")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var actualDisplay = givenPersonEntity.toShortString();
|
final var actualDisplay = givenPersonEntity.toShortString();
|
||||||
|
|
||||||
assertThat(actualDisplay).isEqualTo("some family name, some given name");
|
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -144,10 +144,10 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
allThesePersonsAreReturned(
|
allThesePersonsAreReturned(
|
||||||
result,
|
result,
|
||||||
"Smith, Peter",
|
"NATURAL Smith, Peter",
|
||||||
"Second e.K.",
|
"LEGAL Second e.K.",
|
||||||
"Third OHG",
|
"SOLE_REPRESENTATION Third OHG",
|
||||||
"Erben Bessler");
|
"JOINT_REPRESENTATION Erben Bessler");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -75,7 +75,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relationships?personUuid=%s&relationshipType=%s"
|
.get("http://localhost/api/hs/office/relationships?personUuid=%s&relationshipType=%s"
|
||||||
.formatted(givenPerson.getUuid(), HsOfficeRelationshipTypeResource.SOLE_AGENT))
|
.formatted(givenPerson.getUuid(), HsOfficeRelationshipTypeResource.REPRESENTATIVE))
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
@ -91,7 +91,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"givenName": "Peter",
|
"givenName": "Peter",
|
||||||
"familyName": "Smith"
|
"familyName": "Smith"
|
||||||
},
|
},
|
||||||
"relType": "SOLE_AGENT",
|
"relType": "REPRESENTATIVE",
|
||||||
"contact": { "label": "third contact" }
|
"contact": { "label": "third contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -106,7 +106,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"givenName": "Peter",
|
"givenName": "Peter",
|
||||||
"familyName": "Smith"
|
"familyName": "Smith"
|
||||||
},
|
},
|
||||||
"relType": "SOLE_AGENT",
|
"relType": "REPRESENTATIVE",
|
||||||
"contact": { "label": "second contact" }
|
"contact": { "label": "second contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -120,7 +120,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"givenName": "Peter",
|
"givenName": "Peter",
|
||||||
"familyName": "Smith"
|
"familyName": "Smith"
|
||||||
},
|
},
|
||||||
"relType": "SOLE_AGENT",
|
"relType": "REPRESENTATIVE",
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -153,7 +153,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
|
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
||||||
givenAnchorPerson.getUuid(),
|
givenAnchorPerson.getUuid(),
|
||||||
givenHolderPerson.getUuid(),
|
givenHolderPerson.getUuid(),
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
@ -164,7 +164,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("relType", is("ACCOUNTING_CONTACT"))
|
.body("relType", is("ACCOUNTING"))
|
||||||
.body("relAnchor.tradeName", is("Third OHG"))
|
.body("relAnchor.tradeName", is("Third OHG"))
|
||||||
.body("relHolder.givenName", is("Paul"))
|
.body("relHolder.givenName", is("Paul"))
|
||||||
.body("contact.label", is("forth contact"))
|
.body("contact.label", is("forth contact"))
|
||||||
@ -197,7 +197,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
|
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
||||||
givenAnchorPersonUuid,
|
givenAnchorPersonUuid,
|
||||||
givenHolderPerson.getUuid(),
|
givenHolderPerson.getUuid(),
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
@ -230,7 +230,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
|
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
||||||
givenAnchorPerson.getUuid(),
|
givenAnchorPerson.getUuid(),
|
||||||
givenHolderPersonUuid,
|
givenHolderPersonUuid,
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
@ -263,7 +263,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING_CONTACT,
|
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
||||||
givenAnchorPerson.getUuid(),
|
givenAnchorPerson.getUuid(),
|
||||||
givenHolderPerson.getUuid(),
|
givenHolderPerson.getUuid(),
|
||||||
givenContactUuid))
|
givenContactUuid))
|
||||||
@ -387,7 +387,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("relType", is("JOINT_AGENT"))
|
.body("relType", is("REPRESENTATIVE"))
|
||||||
.body("relAnchor.tradeName", is("Erben Bessler"))
|
.body("relAnchor.tradeName", is("Erben Bessler"))
|
||||||
.body("relHolder.familyName", is("Winkler"))
|
.body("relHolder.familyName", is("Winkler"))
|
||||||
.body("contact.label", is("forth contact"));
|
.body("contact.label", is("forth contact"));
|
||||||
@ -400,7 +400,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
assertThat(rel.getRelAnchor().getTradeName()).contains("Bessler");
|
assertThat(rel.getRelAnchor().getTradeName()).contains("Bessler");
|
||||||
assertThat(rel.getRelHolder().getFamilyName()).contains("Winkler");
|
assertThat(rel.getRelHolder().getFamilyName()).contains("Winkler");
|
||||||
assertThat(rel.getContact().getLabel()).isEqualTo("forth contact");
|
assertThat(rel.getContact().getLabel()).isEqualTo("forth contact");
|
||||||
assertThat(rel.getRelType()).isEqualTo(HsOfficeRelationshipType.JOINT_AGENT);
|
assertThat(rel.getRelType()).isEqualTo(HsOfficeRelationshipType.REPRESENTATIVE);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -477,7 +477,7 @@ class HsOfficeRelationshipControllerAcceptanceTest {
|
|||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
.uuid(UUID.randomUUID())
|
||||||
.relType(HsOfficeRelationshipType.JOINT_AGENT)
|
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
||||||
.relAnchor(givenAnchorPerson)
|
.relAnchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.relHolder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
|
@ -52,7 +52,7 @@ class HsOfficeRelationshipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
protected HsOfficeRelationshipEntity newInitialEntity() {
|
protected HsOfficeRelationshipEntity newInitialEntity() {
|
||||||
final var entity = new HsOfficeRelationshipEntity();
|
final var entity = new HsOfficeRelationshipEntity();
|
||||||
entity.setUuid(INITIAL_RELATIONSHIP_UUID);
|
entity.setUuid(INITIAL_RELATIONSHIP_UUID);
|
||||||
entity.setRelType(HsOfficeRelationshipType.SOLE_AGENT);
|
entity.setRelType(HsOfficeRelationshipType.REPRESENTATIVE);
|
||||||
entity.setRelAnchor(givenInitialAnchorPerson);
|
entity.setRelAnchor(givenInitialAnchorPerson);
|
||||||
entity.setRelHolder(givenInitialHolderPerson);
|
entity.setRelHolder(givenInitialHolderPerson);
|
||||||
entity.setContact(givenInitialContact);
|
entity.setContact(givenInitialContact);
|
||||||
|
@ -77,7 +77,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder()
|
final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder()
|
||||||
.relAnchor(givenAnchorPerson)
|
.relAnchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.relHolder(givenHolderPerson)
|
||||||
.relType(HsOfficeRelationshipType.JOINT_AGENT)
|
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build());
|
.build());
|
||||||
return relationshipRepo.save(newRelationship);
|
return relationshipRepo.save(newRelationship);
|
||||||
@ -105,7 +105,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder()
|
final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder()
|
||||||
.relAnchor(givenAnchorPerson)
|
.relAnchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.relHolder(givenHolderPerson)
|
||||||
.relType(HsOfficeRelationshipType.JOINT_AGENT)
|
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build());
|
.build());
|
||||||
return relationshipRepo.save(newRelationship);
|
return relationshipRepo.save(newRelationship);
|
||||||
@ -114,26 +114,26 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin",
|
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin",
|
||||||
"hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner",
|
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner",
|
||||||
"hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant"));
|
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
|
|
||||||
"{ grant perm * on hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner by system and assume }",
|
"{ grant perm * on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner to role global#global.admin by system and assume }",
|
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role global#global.admin by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
|
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
|
||||||
|
|
||||||
"{ grant perm edit on hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin by system and assume }",
|
"{ grant perm edit on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.owner by system and assume }",
|
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
|
||||||
|
|
||||||
"{ grant perm view on hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant by system and assume }",
|
"{ grant perm view on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant to role hs_office_contact#forthcontact.admin by system and assume }",
|
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_contact#forthcontact.admin by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
|
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
|
||||||
|
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.admin by system and assume }",
|
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
|
||||||
"{ grant role hs_office_contact#forthcontact.tenant to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant by system and assume }",
|
"{ grant role hs_office_contact#forthcontact.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
||||||
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-JOINT_AGENT-BesslerAnita.tenant by system and assume }",
|
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
||||||
null)
|
null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -159,9 +159,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
allTheseRelationshipsAreReturned(
|
allTheseRelationshipsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(relAnchor='First GmbH', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='first contact')",
|
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')",
|
||||||
"rel(relAnchor='Third OHG', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='third contact')",
|
"rel(relAnchor='SOLE_REPRESENTATION Third OHG', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='third contact')",
|
||||||
"rel(relAnchor='Second e.K.', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='second contact')");
|
"rel(relAnchor='LEGAL Second e.K.', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='second contact')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -176,7 +176,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseRelationshipsAreReturned(
|
exactlyTheseRelationshipsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(relAnchor='First GmbH', relType='SOLE_AGENT', relHolder='Smith, Peter', contact='first contact')");
|
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
||||||
.relType(HsOfficeRelationshipType.JOINT_AGENT)
|
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
||||||
.relAnchor(givenAnchorPerson)
|
.relAnchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.relHolder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
|
@ -80,7 +80,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10002,
|
"debitorNumber": 1000212,
|
||||||
"billingContact": { "label": "second contact" }
|
"billingContact": { "label": "second contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": { "holder": "Second e.K." },
|
"bankAccount": { "holder": "Second e.K." },
|
||||||
@ -90,7 +90,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
"billingContact": { "label": "first contact" }
|
"billingContact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": { "holder": "First GmbH" },
|
"bankAccount": { "holder": "First GmbH" },
|
||||||
@ -100,7 +100,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10003,
|
"debitorNumber": 1000313,
|
||||||
"billingContact": { "label": "third contact" }
|
"billingContact": { "label": "third contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": { "holder": "Third OHG" },
|
"bankAccount": { "holder": "Third OHG" },
|
||||||
@ -269,7 +269,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
"billingContact": { "label": "first contact" }
|
"billingContact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": {
|
"bankAccount": {
|
||||||
@ -321,7 +321,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
"billingContact": { "label": "first contact" }
|
"billingContact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": {
|
"bankAccount": {
|
||||||
@ -376,7 +376,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(10001: First GmbH)");
|
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LEGAL First GmbH: fir)");
|
||||||
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
||||||
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
|
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
|
||||||
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
|
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
|
||||||
@ -417,7 +417,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
// finally, the sepaMandate is actually updated
|
// finally, the sepaMandate is actually updated
|
||||||
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(10001: First GmbH)");
|
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LEGAL First GmbH: fir)");
|
||||||
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
||||||
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
|
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");
|
||||||
|
@ -144,13 +144,13 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role sepamandate#temprefB.agent to role sepamandate#temprefB.admin by system and assume }",
|
"{ grant role sepamandate#temprefB.agent to role sepamandate#temprefB.admin by system and assume }",
|
||||||
"{ grant role debitor#10001FirstGmbH-....tenant to role sepamandate#temprefB.agent by system and assume }",
|
"{ grant role debitor#1000111:FirstGmbH-....tenant to role sepamandate#temprefB.agent by system and assume }",
|
||||||
"{ grant role sepamandate#temprefB.agent to role bankaccount#Paul....admin by system and assume }",
|
"{ grant role sepamandate#temprefB.agent to role bankaccount#Paul....admin by system and assume }",
|
||||||
"{ grant role sepamandate#temprefB.agent to role debitor#10001FirstGmbH-....admin by system and assume }",
|
"{ grant role sepamandate#temprefB.agent to role debitor#1000111:FirstGmbH-....admin by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role sepamandate#temprefB.tenant to role sepamandate#temprefB.agent by system and assume }",
|
"{ grant role sepamandate#temprefB.tenant to role sepamandate#temprefB.agent by system and assume }",
|
||||||
"{ grant role debitor#10001FirstGmbH-....guest to role sepamandate#temprefB.tenant by system and assume }",
|
"{ grant role debitor#1000111:FirstGmbH-....guest to role sepamandate#temprefB.tenant by system and assume }",
|
||||||
"{ grant role bankaccount#Paul....guest to role sepamandate#temprefB.tenant by system and assume }",
|
"{ grant role bankaccount#Paul....guest to role sepamandate#temprefB.tenant by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
|
@ -22,7 +22,7 @@ class PostgresArrayIntegrationTest {
|
|||||||
em.createNativeQuery("""
|
em.createNativeQuery("""
|
||||||
create or replace function returnEmptyArray()
|
create or replace function returnEmptyArray()
|
||||||
returns text[]
|
returns text[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
emptyArray text[] = '{}';
|
emptyArray text[] = '{}';
|
||||||
@ -42,7 +42,7 @@ class PostgresArrayIntegrationTest {
|
|||||||
em.createNativeQuery("""
|
em.createNativeQuery("""
|
||||||
create or replace function returnStringArray()
|
create or replace function returnStringArray()
|
||||||
returns varchar(63)[]
|
returns varchar(63)[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
text1 text = 'one';
|
text1 text = 'one';
|
||||||
@ -65,7 +65,7 @@ class PostgresArrayIntegrationTest {
|
|||||||
em.createNativeQuery("""
|
em.createNativeQuery("""
|
||||||
create or replace function returnUuidArray()
|
create or replace function returnUuidArray()
|
||||||
returns uuid[]
|
returns uuid[]
|
||||||
stable leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
uuid1 UUID = 'f47ac10b-58cc-4372-a567-0e02b2c3d479';
|
uuid1 UUID = 'f47ac10b-58cc-4372-a567-0e02b2c3d479';
|
||||||
|
@ -10,9 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.persistence.PersistenceContext;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
@ -25,9 +22,6 @@ class RbacRoleControllerAcceptanceTest {
|
|||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
private Integer port;
|
private Integer port;
|
||||||
|
|
||||||
@PersistenceContext
|
|
||||||
EntityManager em;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.test;
|
package net.hostsharing.test;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import org.junit.jupiter.api.Named;
|
import org.junit.jupiter.api.Named;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -232,7 +233,7 @@ public abstract class PatchUnitTestBase<R, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class JsonNullableProperty<R, RV, E, EV> extends Property<R, RV, E, EV> {
|
protected static class JsonNullableProperty<R, RV, E extends HasUuid, EV> extends Property<R, RV, E, EV> {
|
||||||
|
|
||||||
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
|
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
|
||||||
public final RV givenPatchValue;
|
public final RV givenPatchValue;
|
||||||
|
9
src/test/resources/migration/asset-transactions.csv
Normal file
9
src/test/resources/migration/asset-transactions.csv
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
member_asset_id; bp_id; date; action; amount; comment
|
||||||
|
30000; 17; 2000-12-06; PAYMENT; 1280.00; for subscription A
|
||||||
|
31000; 20; 2000-12-06; PAYMENT; 128.00; for subscription B
|
||||||
|
32000; 17; 2005-01-10; PAYMENT; 2560.00; for subscription C
|
||||||
|
33001; 17; 2005-01-10; HANDOVER; -512.00; for transfer to 10
|
||||||
|
33002; 20; 2005-01-10; ADOPTION; 512.00; for transfer from 7
|
||||||
|
34001; 20; 2016-12-31; CLEARING; -8.00; for cancellation D
|
||||||
|
34002; 20; 2016-12-31; PAYBACK; -100.00; for cancellation D
|
||||||
|
34003; 20; 2016-12-31; LOSS; -20.00; for cancellation D
|
|
4
src/test/resources/migration/business-partners.csv
Normal file
4
src/test/resources/migration/business-partners.csv
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
bp_id;member_id;member_code;member_since;member_until;member_role;author_contract;nondisc_contract;free;exempt_vat;indicator_vat;uid_vat
|
||||||
|
17;10017;hsh00-mih;2000-12-06;;Aufsichtsrat;2006-10-15;2001-10-15;false;false;NET;DE-VAT-007
|
||||||
|
20;10020;hsh00-xyz;2000-12-06;2015-12-31;;;;false;false;GROSS;
|
||||||
|
22;11022;hsh00-xxx;2021-04-01;;;;;true;true;GROSS;
|
|
13
src/test/resources/migration/contacts.csv
Normal file
13
src/test/resources/migration/contacts.csv
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
contact_id; bp_id; salut; first_name; last_name; title; firma; co; street; zipcode;city; country; phone_private; phone_office; phone_mobile; fax; email; roles
|
||||||
|
|
||||||
|
# eine natürliche Person, implizites contractual
|
||||||
|
1101; 17; Herr; Michael; Mellies; ; ; ; Kleine Freiheit 50; 26524; Hage; DE; ; +49 4931 123456; +49 1522 123456;; mih@example.org; partner,billing,operation
|
||||||
|
|
||||||
|
# eine juristische Person mit drei separaten Ansprechpartnern, vip-contact und ex-partner
|
||||||
|
1200; 20;; ; ; ; JM e.K.;; Wiesenweg 15; 12335; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; jm-ex-partner@example.org; ex-partner
|
||||||
|
1201; 20; Frau; Jenny; Meyer-Billing; Dr.; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 7777777; +49 30 1111111; ; +49 30 2222222; jm-billing@example.org; billing
|
||||||
|
1202; 20; Herr; Andrew; Meyer-Operation; ; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 3333333; ; +49 30 4444444; am-operation@example.org; operation,vip-contact
|
||||||
|
1203; 20; Herr; Philip; Meyer-Contract; ; JM GmbH;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; pm-partner@example.org; partner,contractual
|
||||||
|
|
||||||
|
# eine juristische Person mit nur einem Ansprechpartner und explizitem contractual
|
||||||
|
1301; 22; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; partner,billing,contractual,operation
|
|
43
src/test/resources/migration/dump.sh
Normal file
43
src/test/resources/migration/dump.sh
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
host="127.0.0.1"
|
||||||
|
port="5432"
|
||||||
|
dbname="hsh02_hsdb"
|
||||||
|
username="hsh02_hsdb_readonly"
|
||||||
|
|
||||||
|
target="/tmp"
|
||||||
|
|
||||||
|
dump() {
|
||||||
|
sql="copy ($1) to stdout with csv header delimiter ';' quote '\"'"
|
||||||
|
file="${target}/${2}"
|
||||||
|
psql --host ${host} --port ${port} --user ${username} --command "${sql}" ${dbname} >"${file}"
|
||||||
|
}
|
||||||
|
|
||||||
|
dump "select bp_id, member_id, member_code, member_since, member_until, member_role, author_contract, nondisc_contract, free, exempt_vat, indicator_vat, uid_vat
|
||||||
|
from business_partner
|
||||||
|
order by bp_id" \
|
||||||
|
"business-partners.csv"
|
||||||
|
|
||||||
|
dump "select contact_id, bp_id, salut, first_name, last_name, title, firma, co, street, zipcode, city, country, phone_private, phone_office, phone_mobile, fax, email, array_to_string(array_agg(role), ',') as roles
|
||||||
|
from contact
|
||||||
|
left join contactrole_ref using(contact_id)
|
||||||
|
group by contact_id
|
||||||
|
order by contact_id" \
|
||||||
|
"contacts.csv"
|
||||||
|
|
||||||
|
dump "select sepa_mandat_id, bp_id, bank_customer, bank_name, bank_iban, bank_bic, mandat_ref, mandat_signed, mandat_since, mandat_until, mandat_used
|
||||||
|
from sepa_mandat
|
||||||
|
order by sepa_mandat_id" \
|
||||||
|
"sepa-mandates.csv"
|
||||||
|
|
||||||
|
dump "select member_asset_id, bp_id, date, action, amount, comment
|
||||||
|
from member_asset
|
||||||
|
WHERE bp_id NOT IN (511912)
|
||||||
|
order by member_asset_id" \
|
||||||
|
"asset-transactions.csv"
|
||||||
|
|
||||||
|
dump "select member_share_id, bp_id, date, action, quantity, comment
|
||||||
|
from member_share
|
||||||
|
WHERE bp_id NOT IN (511912)
|
||||||
|
order by member_share_id" \
|
||||||
|
"share-transactions.csv"
|
4
src/test/resources/migration/sepa-mandates.csv
Normal file
4
src/test/resources/migration/sepa-mandates.csv
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
sepa_mandat_id; bp_id; bank_customer; bank_name; bank_iban; bank_bic; mandat_ref; mandat_signed; mandat_since; mandat_until; mandat_used
|
||||||
|
234234; 17; Michael Mellies; ING Bank AG; DE37500105177419788228; INGDDEFFXXX; MH12345; 2004-06-12; 2004-06-15; ; 2022-10-20
|
||||||
|
235600; 20; JM e.K.; Targobank AG; DE02300209000106531065; CMCIDEDD; JM33344; 2004-01-15; 2004-01-20;2005-06-27 ;2016-01-18
|
||||||
|
235662; 20; JM GmbH; ING Bank AG; DE49500105174516484892; INGDDEFFXXX; JM33344; 2005-06-28; 2005-07-01; ; 2016-01-18
|
|
5
src/test/resources/migration/share-transactions.csv
Normal file
5
src/test/resources/migration/share-transactions.csv
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
member_share_id;bp_id; date; action; quantity; comment
|
||||||
|
33443; 17; 2000-12-06; SUBSCRIPTION; 20; initial share subscription
|
||||||
|
33451; 20; 2000-12-06; SUBSCRIPTION; 2; initial share subscription
|
||||||
|
33701; 17; 2005-01-10; SUBSCRIPTION; 40; increase
|
||||||
|
33810; 20; 2016-12-31; UNSUBSCRIPTION; 22; membership ended
|
|
Loading…
Reference in New Issue
Block a user