post new contact: process postalAddress #145
4
.aliases
4
.aliases
@ -93,7 +93,8 @@ alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResource
|
|||||||
alias gw-test='. .aliases; ./gradlew test'
|
alias gw-test='. .aliases; ./gradlew test'
|
||||||
alias gw-check='. .aliases; gw test check -x pitest'
|
alias gw-check='. .aliases; gw test check -x pitest'
|
||||||
|
|
||||||
alias cas-curl='bin/cas-curl'
|
alias howto=bin/howto
|
||||||
|
alias cas-curl=bin/cas-curl
|
||||||
|
|
||||||
# etc/docker-compose.yml limits CPUs+MEM and includes a PostgreSQL config for analysing slow queries
|
# etc/docker-compose.yml limits CPUs+MEM and includes a PostgreSQL config for analysing slow queries
|
||||||
alias gw-importOfficeData-in-docker-compose='
|
alias gw-importOfficeData-in-docker-compose='
|
||||||
@ -108,3 +109,4 @@ source .environment
|
|||||||
|
|
||||||
alias scenario-reports-upload='./gradlew scenarioTests convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office'
|
alias scenario-reports-upload='./gradlew scenarioTests convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office'
|
||||||
alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office'
|
alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office'
|
||||||
|
|
||||||
|
@ -4,5 +4,5 @@ export HSADMINNG_POSTGRES_ADMIN_PASSWORD=
|
|||||||
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
||||||
export HSADMINNG_SUPERUSER=superuser-alex@hostsharing.net
|
export HSADMINNG_SUPERUSER=superuser-alex@hostsharing.net
|
||||||
export HSADMINNG_MIGRATION_DATA_PATH=migration
|
export HSADMINNG_MIGRATION_DATA_PATH=migration
|
||||||
export LIQUIBASE_CONTEXT=
|
export LIQUIBASE_COMMAND_CONTEXT_FILTER=
|
||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
|
@ -4,5 +4,5 @@ unset HSADMINNG_POSTGRES_ADMIN_PASSWORD
|
|||||||
unset HSADMINNG_POSTGRES_RESTRICTED_USERNAME
|
unset HSADMINNG_POSTGRES_RESTRICTED_USERNAME
|
||||||
unset HSADMINNG_SUPERUSER
|
unset HSADMINNG_SUPERUSER
|
||||||
unset HSADMINNG_MIGRATION_DATA_PATH
|
unset HSADMINNG_MIGRATION_DATA_PATH
|
||||||
unset LIQUIBASE_CONTEXT
|
unset LIQUIBASE_COMMAND_CONTEXT_FILTER
|
||||||
|
|
||||||
|
@ -617,6 +617,11 @@ Besides the following *How Tos* you can also find several *How Tos* in the sourc
|
|||||||
grep -r HOWTO src
|
grep -r HOWTO src
|
||||||
```
|
```
|
||||||
|
|
||||||
|
also try this (assumed you've sourced .aliases):
|
||||||
|
```sh
|
||||||
|
howto
|
||||||
|
```
|
||||||
|
|
||||||
### How to Configure .pgpass for the Default PostgreSQL Database?
|
### How to Configure .pgpass for the Default PostgreSQL Database?
|
||||||
|
|
||||||
To access the default database schema as used during development, add this line to your `.pgpass` file in your users home directory:
|
To access the default database schema as used during development, add this line to your `.pgpass` file in your users home directory:
|
||||||
|
86
bin/howto
Executable file
86
bin/howto
Executable file
@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from urllib.parse import urljoin, quote
|
||||||
|
|
||||||
|
def path_to_file_uri(path):
|
||||||
|
"""
|
||||||
|
Converts a file path to a file URI.
|
||||||
|
Handles absolute and relative paths.
|
||||||
|
"""
|
||||||
|
abs_path = os.path.abspath(path)
|
||||||
|
return urljoin("file://", quote(abs_path))
|
||||||
|
|
||||||
|
def is_binary_file(filepath, chunk_size=1024):
|
||||||
|
"""
|
||||||
|
Prüft, ob eine Datei binär ist, indem sie den Inhalt der Datei auf nicht-druckbare Zeichen untersucht.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(filepath, "rb") as file:
|
||||||
|
chunk = file.read(chunk_size)
|
||||||
|
if b"\0" in chunk: # Nullbyte ist ein typisches Zeichen für Binärdateien
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Prüfen, ob Datei binär ist: {filepath}: {e}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def search_keywords_in_files(keywords):
|
||||||
|
if not keywords:
|
||||||
|
print("Bitte geben Sie mindestens ein Stichwort an.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Allowed comment symbols
|
||||||
|
comment_symbols = {"//", "#", ";"}
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk("."):
|
||||||
|
# Ausschließen bestimmter Verzeichnisse
|
||||||
|
dirs[:] = [d for d in dirs if d not in {".git", "build"}]
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
filepath = os.path.join(root, file)
|
||||||
|
|
||||||
|
# Überspringen von Binärdateien
|
||||||
|
if is_binary_file(filepath):
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filepath, "r", encoding="utf-8") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
for line_number, line in enumerate(lines, start=1):
|
||||||
|
stripped_line = line.lstrip() # Entfernt führende Leerzeichen
|
||||||
|
for symbol in comment_symbols:
|
||||||
|
if stripped_line.startswith(symbol):
|
||||||
|
# Entfernt das Kommentarzeichen und nachfolgende Leerzeichen
|
||||||
|
howtoMatch = stripped_line[len(symbol):].lstrip()
|
||||||
|
if howtoMatch.startswith(("HOWTO ", "HOWTO: ", "How to ")):
|
||||||
|
if all(keyword in howtoMatch.lower() for keyword in keywords):
|
||||||
|
|
||||||
|
# Titelzeile ohne Kommentarzeichen
|
||||||
|
print(howtoMatch.rstrip())
|
||||||
|
|
||||||
|
# Ausgabe nachfolgender Zeilen mit dem gleichen Kommentar-Präfix
|
||||||
|
for subsequent_line in lines[line_number:]:
|
||||||
|
subsequent_line = subsequent_line.lstrip()
|
||||||
|
if subsequent_line.startswith(symbol):
|
||||||
|
# Entfernt Kommentarzeichen aus Folgezeilen
|
||||||
|
print("\t" + subsequent_line[len(symbol):].strip())
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Link mit Zeilennummer
|
||||||
|
print(f"--> {path_to_file_uri(filepath)}:{line_number}")
|
||||||
|
|
||||||
|
# Abstand zwischen Matches
|
||||||
|
print()
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Lesen der Datei {filepath}: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Verwendung: bin/howto <Stichwort1> <Stichwort2> ...")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
search_keywords_in_files([arg.lower() for arg in sys.argv[1:]])
|
26
build.gradle
26
build.gradle
@ -1,17 +1,20 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.3.7'
|
id 'org.springframework.boot' version '3.4.1'
|
||||||
id 'io.spring.dependency-management' version '1.1.7'
|
id 'io.spring.dependency-management' version '1.1.7'
|
||||||
id 'io.openapiprocessor.openapi-processor' version '2023.2'
|
id 'io.openapiprocessor.openapi-processor' version '2023.2'
|
||||||
id 'com.github.jk1.dependency-license-report' version '2.9'
|
id 'com.github.jk1.dependency-license-report' version '2.9'
|
||||||
id "org.owasp.dependencycheck" version "11.1.1"
|
id "org.owasp.dependencycheck" version "12.0.0"
|
||||||
id "com.diffplug.spotless" version "7.0.0"
|
id "com.diffplug.spotless" version "7.0.2"
|
||||||
id 'jacoco'
|
id 'jacoco'
|
||||||
id 'info.solidsoft.pitest' version '1.15.0'
|
id 'info.solidsoft.pitest' version '1.15.0'
|
||||||
id 'se.patrikerdes.use-latest-versions' version '0.2.18'
|
id 'se.patrikerdes.use-latest-versions' version '0.2.18'
|
||||||
id 'com.github.ben-manes.versions' version '0.51.0'
|
id 'com.github.ben-manes.versions' version '0.51.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HOWTO: find out which dependency versions are managed by Spring Boot:
|
||||||
|
// https://docs.spring.io/spring-boot/appendix/dependency-versions/coordinates.html
|
||||||
|
|
||||||
group = 'net.hostsharing'
|
group = 'net.hostsharing'
|
||||||
version = '0.0.1-SNAPSHOT'
|
version = '0.0.1-SNAPSHOT'
|
||||||
|
|
||||||
@ -20,6 +23,9 @@ wrapper {
|
|||||||
gradleVersion = '8.5'
|
gradleVersion = '8.5'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO.impl: self-attaching is deprecated, see:
|
||||||
|
// https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
compileOnly {
|
compileOnly {
|
||||||
extendsFrom annotationProcessor
|
extendsFrom annotationProcessor
|
||||||
@ -61,23 +67,23 @@ dependencies {
|
|||||||
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||||
implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0'
|
implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0'
|
||||||
implementation 'org.springdoc:springdoc-openapi:2.6.0'
|
implementation 'org.springdoc:springdoc-openapi:2.8.3'
|
||||||
implementation 'org.postgresql:postgresql:42.7.4'
|
implementation 'org.postgresql:postgresql'
|
||||||
implementation 'org.liquibase:liquibase-core:4.30.0'
|
implementation 'org.liquibase:liquibase-core'
|
||||||
implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0'
|
implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0'
|
||||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2'
|
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
|
||||||
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
|
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
|
||||||
implementation 'org.apache.commons:commons-text:1.13.0'
|
implementation 'org.apache.commons:commons-text:1.13.0'
|
||||||
implementation 'net.java.dev.jna:jna:5.16.0'
|
implementation 'net.java.dev.jna:jna:5.16.0'
|
||||||
implementation 'org.modelmapper:modelmapper:3.2.2'
|
implementation 'org.modelmapper:modelmapper:3.2.2'
|
||||||
implementation 'org.iban4j:iban4j:3.2.10-RELEASE'
|
implementation 'org.iban4j:iban4j:3.2.10-RELEASE'
|
||||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
|
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.3'
|
||||||
implementation 'org.reflections:reflections:0.10.2'
|
implementation 'org.reflections:reflections:0.10.2'
|
||||||
|
|
||||||
compileOnly 'org.projectlombok:lombok'
|
compileOnly 'org.projectlombok:lombok'
|
||||||
testCompileOnly 'org.projectlombok:lombok'
|
testCompileOnly 'org.projectlombok:lombok'
|
||||||
|
|
||||||
// FIXME: developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
|
|
||||||
annotationProcessor 'org.projectlombok:lombok'
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok'
|
testAnnotationProcessor 'org.projectlombok:lombok'
|
||||||
@ -89,7 +95,7 @@ dependencies {
|
|||||||
testImplementation 'org.testcontainers:postgresql'
|
testImplementation 'org.testcontainers:postgresql'
|
||||||
testImplementation 'com.tngtech.archunit:archunit-junit5:1.3.0'
|
testImplementation 'com.tngtech.archunit:archunit-junit5:1.3.0'
|
||||||
testImplementation 'io.rest-assured:spring-mock-mvc'
|
testImplementation 'io.rest-assured:spring-mock-mvc'
|
||||||
testImplementation 'org.hamcrest:hamcrest-core:3.0'
|
testImplementation 'org.hamcrest:hamcrest-core'
|
||||||
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'
|
testImplementation 'org.junit.jupiter:junit-jupiter-api'
|
||||||
testImplementation 'org.wiremock:wiremock-standalone:3.10.0'
|
testImplementation 'org.wiremock:wiremock-standalone:3.10.0'
|
||||||
|
@ -5,9 +5,23 @@
|
|||||||
{ "moduleLicense": "Apache-2.0" },
|
{ "moduleLicense": "Apache-2.0" },
|
||||||
{ "moduleLicense": "Apache License 2.0" },
|
{ "moduleLicense": "Apache License 2.0" },
|
||||||
{ "moduleLicense": "Apache License v2.0" },
|
{ "moduleLicense": "Apache License v2.0" },
|
||||||
|
{ "moduleLicense": "Apache License Version 2.0" },
|
||||||
{ "moduleLicense": "Apache License, Version 2.0" },
|
{ "moduleLicense": "Apache License, Version 2.0" },
|
||||||
|
{ "moduleLicense": "The Apache License, Version 2.0" },
|
||||||
{ "moduleLicense": "The Apache Software License, Version 2.0" },
|
{ "moduleLicense": "The Apache Software License, Version 2.0" },
|
||||||
|
|
||||||
|
{
|
||||||
|
"moduleLicense": null,
|
||||||
|
"#moduleLicense": "Apache License 2.0, see https://github.com/springdoc/springdoc-openapi/blob/main/LICENSE",
|
||||||
|
"moduleVersion": "2.4.0",
|
||||||
|
"moduleName": "org.springdoc:springdoc-openapi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleLicense": null,
|
||||||
|
"moduleVersion": "1.0.0",
|
||||||
|
"moduleName": "org.jspecify:jspecify"
|
||||||
|
},
|
||||||
|
|
||||||
{ "moduleLicense": "BSD License" },
|
{ "moduleLicense": "BSD License" },
|
||||||
{ "moduleLicense": "BSD-2-Clause" },
|
{ "moduleLicense": "BSD-2-Clause" },
|
||||||
{ "moduleLicense": "BSD-3-Clause" },
|
{ "moduleLicense": "BSD-3-Clause" },
|
||||||
@ -46,14 +60,8 @@
|
|||||||
{
|
{
|
||||||
"moduleLicense": "Public Domain, per Creative Commons CC0",
|
"moduleLicense": "Public Domain, per Creative Commons CC0",
|
||||||
"moduleVersion": "2.0.3"
|
"moduleVersion": "2.0.3"
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"moduleLicense": null,
|
|
||||||
"#moduleLicense": "Apache License 2.0, see https://github.com/springdoc/springdoc-openapi/blob/main/LICENSE",
|
|
||||||
"moduleVersion": "2.4.0",
|
|
||||||
"moduleName": "org.springdoc:springdoc-openapi"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ public class RestResponseEntityExceptionHandler
|
|||||||
return errorResponse(request, HttpStatus.valueOf(statusCode.value()),
|
return errorResponse(request, HttpStatus.valueOf(statusCode.value()),
|
||||||
Optional.ofNullable(response.getBody()).map(Object::toString).orElse(firstMessageLine(exc)));
|
Optional.ofNullable(response.getBody()).map(Object::toString).orElse(firstMessageLine(exc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked,rawtypes")
|
@SuppressWarnings("unchecked,rawtypes")
|
||||||
protected ResponseEntity handleHttpMessageNotReadable(
|
protected ResponseEntity handleHttpMessageNotReadable(
|
||||||
@ -131,7 +132,7 @@ public class RestResponseEntityExceptionHandler
|
|||||||
final HttpStatusCode status,
|
final HttpStatusCode status,
|
||||||
final WebRequest request) {
|
final WebRequest request) {
|
||||||
final var errorList = exc
|
final var errorList = exc
|
||||||
.getAllValidationResults()
|
.getParameterValidationResults()
|
||||||
.stream()
|
.stream()
|
||||||
.map(ParameterValidationResult::getResolvableErrors)
|
.map(ParameterValidationResult::getResolvableErrors)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
|
@ -5,6 +5,7 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
import net.hostsharing.hsadminng.rbac.role.WithRoleId;
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayAs("BookingDebitor")
|
@DisplayAs("BookingDebitor")
|
||||||
public class HsBookingDebitorEntity implements Stringifyable {
|
public class HsBookingDebitorEntity implements Stringifyable, WithRoleId {
|
||||||
|
|
||||||
public static final String DEBITOR_NUMBER_TAG = "D-";
|
public static final String DEBITOR_NUMBER_TAG = "D-";
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjec
|
|||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectResource;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -26,7 +26,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsBookingProjectRbacRepository bookingProjectRepo;
|
private HsBookingProjectRbacRepository bookingProjectRepo;
|
||||||
|
@ -89,7 +89,7 @@ public abstract class HsHostingAsset implements Stringifyable, BaseEntity<HsHost
|
|||||||
@JoinColumn(name = "alarmcontactuuid")
|
@JoinColumn(name = "alarmcontactuuid")
|
||||||
private HsOfficeContactRealEntity alarmContact;
|
private HsOfficeContactRealEntity alarmContact;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
|
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "parentassetuuid", referencedColumnName = "uuid")
|
@JoinColumn(name = "parentassetuuid", referencedColumnName = "uuid")
|
||||||
private List<HsHostingAssetRealEntity> subHostingAssets;
|
private List<HsHostingAssetRealEntity> subHostingAssets;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAsse
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
||||||
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -36,7 +36,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsHostingAssetRbacRepository rbacAssetRepo;
|
private HsHostingAssetRbacRepository rbacAssetRepo;
|
||||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.mapper.ToStringConverter;
|
import net.hostsharing.hsadminng.mapper.ToStringConverter;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ public class DomainSetupHostingAssetFactory extends HostingAssetFactory {
|
|||||||
final EntityManagerWrapper emw,
|
final EntityManagerWrapper emw,
|
||||||
final HsBookingItemRealEntity newBookingItemRealEntity,
|
final HsBookingItemRealEntity newBookingItemRealEntity,
|
||||||
final HsHostingAssetAutoInsertResource asset,
|
final HsHostingAssetAutoInsertResource asset,
|
||||||
final StandardMapper standardMapper) {
|
final StrictMapper StrictMapper) {
|
||||||
super(emw, newBookingItemRealEntity, asset, standardMapper);
|
super(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,7 +6,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
|
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ abstract class HostingAssetFactory {
|
|||||||
final EntityManagerWrapper emw;
|
final EntityManagerWrapper emw;
|
||||||
final HsBookingItemRealEntity fromBookingItem;
|
final HsBookingItemRealEntity fromBookingItem;
|
||||||
final HsHostingAssetAutoInsertResource asset;
|
final HsHostingAssetAutoInsertResource asset;
|
||||||
final StandardMapper standardMapper;
|
final StrictMapper StrictMapper;
|
||||||
|
|
||||||
protected abstract HsHostingAsset create();
|
protected abstract HsHostingAsset create();
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedAppEvent;
|
import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedAppEvent;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
@ -25,7 +25,7 @@ public class HsBookingItemCreatedListener implements ApplicationListener<Booking
|
|||||||
private ObjectMapper jsonMapper;
|
private ObjectMapper jsonMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper standardMapper;
|
private StrictMapper StrictMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@ -44,9 +44,9 @@ public class HsBookingItemCreatedListener implements ApplicationListener<Booking
|
|||||||
final var asset = jsonMapper.readValue(event.getEntity().getAssetJson(), HsHostingAssetAutoInsertResource.class);
|
final var asset = jsonMapper.readValue(event.getEntity().getAssetJson(), HsHostingAssetAutoInsertResource.class);
|
||||||
final var factory = switch (newBookingItemRealEntity.getType()) {
|
final var factory = switch (newBookingItemRealEntity.getType()) {
|
||||||
case PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER ->
|
case PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER ->
|
||||||
forNowNoAutomaticHostingAssetCreationPossible(emw, newBookingItemRealEntity, asset, standardMapper);
|
forNowNoAutomaticHostingAssetCreationPossible(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||||
case MANAGED_WEBSPACE -> new ManagedWebspaceHostingAssetFactory(emw, newBookingItemRealEntity, asset, standardMapper);
|
case MANAGED_WEBSPACE -> new ManagedWebspaceHostingAssetFactory(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||||
case DOMAIN_SETUP -> new DomainSetupHostingAssetFactory(emw, newBookingItemRealEntity, asset, standardMapper);
|
case DOMAIN_SETUP -> new DomainSetupHostingAssetFactory(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||||
};
|
};
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
final var statusMessage = factory.createAndPersist();
|
final var statusMessage = factory.createAndPersist();
|
||||||
@ -62,9 +62,9 @@ public class HsBookingItemCreatedListener implements ApplicationListener<Booking
|
|||||||
final EntityManagerWrapper emw,
|
final EntityManagerWrapper emw,
|
||||||
final HsBookingItemRealEntity fromBookingItem,
|
final HsBookingItemRealEntity fromBookingItem,
|
||||||
final HsHostingAssetAutoInsertResource asset,
|
final HsHostingAssetAutoInsertResource asset,
|
||||||
final StandardMapper standardMapper
|
final StrictMapper StrictMapper
|
||||||
) {
|
) {
|
||||||
return new HostingAssetFactory(emw, fromBookingItem, asset, standardMapper) {
|
return new HostingAssetFactory(emw, fromBookingItem, asset, StrictMapper) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsHostingAsset create() {
|
protected HsHostingAsset create() {
|
||||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
|
|
||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
@ -19,8 +19,8 @@ public class ManagedWebspaceHostingAssetFactory extends HostingAssetFactory {
|
|||||||
final EntityManagerWrapper emw,
|
final EntityManagerWrapper emw,
|
||||||
final HsBookingItemRealEntity newBookingItemRealEntity,
|
final HsBookingItemRealEntity newBookingItemRealEntity,
|
||||||
final HsHostingAssetAutoInsertResource asset,
|
final HsHostingAssetAutoInsertResource asset,
|
||||||
final StandardMapper standardMapper) {
|
final StrictMapper StrictMapper) {
|
||||||
super(emw, newBookingItemRealEntity, asset, standardMapper);
|
super(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -32,7 +32,7 @@ public class ManagedWebspaceHostingAssetFactory extends HostingAssetFactory {
|
|||||||
.map(Enum::name)
|
.map(Enum::name)
|
||||||
.orElse(null));
|
.orElse(null));
|
||||||
}
|
}
|
||||||
final var managedWebspaceHostingAsset = standardMapper.map(asset, HsHostingAssetRealEntity.class);
|
final var managedWebspaceHostingAsset = StrictMapper.map(asset, HsHostingAssetRealEntity.class);
|
||||||
managedWebspaceHostingAsset.setBookingItem(fromBookingItem);
|
managedWebspaceHostingAsset.setBookingItem(fromBookingItem);
|
||||||
emw.createQuery(
|
emw.createQuery(
|
||||||
"SELECT asset FROM HsHostingAssetRealEntity asset WHERE asset.bookingItem.uuid=:bookingItemUuid",
|
"SELECT asset FROM HsHostingAssetRealEntity asset WHERE asset.bookingItem.uuid=:bookingItemUuid",
|
||||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.context.Context;
|
|||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeBankAccountsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeBankAccountsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountResource;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.iban4j.BicUtil;
|
import org.iban4j.BicUtil;
|
||||||
import org.iban4j.IbanUtil;
|
import org.iban4j.IbanUtil;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -25,7 +25,7 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeBankAccountRepository bankAccountRepo;
|
private HsOfficeBankAccountRepository bankAccountRepo;
|
||||||
|
@ -12,6 +12,7 @@ import lombok.experimental.SuperBuilder;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
|
import net.hostsharing.hsadminng.rbac.role.WithRoleId;
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
@ -37,7 +38,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
|||||||
@SuperBuilder(toBuilder = true)
|
@SuperBuilder(toBuilder = true)
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayAs("Contact")
|
@DisplayAs("Contact")
|
||||||
public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact> {
|
public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact>, WithRoleId {
|
||||||
|
|
||||||
private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact")
|
private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact")
|
||||||
.withProp(Fields.caption, HsOfficeContact::getCaption)
|
.withProp(Fields.caption, HsOfficeContact::getCaption)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.contact;
|
package net.hostsharing.hsadminng.hs.office.contact;
|
||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeContactsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeContactsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||||
@ -28,7 +28,7 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeContactRbacRepository contactRepo;
|
private HsOfficeContactRbacRepository contactRepo;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -10,11 +9,22 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
|
|||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||||
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.persistence.Version;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@ -57,8 +67,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
|||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "UUID")
|
@GeneratedValue
|
||||||
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
|
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
@Version
|
@Version
|
||||||
@ -122,15 +131,15 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTaggedMemberNumber() {
|
|
||||||
return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse("M-???????");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTaggedMemberNumber() {
|
||||||
|
return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse("M-???????");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return "%s:%.3s:%+1.2f".formatted(
|
return "%s:%.3s:%+1.2f".formatted(
|
||||||
@ -141,7 +150,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
|||||||
|
|
||||||
public static RbacSpec rbac() {
|
public static RbacSpec rbac() {
|
||||||
return rbacViewFor("coopAssetsTransaction", HsOfficeCoopAssetsTransactionEntity.class)
|
return rbacViewFor("coopAssetsTransaction", HsOfficeCoopAssetsTransactionEntity.class)
|
||||||
.withIdentityView(RbacSpec.SQL.projection("reference"))
|
.withIdentityView(SQL.projection("reference"))
|
||||||
.withUpdatableColumns("comment")
|
.withUpdatableColumns("comment")
|
||||||
.importEntityAlias("membership", HsOfficeMembershipEntity.class, usingDefaultCase(),
|
.importEntityAlias("membership", HsOfficeMembershipEntity.class, usingDefaultCase(),
|
||||||
dependsOnColumn("membershipUuid"),
|
dependsOnColumn("membershipUuid"),
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||||
|
|
||||||
import jakarta.persistence.EntityNotFoundException;
|
|
||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource;
|
||||||
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
||||||
@ -25,6 +24,7 @@ import java.util.function.BiConsumer;
|
|||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION;
|
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION;
|
||||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION;
|
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION;
|
||||||
|
import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopSharesApi {
|
public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopSharesApi {
|
||||||
@ -33,14 +33,16 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo;
|
private HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsOfficeMembershipRepository membershipRepo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
|
|
||||||
@Timed("app.office.coopShares.api.getListOfCoopShares")
|
@Timed("app.office.coopShares.api.getListOfCoopShares")
|
||||||
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> getListOfCoopShares(
|
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> getListOfCoopShares(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
@ -55,7 +57,10 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
fromValueDate,
|
fromValueDate,
|
||||||
toValueDate);
|
toValueDate);
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficeCoopSharesTransactionResource.class);
|
final var resources = mapper.mapList(
|
||||||
|
entities,
|
||||||
|
HsOfficeCoopSharesTransactionResource.class,
|
||||||
|
ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(resources);
|
return ResponseEntity.ok(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +75,10 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
validate(requestBody);
|
validate(requestBody);
|
||||||
|
|
||||||
final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
final var entityToSave = mapper.map(
|
||||||
|
requestBody,
|
||||||
|
HsOfficeCoopSharesTransactionEntity.class,
|
||||||
|
RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||||
|
|
||||||
final var saved = coopSharesTransactionRepo.save(entityToSave);
|
final var saved = coopSharesTransactionRepo.save(entityToSave);
|
||||||
|
|
||||||
@ -79,7 +87,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
.path("/api/hs/office/coopsharestransactions/{id}")
|
.path("/api/hs/office/coopsharestransactions/{id}")
|
||||||
.buildAndExpand(saved.getUuid())
|
.buildAndExpand(saved.getUuid())
|
||||||
.toUri();
|
.toUri();
|
||||||
final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class);
|
final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.created(uri).body(mapped);
|
return ResponseEntity.created(uri).body(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,15 +95,18 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Timed("app.office.coopShares.repo.getSingleCoopShareTransactionByUuid")
|
@Timed("app.office.coopShares.repo.getSingleCoopShareTransactionByUuid")
|
||||||
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getSingleCoopShareTransactionByUuid(
|
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getSingleCoopShareTransactionByUuid(
|
||||||
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
|
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
|
||||||
|
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid);
|
final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid);
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeCoopSharesTransactionResource.class));
|
return ResponseEntity.ok(mapper.map(
|
||||||
|
result.get(),
|
||||||
|
HsOfficeCoopSharesTransactionResource.class,
|
||||||
|
ENTITY_TO_RESOURCE_POSTMAPPER));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +148,16 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BiConsumer<HsOfficeCoopSharesTransactionInsertResource, HsOfficeCoopSharesTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
final BiConsumer<HsOfficeCoopSharesTransactionInsertResource, HsOfficeCoopSharesTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
if ( resource.getRevertedShareTxUuid() != null ) {
|
entity.setMembership(resolve("membership.uuid", resource.getMembershipUuid(), membershipRepo::findByUuid));
|
||||||
entity.setRevertedShareTx(coopSharesTransactionRepo.findByUuid(resource.getRevertedShareTxUuid())
|
if (resource.getRevertedShareTxUuid() != null) {
|
||||||
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] revertedShareTxUuid %s not found".formatted(resource.getRevertedShareTxUuid()))));
|
entity.setRevertedShareTx(resolve(
|
||||||
|
"revertedShareTx.uuid",
|
||||||
|
resource.getRevertedShareTxUuid(),
|
||||||
|
coopSharesTransactionRepo::findByUuid));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
final BiConsumer<HsOfficeCoopSharesTransactionEntity, HsOfficeCoopSharesTransactionResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
|
resource.setMembershipUuid(entity.getMembership().getUuid());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,23 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.persistence.Version;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -132,6 +142,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseE
|
|||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
NOT_NULL)
|
NOT_NULL)
|
||||||
|
|
||||||
|
// the membership:ADMIN is not to be confused with the member itself, it's an account manager of the coop
|
||||||
.toRole("membership", ADMIN).grantPermission(INSERT)
|
.toRole("membership", ADMIN).grantPermission(INSERT)
|
||||||
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
||||||
.toRole("membership", AGENT).grantPermission(SELECT);
|
.toRole("membership", AGENT).grantPermission(SELECT);
|
||||||
|
@ -2,14 +2,16 @@ package net.hostsharing.hsadminng.hs.office.debitor;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource;
|
||||||
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.generated.api.v1.model.HsOfficeDebitorResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityExistsValidator;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -26,6 +28,7 @@ import java.util.UUID;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||||
|
import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve;
|
||||||
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ -36,16 +39,22 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeDebitorRepository debitorRepo;
|
private HsOfficeDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeRelationRealRepository relrealRepo;
|
private HsOfficeRelationRealRepository realRelRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EntityExistsValidator entityValidator;
|
private HsOfficePersonRealRepository realPersonRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsOfficeContactRealRepository realContactRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsOfficeBankAccountRepository bankAccountRepo;
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
@ -63,9 +72,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
|
|
||||||
final var entities = partnerNumber != null
|
final var entities = partnerNumber != null
|
||||||
? debitorRepo.findDebitorsByPartnerNumber(cropTag("P-", partnerNumber))
|
? debitorRepo.findDebitorsByPartnerNumber(cropTag("P-", partnerNumber))
|
||||||
: partnerUuid != null
|
: partnerUuid != null
|
||||||
? debitorRepo.findDebitorsByPartnerUuid(partnerUuid)
|
? debitorRepo.findDebitorsByPartnerUuid(partnerUuid)
|
||||||
: debitorRepo.findDebitorsByOptionalNameLike(name);
|
: debitorRepo.findDebitorsByOptionalNameLike(name);
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(resources);
|
return ResponseEntity.ok(resources);
|
||||||
@ -81,34 +90,19 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
|
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
|
Validate.isTrue(
|
||||||
|
body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
|
||||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
|
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
|
||||||
Validate.isTrue(body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
|
Validate.isTrue(
|
||||||
|
body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
|
||||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none");
|
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none");
|
||||||
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
|
Validate.isTrue(
|
||||||
|
body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
|
||||||
"ERROR: [400] debitorRel.mark must be null");
|
"ERROR: [400] debitorRel.mark must be null");
|
||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||||
if (body.getDebitorRel() != null) {
|
|
||||||
final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class);
|
|
||||||
debitorRel.setType(DEBITOR);
|
|
||||||
entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor());
|
|
||||||
entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder());
|
|
||||||
entityValidator.validateEntityExists("debitorRel.contactUuid", debitorRel.getContact());
|
|
||||||
entityToSave.setDebitorRel(relrealRepo.save(debitorRel));
|
|
||||||
} else {
|
|
||||||
final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid());
|
|
||||||
debitorRelOptional.ifPresentOrElse(
|
|
||||||
debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));},
|
|
||||||
() -> {
|
|
||||||
throw new ValidationException(
|
|
||||||
"Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
final var savedEntity = debitorRepo.save(entityToSave);
|
final var savedEntity = debitorRepo.save(entityToSave).reload(em);
|
||||||
em.flush();
|
|
||||||
em.refresh(savedEntity);
|
|
||||||
|
|
||||||
final var uri =
|
final var uri =
|
||||||
MvcUriComponentsBuilder.fromController(getClass())
|
MvcUriComponentsBuilder.fromController(getClass())
|
||||||
@ -181,7 +175,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
|
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow();
|
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow().reload(em);
|
||||||
|
|
||||||
new HsOfficeDebitorEntityPatcher(em, current).apply(body);
|
new HsOfficeDebitorEntityPatcher(em, current).apply(body);
|
||||||
|
|
||||||
@ -191,7 +185,39 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
return ResponseEntity.ok(mapped);
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final BiConsumer<HsOfficeDebitorInsertResource, HsOfficeDebitorEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
|
if (resource.getDebitorRel() != null) {
|
||||||
|
final var debitorRel = realRelRepo.save(HsOfficeRelationRealEntity.builder()
|
||||||
|
.type(DEBITOR)
|
||||||
|
.anchor(resolve(
|
||||||
|
"debitorRel.anchor.uuid", resource.getDebitorRel().getAnchorUuid(), realPersonRepo::findByUuid))
|
||||||
|
.holder(resolve(
|
||||||
|
"debitorRel.holder.uuid", resource.getDebitorRel().getHolderUuid(), realPersonRepo::findByUuid))
|
||||||
|
.contact(resolve(
|
||||||
|
"debitorRel.contact.uuid", resource.getDebitorRel().getContactUuid(), realContactRepo::findByUuid))
|
||||||
|
.build());
|
||||||
|
entity.setDebitorRel(debitorRel);
|
||||||
|
} else {
|
||||||
|
final var debitorRelOptional = realRelRepo.findByUuid(resource.getDebitorRelUuid());
|
||||||
|
debitorRelOptional.ifPresentOrElse(
|
||||||
|
debitorRel -> {
|
||||||
|
entity.setDebitorRel(realRelRepo.save(debitorRel));
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
throw new ValidationException(
|
||||||
|
"Unable to find debitorRel.uuid: " + resource.getDebitorRelUuid());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource.getRefundBankAccountUuid() != null) {
|
||||||
|
entity.setRefundBankAccount(resolve(
|
||||||
|
"refundBankAccount.uuid", resource.getRefundBankAccountUuid(), bankAccountRepo::findByUuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
final BiConsumer<HsOfficeDebitorEntity, HsOfficeDebitorResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
final BiConsumer<HsOfficeDebitorEntity, HsOfficeDebitorResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
resource.setDebitorNumber(entity.getTaggedDebitorNumber());
|
resource.setDebitorNumber(entity.getTaggedDebitorNumber());
|
||||||
|
resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartner;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||||
@ -16,7 +17,6 @@ import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
|||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
import org.hibernate.annotations.JoinFormula;
|
import org.hibernate.annotations.JoinFormula;
|
||||||
import org.hibernate.annotations.NotFound;
|
import org.hibernate.annotations.NotFound;
|
||||||
import org.hibernate.annotations.NotFoundAction;
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
@ -75,7 +75,6 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
|||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
|
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
@Version
|
@Version
|
||||||
@ -87,16 +86,16 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
|||||||
value = """
|
value = """
|
||||||
(
|
(
|
||||||
SELECT DISTINCT partner.uuid
|
SELECT DISTINCT partner.uuid
|
||||||
FROM hs_office.partner_rv partner
|
FROM hs_office.partner partner
|
||||||
JOIN hs_office.relation dRel
|
JOIN hs_office.relation dRel
|
||||||
ON dRel.uuid = debitorreluuid AND dRel.type = 'DEBITOR'
|
ON dRel.uuid = debitorRelUuid AND dRel.type = 'DEBITOR'
|
||||||
JOIN hs_office.relation pRel
|
JOIN hs_office.relation pRel
|
||||||
ON pRel.uuid = partner.partnerRelUuid AND pRel.type = 'PARTNER'
|
ON pRel.uuid = partner.partnerRelUuid AND pRel.type = 'PARTNER'
|
||||||
WHERE pRel.holderUuid = dRel.anchorUuid
|
WHERE pRel.holderUuid = dRel.anchorUuid
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
@NotFound(action = NotFoundAction.IGNORE) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number
|
@NotFound(action = NotFoundAction.EXCEPTION) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number
|
||||||
private HsOfficePartnerEntity partner;
|
private HsOfficePartnerRealEntity partner;
|
||||||
|
|
||||||
@Column(name = "debitornumbersuffix", length = 2)
|
@Column(name = "debitornumbersuffix", length = 2)
|
||||||
@Pattern(regexp = TWO_DECIMAL_DIGITS)
|
@Pattern(regexp = TWO_DECIMAL_DIGITS)
|
||||||
@ -132,9 +131,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
|||||||
@Override
|
@Override
|
||||||
public HsOfficeDebitorEntity load() {
|
public HsOfficeDebitorEntity load() {
|
||||||
BaseEntity.super.load();
|
BaseEntity.super.load();
|
||||||
if (partner != null) {
|
partner.load();
|
||||||
partner.load();
|
|
||||||
}
|
|
||||||
debitorRel.load();
|
debitorRel.load();
|
||||||
if (refundBankAccount != null) {
|
if (refundBankAccount != null) {
|
||||||
refundBankAccount.load();
|
refundBankAccount.load();
|
||||||
@ -145,7 +142,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
|||||||
public String getTaggedDebitorNumber() {
|
public String getTaggedDebitorNumber() {
|
||||||
return ofNullable(partner)
|
return ofNullable(partner)
|
||||||
.filter(partner -> debitorNumberSuffix != null)
|
.filter(partner -> debitorNumberSuffix != null)
|
||||||
.map(HsOfficePartnerEntity::getPartnerNumber)
|
.map(HsOfficePartner::getPartnerNumber)
|
||||||
.map(partnerNumber -> DEBITOR_NUMBER_TAG + partnerNumber + debitorNumberSuffix)
|
.map(partnerNumber -> DEBITOR_NUMBER_TAG + partnerNumber + debitorNumberSuffix)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
|||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||||
JOIN HsOfficePartnerEntity partner
|
JOIN HsOfficePartnerRealEntity partner
|
||||||
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
||||||
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
||||||
WHERE partner.partnerNumber = :partnerNumber
|
WHERE partner.partnerNumber = :partnerNumber
|
||||||
@ -42,7 +42,7 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
|||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||||
JOIN HsOfficePartnerEntity partner
|
JOIN HsOfficePartnerRealEntity partner
|
||||||
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
||||||
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
||||||
JOIN HsOfficePersonRealEntity person
|
JOIN HsOfficePersonRealEntity person
|
||||||
|
@ -6,14 +6,16 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeMembersh
|
|||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityNotFoundException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@ -28,7 +30,10 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsOfficePartnerRealRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeMembershipRepository membershipRepo;
|
private HsOfficeMembershipRepository membershipRepo;
|
||||||
@ -47,7 +52,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
|
|
||||||
final var entities = partnerNumber != null
|
final var entities = partnerNumber != null
|
||||||
? membershipRepo.findMembershipsByPartnerNumber(
|
? membershipRepo.findMembershipsByPartnerNumber(
|
||||||
cropTag(HsOfficePartnerEntity.PARTNER_NUMBER_TAG, partnerNumber))
|
cropTag(HsOfficePartnerRbacEntity.PARTNER_NUMBER_TAG, partnerNumber))
|
||||||
: partnerUuid != null
|
: partnerUuid != null
|
||||||
? membershipRepo.findMembershipsByPartnerUuid(partnerUuid)
|
? membershipRepo.findMembershipsByPartnerUuid(partnerUuid)
|
||||||
: membershipRepo.findAll();
|
: membershipRepo.findAll();
|
||||||
@ -68,7 +73,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
|
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class);
|
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||||
|
|
||||||
final var saved = membershipRepo.save(entityToSave);
|
final var saved = membershipRepo.save(entityToSave);
|
||||||
|
|
||||||
@ -164,5 +169,12 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
if (entity.getValidity().hasUpperBound()) {
|
if (entity.getValidity().hasUpperBound()) {
|
||||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||||
}
|
}
|
||||||
|
resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); // TODO.refa: use partner mapper?
|
||||||
|
};
|
||||||
|
|
||||||
|
final BiConsumer<HsOfficeMembershipInsertResource, HsOfficeMembershipEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
|
entity.setPartner(partnerRepo.findByUuid(resource.getPartnerUuid())
|
||||||
|
.orElseThrow(() -> new EntityNotFoundException(
|
||||||
|
"ERROR: [400] partnerUuid %s not found".formatted(resource.getPartnerUuid()))));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,12 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||||
|
import net.hostsharing.hsadminng.rbac.role.WithRoleId;
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
@ -63,7 +64,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayAs("Membership")
|
@DisplayAs("Membership")
|
||||||
public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable {
|
public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable, WithRoleId {
|
||||||
|
|
||||||
public static final String MEMBER_NUMBER_TAG = "M-";
|
public static final String MEMBER_NUMBER_TAG = "M-";
|
||||||
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
||||||
@ -84,7 +85,7 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
|||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "partneruuid")
|
@JoinColumn(name = "partneruuid")
|
||||||
private HsOfficePartnerEntity partner;
|
private HsOfficePartnerRealEntity partner;
|
||||||
|
|
||||||
@Column(name = "membernumbersuffix", length = 2)
|
@Column(name = "membernumbersuffix", length = 2)
|
||||||
@Pattern(regexp = TWO_DECIMAL_DIGITS)
|
@Pattern(regexp = TWO_DECIMAL_DIGITS)
|
||||||
|
@ -2,18 +2,18 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
|
||||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||||
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class HsOfficeMembershipEntityPatcher implements EntityPatcher<HsOfficeMembershipPatchResource> {
|
public class HsOfficeMembershipEntityPatcher implements EntityPatcher<HsOfficeMembershipPatchResource> {
|
||||||
|
|
||||||
private final StandardMapper mapper;
|
private final StrictMapper mapper;
|
||||||
private final HsOfficeMembershipEntity entity;
|
private final HsOfficeMembershipEntity entity;
|
||||||
|
|
||||||
public HsOfficeMembershipEntityPatcher(
|
public HsOfficeMembershipEntityPatcher(
|
||||||
final StandardMapper mapper,
|
final StrictMapper mapper,
|
||||||
final HsOfficeMembershipEntity entity) {
|
final HsOfficeMembershipEntity entity) {
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePerson;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
import org.hibernate.annotations.NotFound;
|
||||||
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import jakarta.persistence.Version;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static jakarta.persistence.CascadeType.DETACH;
|
||||||
|
import static jakarta.persistence.CascadeType.MERGE;
|
||||||
|
import static jakarta.persistence.CascadeType.PERSIST;
|
||||||
|
import static jakarta.persistence.CascadeType.REFRESH;
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
|
@MappedSuperclass
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
|
@DisplayAs("Partner")
|
||||||
|
public class HsOfficePartner<T extends HsOfficePartner<?>> implements Stringifyable, BaseEntity<T> {
|
||||||
|
|
||||||
|
public static final String PARTNER_NUMBER_TAG = "P-";
|
||||||
|
|
||||||
|
protected static Stringify<HsOfficePartner> stringify = stringify(HsOfficePartner.class, "partner")
|
||||||
|
.withIdProp(HsOfficePartner::toShortString)
|
||||||
|
.withProp(p -> ofNullable(p.getPartnerRel())
|
||||||
|
.map(HsOfficeRelation::getHolder)
|
||||||
|
.map(HsOfficePerson::toShortString)
|
||||||
|
.orElse(null))
|
||||||
|
.withProp(p -> ofNullable(p.getPartnerRel())
|
||||||
|
.map(HsOfficeRelation::getContact)
|
||||||
|
.map(HsOfficeContact::toShortString)
|
||||||
|
.orElse(null))
|
||||||
|
.quotedValues(false);
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private UUID uuid;
|
||||||
|
|
||||||
|
@Version
|
||||||
|
private int version;
|
||||||
|
|
||||||
|
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
|
||||||
|
private Integer partnerNumber;
|
||||||
|
|
||||||
|
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "partnerreluuid", nullable = false)
|
||||||
|
private HsOfficeRelationRealEntity partnerRel;
|
||||||
|
|
||||||
|
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "detailsuuid")
|
||||||
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
|
private HsOfficePartnerDetailsEntity details;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T load() {
|
||||||
|
BaseEntity.super.load();
|
||||||
|
partnerRel.load();
|
||||||
|
if (details != null) {
|
||||||
|
details.load();
|
||||||
|
}
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaggedPartnerNumber() {
|
||||||
|
return PARTNER_NUMBER_TAG + partnerNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return stringify.apply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toShortString() {
|
||||||
|
return getTaggedPartnerNumber();
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@ -26,6 +26,7 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
||||||
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||||
@ -38,10 +39,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficePartnerRepository partnerRepo;
|
private HsOfficePartnerRbacRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeRelationRealRepository relationRepo;
|
private HsOfficeRelationRealRepository relationRepo;
|
||||||
@ -60,7 +61,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
|
|
||||||
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
|
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class);
|
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(resources);
|
return ResponseEntity.ok(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
.path("/api/hs/office/partners/{id}")
|
.path("/api/hs/office/partners/{id}")
|
||||||
.buildAndExpand(saved.getUuid())
|
.buildAndExpand(saved.getUuid())
|
||||||
.toUri();
|
.toUri();
|
||||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.created(uri).body(mapped);
|
return ResponseEntity.created(uri).body(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +102,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
|
final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -118,7 +120,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
|
final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -161,20 +164,20 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
final var saved = partnerRepo.save(current);
|
final var saved = partnerRepo.save(current);
|
||||||
optionallyCreateExPartnerRelation(saved, previousPartnerRel);
|
optionallyCreateExPartnerRelation(saved, previousPartnerRel);
|
||||||
|
|
||||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(mapped);
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
private void optionallyCreateExPartnerRelation(final HsOfficePartnerRbacEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
||||||
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
||||||
// TODO.impl: we also need to use the new partner-person as the anchor
|
// TODO.impl: we also need to use the new partner-person as the anchor
|
||||||
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
private HsOfficePartnerRbacEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
||||||
final var entityToSave = new HsOfficePartnerEntity();
|
final var entityToSave = new HsOfficePartnerRbacEntity();
|
||||||
entityToSave.setPartnerNumber(cropTag(HsOfficePartnerEntity.PARTNER_NUMBER_TAG, body.getPartnerNumber()));
|
entityToSave.setPartnerNumber(cropTag(HsOfficePartnerRbacEntity.PARTNER_NUMBER_TAG, body.getPartnerNumber()));
|
||||||
entityToSave.setPartnerRel(persistPartnerRel(body.getPartnerRel()));
|
entityToSave.setPartnerRel(persistPartnerRel(body.getPartnerRel()));
|
||||||
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
||||||
return entityToSave;
|
return entityToSave;
|
||||||
@ -197,4 +200,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
throw new ReferenceNotFoundException(entityClass, uuid, exc);
|
throw new ReferenceNotFoundException(entityClass, uuid, exc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final BiConsumer<HsOfficePartnerRbacEntity, HsOfficePartnerResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
|
resource.setPartnerNumber(entity.getTaggedPartnerNumber());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePerson;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
|
||||||
import net.hostsharing.hsadminng.repr.Stringify;
|
|
||||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
|
||||||
import org.hibernate.annotations.NotFound;
|
|
||||||
import org.hibernate.annotations.NotFoundAction;
|
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static jakarta.persistence.CascadeType.*;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Column.dependsOnColumn;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.ColumnValue.usingDefaultCase;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.GLOBAL;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.*;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.SELECT;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Role.*;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL.directlyFetchedByDependsOnColumn;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.rbacViewFor;
|
|
||||||
import static java.util.Optional.ofNullable;
|
|
||||||
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(schema = "hs_office", name = "partner_rv")
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@DisplayAs("Partner")
|
|
||||||
public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOfficePartnerEntity> {
|
|
||||||
|
|
||||||
public static final String PARTNER_NUMBER_TAG = "P-";
|
|
||||||
|
|
||||||
private static Stringify<HsOfficePartnerEntity> stringify = stringify(HsOfficePartnerEntity.class, "partner")
|
|
||||||
.withIdProp(HsOfficePartnerEntity::toShortString)
|
|
||||||
.withProp(p -> ofNullable(p.getPartnerRel())
|
|
||||||
.map(HsOfficeRelation::getHolder)
|
|
||||||
.map(HsOfficePerson::toShortString)
|
|
||||||
.orElse(null))
|
|
||||||
.withProp(p -> ofNullable(p.getPartnerRel())
|
|
||||||
.map(HsOfficeRelation::getContact)
|
|
||||||
.map(HsOfficeContact::toShortString)
|
|
||||||
.orElse(null))
|
|
||||||
.quotedValues(false);
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
private UUID uuid;
|
|
||||||
|
|
||||||
@Version
|
|
||||||
private int version;
|
|
||||||
|
|
||||||
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
|
|
||||||
private Integer partnerNumber;
|
|
||||||
|
|
||||||
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "partnerreluuid", nullable = false)
|
|
||||||
private HsOfficeRelationRealEntity partnerRel;
|
|
||||||
|
|
||||||
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "detailsuuid")
|
|
||||||
@NotFound(action = NotFoundAction.IGNORE)
|
|
||||||
private HsOfficePartnerDetailsEntity details;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HsOfficePartnerEntity load() {
|
|
||||||
BaseEntity.super.load();
|
|
||||||
partnerRel.load();
|
|
||||||
details.load();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTaggedPartnerNumber() {
|
|
||||||
return PARTNER_NUMBER_TAG + partnerNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return stringify.apply(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toShortString() {
|
|
||||||
return getTaggedPartnerNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RbacSpec rbac() {
|
|
||||||
return rbacViewFor("partner", HsOfficePartnerEntity.class)
|
|
||||||
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
|
|
||||||
.withUpdatableColumns("partnerRelUuid")
|
|
||||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
|
||||||
|
|
||||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
|
|
||||||
usingDefaultCase(),
|
|
||||||
directlyFetchedByDependsOnColumn(),
|
|
||||||
dependsOnColumn("partnerRelUuid"))
|
|
||||||
.createPermission(DELETE).grantedTo("partnerRel", OWNER)
|
|
||||||
.createPermission(UPDATE).grantedTo("partnerRel", ADMIN)
|
|
||||||
.createPermission(SELECT).grantedTo("partnerRel", TENANT)
|
|
||||||
|
|
||||||
.importSubEntityAlias("partnerDetails", HsOfficePartnerDetailsEntity.class,
|
|
||||||
directlyFetchedByDependsOnColumn(),
|
|
||||||
dependsOnColumn("detailsUuid"))
|
|
||||||
.createPermission("partnerDetails", DELETE).grantedTo("partnerRel", OWNER)
|
|
||||||
.createPermission("partnerDetails", UPDATE).grantedTo("partnerRel", AGENT)
|
|
||||||
.createPermission("partnerDetails", SELECT).grantedTo("partnerRel", AGENT); // not TENANT!
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
rbac().generateWithBaseFileName("5-hs-office/504-partner/5043-hs-office-partner-rbac");
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,10 +9,10 @@ import jakarta.persistence.EntityManager;
|
|||||||
|
|
||||||
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
|
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
|
||||||
private final EntityManager em;
|
private final EntityManager em;
|
||||||
private final HsOfficePartnerEntity entity;
|
private final HsOfficePartnerRbacEntity entity;
|
||||||
HsOfficePartnerEntityPatcher(
|
HsOfficePartnerEntityPatcher(
|
||||||
final EntityManager em,
|
final EntityManager em,
|
||||||
final HsOfficePartnerEntity entity) {
|
final HsOfficePartnerRbacEntity entity) {
|
||||||
this.em = em;
|
this.em = em;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||||
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||||
|
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static jakarta.persistence.CascadeType.*;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Column.dependsOnColumn;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.ColumnValue.usingDefaultCase;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.GLOBAL;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.*;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.SELECT;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Role.*;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL.directlyFetchedByDependsOnColumn;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.rbacViewFor;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(schema = "hs_office", name = "partner_rv")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@DisplayAs("RbacPartner")
|
||||||
|
public class HsOfficePartnerRbacEntity extends HsOfficePartner<HsOfficePartnerRbacEntity> {
|
||||||
|
|
||||||
|
public static RbacSpec rbac() {
|
||||||
|
return rbacViewFor("partner", HsOfficePartnerRbacEntity.class)
|
||||||
|
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
|
||||||
|
.withUpdatableColumns("partnerRelUuid")
|
||||||
|
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||||
|
|
||||||
|
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
|
||||||
|
usingDefaultCase(),
|
||||||
|
directlyFetchedByDependsOnColumn(),
|
||||||
|
dependsOnColumn("partnerRelUuid"))
|
||||||
|
.createPermission(DELETE).grantedTo("partnerRel", OWNER)
|
||||||
|
.createPermission(UPDATE).grantedTo("partnerRel", ADMIN)
|
||||||
|
.createPermission(SELECT).grantedTo("partnerRel", TENANT)
|
||||||
|
|
||||||
|
.importSubEntityAlias("partnerDetails", HsOfficePartnerDetailsEntity.class,
|
||||||
|
directlyFetchedByDependsOnColumn(),
|
||||||
|
dependsOnColumn("detailsUuid"))
|
||||||
|
.createPermission("partnerDetails", DELETE).grantedTo("partnerRel", OWNER)
|
||||||
|
.createPermission("partnerDetails", UPDATE).grantedTo("partnerRel", AGENT)
|
||||||
|
.createPermission("partnerDetails", SELECT).grantedTo("partnerRel", AGENT); // not TENANT!
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
rbac().generateWithBaseFileName("5-hs-office/504-partner/5043-hs-office-partner-rbac");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
|
import io.micrometer.core.annotation.Timed;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface HsOfficePartnerRbacRepository extends Repository<HsOfficePartnerRbacEntity, UUID> {
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.findByUuid.rbac")
|
||||||
|
Optional<HsOfficePartnerRbacEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.findAll.rbac")
|
||||||
|
List<HsOfficePartnerRbacEntity> findAll(); // TODO.refa: move to a repo in test sources
|
||||||
|
|
||||||
|
@Query(value = """
|
||||||
|
select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version
|
||||||
|
from hs_office.partner_rv partner
|
||||||
|
join hs_office.relation partnerRel on partnerRel.uuid = partner.partnerreluuid
|
||||||
|
join hs_office.contact contact on contact.uuid = partnerRel.contactuuid
|
||||||
|
join hs_office.person partnerPerson on partnerPerson.uuid = partnerRel.holderuuid
|
||||||
|
left join hs_office.partner_details_rv partnerDetails on partnerDetails.uuid = partner.detailsuuid
|
||||||
|
where :name is null
|
||||||
|
or (partnerDetails.uuid is not null and partnerDetails.birthname like (cast(:name as text) || '%') escape '')
|
||||||
|
or contact.caption like (cast(:name as text) || '%') escape ''
|
||||||
|
or partnerPerson.tradename like (cast(:name as text) || '%') escape ''
|
||||||
|
or partnerPerson.givenname like (cast(:name as text) || '%') escape ''
|
||||||
|
or partnerPerson.familyname like (cast(:name as text) || '%') escape ''
|
||||||
|
""", nativeQuery = true)
|
||||||
|
@Timed("app.office.partners.repo.findPartnerByOptionalNameLike.rbac")
|
||||||
|
List<HsOfficePartnerRbacEntity> findPartnerByOptionalNameLike(String name);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.findPartnerByPartnerNumber.rbac")
|
||||||
|
Optional<HsOfficePartnerRbacEntity> findPartnerByPartnerNumber(Integer partnerNumber);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.save.rbac")
|
||||||
|
HsOfficePartnerRbacEntity save(final HsOfficePartnerRbacEntity entity);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.count.rbac")
|
||||||
|
long count();
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.deleteByUuid.rbac")
|
||||||
|
int deleteByUuid(UUID uuid);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(schema = "hs_office", name = "partner")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@DisplayAs("RealPartner")
|
||||||
|
public class HsOfficePartnerRealEntity extends HsOfficePartner<HsOfficePartnerRealEntity> {
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
|
import io.micrometer.core.annotation.Timed;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface HsOfficePartnerRealRepository extends Repository<HsOfficePartnerRealEntity, UUID> {
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.findByUuid.real")
|
||||||
|
Optional<HsOfficePartnerRealEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.findAll.real")
|
||||||
|
List<HsOfficePartnerRbacEntity> findAll(); // TODO.refa: move to a repo in test sources
|
||||||
|
|
||||||
|
@Query(value = """
|
||||||
|
select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version
|
||||||
|
from hs_office.partner partner
|
||||||
|
join hs_office.relation partnerRel on partnerRel.uuid = partner.partnerreluuid
|
||||||
|
join hs_office.contact contact on contact.uuid = partnerRel.contactuuid
|
||||||
|
join hs_office.person partnerPerson on partnerPerson.uuid = partnerRel.holderuuid
|
||||||
|
left join hs_office.partner_details_rv partnerDetails on partnerDetails.uuid = partner.detailsuuid
|
||||||
|
where :name is null
|
||||||
|
or (partnerDetails.uuid is not null and partnerDetails.birthname like (cast(:name as text) || '%') escape '')
|
||||||
|
or contact.caption like (cast(:name as text) || '%') escape ''
|
||||||
|
or partnerPerson.tradename like (cast(:name as text) || '%') escape ''
|
||||||
|
or partnerPerson.givenname like (cast(:name as text) || '%') escape ''
|
||||||
|
or partnerPerson.familyname like (cast(:name as text) || '%') escape ''
|
||||||
|
""", nativeQuery = true)
|
||||||
|
@Timed("app.office.partners.repo.findPartnerByOptionalNameLike.real")
|
||||||
|
List<HsOfficePartnerRealEntity> findPartnerByOptionalNameLike(String name);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.findPartnerByPartnerNumber.real")
|
||||||
|
Optional<HsOfficePartnerRealEntity> findPartnerByPartnerNumber(Integer partnerNumber);
|
||||||
|
|
||||||
|
@Timed("app.office.partners.repo.save.real")
|
||||||
|
HsOfficePartnerRealEntity save(final HsOfficePartnerRealEntity entity);
|
||||||
|
}
|
@ -1,45 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
|
||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.Repository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEntity, UUID> {
|
|
||||||
|
|
||||||
@Timed("app.office.partners.repo.findByUuid")
|
|
||||||
Optional<HsOfficePartnerEntity> findByUuid(UUID id);
|
|
||||||
|
|
||||||
@Timed("app.office.partners.repo.findAll")
|
|
||||||
List<HsOfficePartnerEntity> findAll(); // TODO.refa: move to a repo in test sources
|
|
||||||
|
|
||||||
@Query("""
|
|
||||||
SELECT partner FROM HsOfficePartnerEntity partner
|
|
||||||
JOIN HsOfficeRelationRealEntity rel ON rel.uuid = partner.partnerRel.uuid
|
|
||||||
JOIN HsOfficeContactRealEntity contact ON contact.uuid = rel.contact.uuid
|
|
||||||
JOIN HsOfficePersonRealEntity person ON person.uuid = rel.holder.uuid
|
|
||||||
WHERE :name is null
|
|
||||||
OR partner.details.birthName like concat(cast(:name as text), '%')
|
|
||||||
OR contact.caption like concat(cast(:name as text), '%')
|
|
||||||
OR person.tradeName like concat(cast(:name as text), '%')
|
|
||||||
OR person.givenName like concat(cast(:name as text), '%')
|
|
||||||
OR person.familyName like concat(cast(:name as text), '%')
|
|
||||||
""")
|
|
||||||
@Timed("app.office.partners.repo.findPartnerByOptionalNameLike")
|
|
||||||
List<HsOfficePartnerEntity> findPartnerByOptionalNameLike(String name);
|
|
||||||
|
|
||||||
@Timed("app.office.partners.repo.findPartnerByPartnerNumber")
|
|
||||||
Optional<HsOfficePartnerEntity> findPartnerByPartnerNumber(Integer partnerNumber);
|
|
||||||
|
|
||||||
@Timed("app.office.partners.repo.save")
|
|
||||||
HsOfficePartnerEntity save(final HsOfficePartnerEntity entity);
|
|
||||||
|
|
||||||
@Timed("app.office.partners.repo.count")
|
|
||||||
long count();
|
|
||||||
|
|
||||||
@Timed("app.office.partners.repo.deleteByUuid")
|
|
||||||
int deleteByUuid(UUID uuid);
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.person;
|
package net.hostsharing.hsadminng.hs.office.person;
|
||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePersonsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePersonsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
||||||
@ -24,7 +24,7 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficePersonRbacRepository personRepo;
|
private HsOfficePersonRbacRepository personRepo;
|
||||||
|
@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.office.person;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.FieldNameConstants;
|
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
|
||||||
@ -17,7 +16,6 @@ import jakarta.persistence.Table;
|
|||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@SuperBuilder(toBuilder = true)
|
@SuperBuilder(toBuilder = true)
|
||||||
@FieldNameConstants
|
|
||||||
@DisplayAs("RealPerson")
|
@DisplayAs("RealPerson")
|
||||||
public class HsOfficePersonRealEntity extends HsOfficePerson<HsOfficePersonRealEntity> {
|
public class HsOfficePersonRealEntity extends HsOfficePerson<HsOfficePersonRealEntity> {
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeRelation
|
|||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -32,7 +32,7 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeRelationRbacRepository rbacRelationRepo;
|
private HsOfficeRelationRbacRepository rbacRelationRepo;
|
||||||
|
@ -2,11 +2,14 @@ package net.hostsharing.hsadminng.hs.office.sepamandate;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandatePatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandatePatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateResource;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -15,6 +18,7 @@ import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBui
|
|||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
import jakarta.validation.ValidationException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@ -29,7 +33,13 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsOfficeDebitorRepository debitorRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsOfficeBankAccountRepository bankAccountRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeSepaMandateRepository sepaMandateRepo;
|
private HsOfficeSepaMandateRepository sepaMandateRepo;
|
||||||
@ -137,10 +147,22 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
|||||||
if (entity.getValidity().hasUpperBound()) {
|
if (entity.getValidity().hasUpperBound()) {
|
||||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||||
}
|
}
|
||||||
|
resource.setDebitor(mapper.map(entity.getDebitor(), HsOfficeDebitorResource.class));
|
||||||
resource.getDebitor().setDebitorNumber(entity.getDebitor().getTaggedDebitorNumber());
|
resource.getDebitor().setDebitorNumber(entity.getDebitor().getTaggedDebitorNumber());
|
||||||
|
resource.getDebitor().getPartner().setPartnerNumber(entity.getDebitor().getPartner().getTaggedPartnerNumber());
|
||||||
};
|
};
|
||||||
|
|
||||||
final BiConsumer<HsOfficeSepaMandateInsertResource, HsOfficeSepaMandateEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
final BiConsumer<HsOfficeSepaMandateInsertResource, HsOfficeSepaMandateEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
entity.setValidity(toPostgresDateRange(resource.getValidFrom(), resource.getValidTo()));
|
entity.setValidity(toPostgresDateRange(resource.getValidFrom(), resource.getValidTo()));
|
||||||
|
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid()).orElseThrow( () ->
|
||||||
|
new ValidationException(
|
||||||
|
"debitor.uuid='" + resource.getDebitorUuid() + "' not found or not accessible"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
entity.setBankAccount(bankAccountRepo.findByUuid(resource.getBankAccountUuid()).orElseThrow( () ->
|
||||||
|
new ValidationException(
|
||||||
|
"bankAccount.uuid='" + resource.getBankAccountUuid() + "' not found or not accessible"
|
||||||
|
)
|
||||||
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.validation;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import jakarta.validation.ValidationException;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class UuidResolver {
|
||||||
|
|
||||||
|
public static <T> T resolve(final String jsonPath, final UUID uuid, final Function<UUID, Optional<T>> findByUuid) {
|
||||||
|
return findByUuid.apply(uuid)
|
||||||
|
.orElseThrow(() -> new ValidationException("Unable to find " + jsonPath + ": " + uuid));
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.mapper;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A nicer API for ModelMapper in standard mode.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class StandardMapper extends Mapper {
|
|
||||||
|
|
||||||
public StandardMapper(@Autowired final EntityManagerWrapper em) {
|
|
||||||
super(em);
|
|
||||||
getConfiguration().setAmbiguityIgnored(true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.persistence;
|
|||||||
|
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface BaseEntity<T extends BaseEntity<?>> {
|
public interface BaseEntity<T extends BaseEntity<?>> {
|
||||||
@ -15,4 +16,10 @@ public interface BaseEntity<T extends BaseEntity<?>> {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (T) this;
|
return (T) this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
default T reload(final EntityManager em) {
|
||||||
|
em.flush();
|
||||||
|
em.refresh(this);
|
||||||
|
return load();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.persistence;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs.DisplayName;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.validation.ValidationException;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class EntityExistsValidator {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private EntityManagerWrapper em;
|
|
||||||
|
|
||||||
public <T extends BaseEntity<T>> void validateEntityExists(final String property, final T entitySkeleton) {
|
|
||||||
final var foundEntity = em.find(entityClass(entitySkeleton), entitySkeleton.getUuid());
|
|
||||||
if ( foundEntity == null) {
|
|
||||||
throw new ValidationException("Unable to find " + DisplayName.of(entitySkeleton) + " by " + property + ": " + entitySkeleton.getUuid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T extends BaseEntity<T>> Class<?> entityClass(final T entityOrProxy) {
|
|
||||||
final var entityClass = entityClass(entityOrProxy.getClass());
|
|
||||||
if (entityClass == null) {
|
|
||||||
throw new IllegalArgumentException("@Entity not found in superclass hierarchy of " + entityOrProxy.getClass());
|
|
||||||
}
|
|
||||||
return entityClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?> entityClass(final Class<?> entityOrProxyClass) {
|
|
||||||
return entityOrProxyClass.isAnnotationPresent(Entity.class)
|
|
||||||
? entityOrProxyClass
|
|
||||||
: entityOrProxyClass.getSuperclass() == null
|
|
||||||
? null
|
|
||||||
: entityClass(entityOrProxyClass.getSuperclass());
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.grant;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacGrantsApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacGrantsApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacGrantResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacGrantResource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -23,7 +23,7 @@ public class RbacGrantController implements RbacGrantsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RbacGrantRepository rbacGrantRepository;
|
private RbacGrantRepository rbacGrantRepository;
|
||||||
|
@ -49,8 +49,18 @@ public class RbacGrantsDiagramService {
|
|||||||
NON_TEST_ENTITIES;
|
NON_TEST_ENTITIES;
|
||||||
|
|
||||||
public static final EnumSet<Include> ALL = EnumSet.allOf(Include.class);
|
public static final EnumSet<Include> ALL = EnumSet.allOf(Include.class);
|
||||||
public static final EnumSet<Include> ALL_TEST_ENTITY_RELATED = EnumSet.of(USERS, DETAILS, NOT_ASSUMED, TEST_ENTITIES, PERMISSIONS);
|
public static final EnumSet<Include> ALL_TEST_ENTITY_RELATED = EnumSet.of(
|
||||||
public static final EnumSet<Include> ALL_NON_TEST_ENTITY_RELATED = EnumSet.of(USERS, DETAILS, NOT_ASSUMED, NON_TEST_ENTITIES, PERMISSIONS);
|
USERS,
|
||||||
|
DETAILS,
|
||||||
|
NOT_ASSUMED,
|
||||||
|
TEST_ENTITIES,
|
||||||
|
PERMISSIONS);
|
||||||
|
public static final EnumSet<Include> ALL_NON_TEST_ENTITY_RELATED = EnumSet.of(
|
||||||
|
USERS,
|
||||||
|
DETAILS,
|
||||||
|
NOT_ASSUMED,
|
||||||
|
NON_TEST_ENTITIES,
|
||||||
|
PERMISSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -66,9 +76,9 @@ public class RbacGrantsDiagramService {
|
|||||||
|
|
||||||
public String allGrantsTocurrentSubject(final EnumSet<Include> includes) {
|
public String allGrantsTocurrentSubject(final EnumSet<Include> includes) {
|
||||||
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
||||||
for ( UUID subjectUuid: context.fetchCurrentSubjectOrAssumedRolesUuids() ) {
|
for (UUID subjectUuid : context.fetchCurrentSubjectOrAssumedRolesUuids()) {
|
||||||
traverseGrantsTo(graph, subjectUuid, includes);
|
traverseGrantsTo(graph, subjectUuid, includes);
|
||||||
}
|
}
|
||||||
return toMermaidFlowchart(graph, includes);
|
return toMermaidFlowchart(graph, includes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +88,7 @@ public class RbacGrantsDiagramService {
|
|||||||
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
|
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( !g.getDescendantIdName().startsWith("role:rbac.global")) {
|
if (!g.getDescendantIdName().startsWith("role:rbac.global")) {
|
||||||
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":rbactest.")) {
|
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":rbactest.")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -94,12 +104,17 @@ public class RbacGrantsDiagramService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
||||||
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op")
|
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") // List -> List<List<UUID>>
|
||||||
|
final var refUuidLists = (List<List<UUID>>) em.createNativeQuery(
|
||||||
|
"select uuid from rbac.permission where objectUuid=:targetObject and op=:op",
|
||||||
|
List.class)
|
||||||
.setParameter("targetObject", targetObject)
|
.setParameter("targetObject", targetObject)
|
||||||
.setParameter("op", op)
|
.setParameter("op", op)
|
||||||
.getSingleResult();
|
.getResultList();
|
||||||
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
refUuidLists.stream().flatMap(Collection::stream)
|
||||||
traverseGrantsFrom(graph, refUuid, includes);
|
.forEach(refUuid -> traverseGrantsFrom(graph, refUuid, includes));
|
||||||
return toMermaidFlowchart(graph, includes);
|
return toMermaidFlowchart(graph, includes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,20 +140,20 @@ public class RbacGrantsDiagramService {
|
|||||||
final var entities =
|
final var entities =
|
||||||
includes.contains(DETAILS)
|
includes.contains(DETAILS)
|
||||||
? graph.stream()
|
? graph.stream()
|
||||||
.flatMap(g -> Stream.of(
|
.flatMap(g -> Stream.of(
|
||||||
new Node(g.getAscendantIdName(), g.getAscendingUuid()),
|
new Node(g.getAscendantIdName(), g.getAscendingUuid()),
|
||||||
new Node(g.getDescendantIdName(), g.getDescendantUuid()))
|
new Node(g.getDescendantIdName(), g.getDescendantUuid()))
|
||||||
)
|
)
|
||||||
.collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName))
|
.collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName))
|
||||||
.entrySet().stream()
|
.entrySet().stream()
|
||||||
.map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
.map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
||||||
+ entity.getValue().stream()
|
+ entity.getValue().stream()
|
||||||
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
||||||
.sorted()
|
.sorted()
|
||||||
.distinct()
|
.distinct()
|
||||||
.collect(joining("\n\n ")))
|
.collect(joining("\n\n ")))
|
||||||
.collect(joining("\n\nend\n\n"))
|
.collect(joining("\n\nend\n\n"))
|
||||||
+ "\n\nend\n\n"
|
+ "\n\nend\n\n"
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
final var grants = graph.stream()
|
final var grants = graph.stream()
|
||||||
@ -193,7 +208,7 @@ public class RbacGrantsDiagramService {
|
|||||||
final var refType = refType(idName);
|
final var refType = refType(idName);
|
||||||
|
|
||||||
if (refType.equals("user")) {
|
if (refType.equals("user")) {
|
||||||
final var displayName = idName.substring(refType.length()+1);
|
final var displayName = idName.substring(refType.length() + 1);
|
||||||
return "(" + displayName + "\nref:" + uuid + ")";
|
return "(" + displayName + "\nref:" + uuid + ")";
|
||||||
}
|
}
|
||||||
if (refType.equals("role")) {
|
if (refType.equals("role")) {
|
||||||
@ -215,15 +230,20 @@ public class RbacGrantsDiagramService {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private static String cleanId(final String idName) {
|
private static String cleanId(final String idName) {
|
||||||
return idName.replaceAll("@.*", "")
|
return idName.replaceAll("@.*", "")
|
||||||
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "").replace(">", ":").replace("|", "_");
|
.replace("[", "")
|
||||||
|
.replace("]", "")
|
||||||
|
.replace("(", "")
|
||||||
|
.replace(")", "")
|
||||||
|
.replace(",", "")
|
||||||
|
.replace(">", ":")
|
||||||
|
.replace("|", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static class LimitedHashSet<T> extends HashSet<T> {
|
static class LimitedHashSet<T> extends HashSet<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(final T t) {
|
public boolean add(final T t) {
|
||||||
if (size() < GRANT_LIMIT ) {
|
if (size() < GRANT_LIMIT) {
|
||||||
return super.add(t);
|
return super.add(t);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.role;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacRolesApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacRolesApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacRoleResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacRoleResource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -19,7 +19,7 @@ public class RbacRoleController implements RbacRolesApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RbacRoleRepository rbacRoleRepository;
|
private RbacRoleRepository rbacRoleRepository;
|
||||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.subject;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectResource;
|
||||||
@ -22,7 +22,7 @@ public class RbacSubjectController implements RbacSubjectsApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RbacSubjectRepository rbacSubjectRepository;
|
private RbacSubjectRepository rbacSubjectRepository;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.rbac.test.cust;
|
package net.hostsharing.hsadminng.rbac.test.cust;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestCustomersApi;
|
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestCustomersApi;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestCustomerResource;
|
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestCustomerResource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -21,7 +21,7 @@ public class TestCustomerController implements TestCustomersApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TestCustomerRepository testCustomerRepository;
|
private TestCustomerRepository testCustomerRepository;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.rbac.test.pac;
|
package net.hostsharing.hsadminng.rbac.test.pac;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestPackagesApi;
|
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestPackagesApi;
|
||||||
@ -21,7 +21,7 @@ public class TestPackageController implements TestPackagesApi {
|
|||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StandardMapper mapper;
|
private StrictMapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TestPackageRepository testPackageRepository;
|
private TestPackageRepository testPackageRepository;
|
||||||
|
@ -90,6 +90,7 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
vatReverseCharge:
|
vatReverseCharge:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
# TODO.feat: alternatively the complete refundBankAccount
|
||||||
refundBankAccount.uuid:
|
refundBankAccount.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
@ -43,7 +43,10 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call base.defineContext('creating coopSharesTransaction test-data');
|
call base.defineContext('creating coopSharesTransaction test-data',
|
||||||
|
null,
|
||||||
|
'superuser-alex@hostsharing.net',
|
||||||
|
'rbac.global#global:ADMIN');
|
||||||
SET CONSTRAINTS ALL DEFERRED;
|
SET CONSTRAINTS ALL DEFERRED;
|
||||||
|
|
||||||
call hs_office.coopsharetx_create_test_data(10001, '01');
|
call hs_office.coopsharetx_create_test_data(10001, '01');
|
||||||
|
@ -49,7 +49,10 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call base.defineContext('creating coopAssetsTransaction test-data');
|
call base.defineContext('creating coopAssetsTransaction test-data',
|
||||||
|
null,
|
||||||
|
'superuser-alex@hostsharing.net',
|
||||||
|
'rbac.global#global:ADMIN');
|
||||||
SET CONSTRAINTS ALL DEFERRED;
|
SET CONSTRAINTS ALL DEFERRED;
|
||||||
|
|
||||||
call hs_office.coopassettx_create_test_data(10001, '01');
|
call hs_office.coopassettx_create_test_data(10001, '01');
|
||||||
|
@ -81,8 +81,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
|
|||||||
void handleJpaObjectRetrievalFailureExceptionWithDisplayName() {
|
void handleJpaObjectRetrievalFailureExceptionWithDisplayName() {
|
||||||
// given
|
// given
|
||||||
final var givenException = new JpaObjectRetrievalFailureException(
|
final var givenException = new JpaObjectRetrievalFailureException(
|
||||||
new EntityNotFoundException(
|
new EntityNotFoundException("Unable to find Entity with id 12345-123454")
|
||||||
"Unable to find net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity with id 12345-123454")
|
|
||||||
);
|
);
|
||||||
final var givenWebRequest = mock(WebRequest.class);
|
final var givenWebRequest = mock(WebRequest.class);
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
|
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
|
||||||
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Partner with uuid 12345-123454");
|
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Entity with id 12345-123454");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -643,7 +643,6 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
|
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
final var newBookingItem = HsBookingItemRealEntity.builder()
|
final var newBookingItem = HsBookingItemRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.project(givenProject)
|
.project(givenProject)
|
||||||
.type(hsBookingItemType)
|
.type(hsBookingItemType)
|
||||||
.caption("some test-booking")
|
.caption("some test-booking")
|
||||||
|
@ -14,7 +14,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.context.TestConfiguration;
|
import org.springframework.boot.test.context.TestConfiguration;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@ -48,23 +48,23 @@ class HsBookingItemControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||||
StrictMapper mapper;
|
StrictMapper mapper;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerWrapper em;
|
EntityManagerWrapper em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerFactory emf;
|
EntityManagerFactory emf;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsBookingProjectRealRepository realProjectRepo;
|
HsBookingProjectRealRepository realProjectRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsBookingItemRbacRepository rbacBookingItemRepo;
|
HsBookingItemRbacRepository rbacBookingItemRepo;
|
||||||
|
|
||||||
@TestConfiguration
|
@TestConfiguration
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
|||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -270,7 +270,6 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
|
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
|
||||||
final var newBookingProject = HsBookingProjectRealEntity.builder()
|
final var newBookingProject = HsBookingProjectRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.debitor(givenDebitor)
|
.debitor(givenDebitor)
|
||||||
.caption(caption)
|
.caption(caption)
|
||||||
.build();
|
.build();
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -488,7 +488,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||||
HsHostingAssetRealEntity.builder()
|
HsHostingAssetRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.bookingItem(givenSomeNewBookingItem(
|
.bookingItem(givenSomeNewBookingItem(
|
||||||
"D-1000111 default project",
|
"D-1000111 default project",
|
||||||
HsBookingItemType.MANAGED_SERVER,
|
HsBookingItemType.MANAGED_SERVER,
|
||||||
@ -571,7 +570,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||||
HsHostingAssetRealEntity.builder()
|
HsHostingAssetRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.type(UNIX_USER)
|
.type(UNIX_USER)
|
||||||
.parentAsset(givenRealHostingAsset(MANAGED_WEBSPACE, "fir01"))
|
.parentAsset(givenRealHostingAsset(MANAGED_WEBSPACE, "fir01"))
|
||||||
.identifier("fir01-temp")
|
.identifier("fir01-temp")
|
||||||
@ -648,7 +646,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||||
HsHostingAssetRealEntity.builder()
|
HsHostingAssetRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.bookingItem(givenSomeNewBookingItem(
|
.bookingItem(givenSomeNewBookingItem(
|
||||||
"D-1000111 default project",
|
"D-1000111 default project",
|
||||||
HsBookingItemType.MANAGED_SERVER,
|
HsBookingItemType.MANAGED_SERVER,
|
||||||
@ -681,7 +678,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||||
HsHostingAssetRealEntity.builder()
|
HsHostingAssetRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.bookingItem(givenSomeNewBookingItem(
|
.bookingItem(givenSomeNewBookingItem(
|
||||||
"D-1000111 default project",
|
"D-1000111 default project",
|
||||||
HsBookingItemType.MANAGED_SERVER,
|
HsBookingItemType.MANAGED_SERVER,
|
||||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -24,7 +24,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsHostingAssetController.class)
|
@WebMvcTest(HsHostingAssetController.class)
|
||||||
@Import({ StandardMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class })
|
@Import({ StrictMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class })
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
public class HsHostingAssetControllerRestTest {
|
public class HsHostingAssetControllerRestTest {
|
||||||
@ -62,27 +62,27 @@ public class HsHostingAssetControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||||
StandardMapper mapper;
|
StrictMapper mapper;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerWrapper em;
|
EntityManagerWrapper em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerFactory emf;
|
EntityManagerFactory emf;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
@SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController
|
@SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController
|
||||||
private HsBookingItemRealRepository realBookingItemRepo;
|
private HsBookingItemRealRepository realBookingItemRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
private HsHostingAssetRealRepository realAssetRepo;
|
private HsHostingAssetRealRepository realAssetRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
private HsHostingAssetRbacRepository rbacAssetRepo;
|
private HsHostingAssetRbacRepository rbacAssetRepo;
|
||||||
|
|
||||||
@TestConfiguration
|
@TestConfiguration
|
||||||
|
@ -17,7 +17,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -12,7 +12,7 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@ -59,7 +59,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
|||||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private StandardMapper standardMapper = new StandardMapper(emw);
|
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private HsBookingItemCreatedListener listener;
|
private HsBookingItemCreatedListener listener;
|
||||||
|
@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedEventEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@ -42,7 +42,7 @@ class HsBookingItemCreatedListenerUnitTest {
|
|||||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private StandardMapper standardMapper = new StandardMapper(emw);
|
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private HsBookingItemCreatedListener listener;
|
private HsBookingItemCreatedListener listener;
|
||||||
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns;
|
|||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -55,7 +55,7 @@ class ManagedWebspaceHostingAssetFactoryUnitTest {
|
|||||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private StandardMapper standardMapper = new StandardMapper(emw);
|
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private HsBookingItemCreatedListener listener;
|
private HsBookingItemCreatedListener listener;
|
||||||
|
@ -10,7 +10,7 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus;
|
||||||
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.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||||
@ -84,7 +84,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
|
|
||||||
static Map<Integer, HsOfficeContactRealEntity> contacts = new WriteOnceMap<>();
|
static Map<Integer, HsOfficeContactRealEntity> contacts = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsOfficePersonRealEntity> persons = new WriteOnceMap<>();
|
static Map<Integer, HsOfficePersonRealEntity> persons = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsOfficePartnerEntity> partners = new WriteOnceMap<>();
|
static Map<Integer, HsOfficePartnerRealEntity> partners = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsOfficeDebitorEntity> debitors = new WriteOnceMap<>();
|
static Map<Integer, HsOfficeDebitorEntity> debitors = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsOfficeMembershipEntity> memberships = new WriteOnceMap<>();
|
static Map<Integer, HsOfficeMembershipEntity> memberships = new WriteOnceMap<>();
|
||||||
|
|
||||||
@ -743,7 +743,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
null // is set during contacts import depending on assigned roles
|
null // is set during contacts import depending on assigned roles
|
||||||
);
|
);
|
||||||
|
|
||||||
final var partner = HsOfficePartnerEntity.builder()
|
final var partner = HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(rec.getInteger("member_id"))
|
.partnerNumber(rec.getInteger("member_id"))
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
.partnerRel(partnerRel)
|
.partnerRel(partnerRel)
|
||||||
|
@ -14,7 +14,7 @@ import org.junit.jupiter.api.extension.TestWatcher;
|
|||||||
import org.opentest4j.AssertionFailedError;
|
import org.opentest4j.AssertionFailedError;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
static final LinkedHashSet<String> errors = new LinkedHashSet<>();
|
static final LinkedHashSet<String> errors = new LinkedHashSet<>();
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
@ -26,14 +26,14 @@ class HsOfficeBankAccountControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||||
StandardMapper mapper;
|
StrictMapper mapper;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficeBankAccountRepository bankAccountRepo;
|
HsOfficeBankAccountRepository bankAccountRepo;
|
||||||
|
|
||||||
enum InvalidIbanTestCase {
|
enum InvalidIbanTestCase {
|
||||||
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -46,7 +46,7 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -384,7 +384,6 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define(creatingUser);
|
context.define(creatingUser);
|
||||||
final var newContact = HsOfficeContactRbacEntity.builder()
|
final var newContact = HsOfficeContactRbacEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.caption("Temp from " + Context.getCallerMethodNameFromStackFrame(1) )
|
.caption("Temp from " + Context.getCallerMethodNameFromStackFrame(1) )
|
||||||
.postalAddress(Map.ofEntries(
|
.postalAddress(Map.ofEntries(
|
||||||
entry("name", RandomStringUtils.randomAlphabetic(6) + " " + RandomStringUtils.randomAlphabetic(10)),
|
entry("name", RandomStringUtils.randomAlphabetic(6) + " " + RandomStringUtils.randomAlphabetic(10)),
|
||||||
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -46,7 +46,7 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
||||||
@ -17,10 +17,10 @@ import org.junit.jupiter.params.provider.EnumSource;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
@ -67,7 +67,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
private static final String ORIGIN_MEMBER_NUMBER = "M-1111100";
|
private static final String ORIGIN_MEMBER_NUMBER = "M-1111100";
|
||||||
public final HsOfficeMembershipEntity ORIGIN_TARGET_MEMBER_ENTITY = HsOfficeMembershipEntity.builder()
|
public final HsOfficeMembershipEntity ORIGIN_TARGET_MEMBER_ENTITY = HsOfficeMembershipEntity.builder()
|
||||||
.uuid(ORIGIN_MEMBERSHIP_UUID)
|
.uuid(ORIGIN_MEMBERSHIP_UUID)
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(partnerNumberOf(ORIGIN_MEMBER_NUMBER))
|
.partnerNumber(partnerNumberOf(ORIGIN_MEMBER_NUMBER))
|
||||||
.build())
|
.build())
|
||||||
.memberNumberSuffix(suffixOf(ORIGIN_MEMBER_NUMBER))
|
.memberNumberSuffix(suffixOf(ORIGIN_MEMBER_NUMBER))
|
||||||
@ -77,7 +77,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
private static final String AVAILABLE_TARGET_MEMBER_NUMBER = "M-1234500";
|
private static final String AVAILABLE_TARGET_MEMBER_NUMBER = "M-1234500";
|
||||||
public final HsOfficeMembershipEntity AVAILABLE_MEMBER_ENTITY = HsOfficeMembershipEntity.builder()
|
public final HsOfficeMembershipEntity AVAILABLE_MEMBER_ENTITY = HsOfficeMembershipEntity.builder()
|
||||||
.uuid(AVAILABLE_TARGET_MEMBERSHIP_UUID)
|
.uuid(AVAILABLE_TARGET_MEMBERSHIP_UUID)
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(partnerNumberOf(AVAILABLE_TARGET_MEMBER_NUMBER))
|
.partnerNumber(partnerNumberOf(AVAILABLE_TARGET_MEMBER_NUMBER))
|
||||||
.build())
|
.build())
|
||||||
.memberNumberSuffix(suffixOf(AVAILABLE_TARGET_MEMBER_NUMBER))
|
.memberNumberSuffix(suffixOf(AVAILABLE_TARGET_MEMBER_NUMBER))
|
||||||
@ -499,20 +499,20 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||||
StrictMapper mapper;
|
StrictMapper mapper;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerWrapper emw; // even if not used in test anymore, it's needed by base-class of StrictMapper
|
EntityManagerWrapper emw; // even if not used in test anymore, it's needed by base-class of StrictMapper
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
|
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficeMembershipRepository membershipRepo;
|
HsOfficeMembershipRepository membershipRepo;
|
||||||
|
|
||||||
static final String INSERT_REQUEST_BODY_TEMPLATE = """
|
static final String INSERT_REQUEST_BODY_TEMPLATE = """
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -51,7 +51,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -170,7 +170,9 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given().header("current-subject", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body("""
|
.given()
|
||||||
|
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||||
|
.contentType(ContentType.JSON).body("""
|
||||||
{
|
{
|
||||||
"membership.uuid": "%s",
|
"membership.uuid": "%s",
|
||||||
"transactionType": "SUBSCRIPTION",
|
"transactionType": "SUBSCRIPTION",
|
||||||
@ -179,15 +181,29 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
"reference": "temp ref A",
|
"reference": "temp ref A",
|
||||||
"comment": "just some test coop shares transaction"
|
"comment": "just some test coop shares transaction"
|
||||||
}
|
}
|
||||||
""".formatted(givenMembership.getUuid())).port(port).when().post("http://localhost/api/hs/office/coopsharestransactions").then().log().all().assertThat().statusCode(201).contentType(ContentType.JSON).body("uuid", isUuidValid()).body("", lenientlyEquals("""
|
""".formatted(givenMembership.getUuid()))
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||||
|
.then()
|
||||||
|
.log().all()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(201)
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body("uuid", isUuidValid())
|
||||||
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
|
"membership.uuid": "%s",
|
||||||
"transactionType": "SUBSCRIPTION",
|
"transactionType": "SUBSCRIPTION",
|
||||||
"shareCount": 8,
|
"shareCount": 8,
|
||||||
"valueDate": "2022-10-13",
|
"valueDate": "2022-10-13",
|
||||||
"reference": "temp ref A",
|
"reference": "temp ref A",
|
||||||
"comment": "just some test coop shares transaction"
|
"comment": "just some test coop shares transaction"
|
||||||
}
|
}
|
||||||
""")).header("Location", startsWith("http://localhost")).extract().header("Location"); // @formatter:on
|
""".formatted(givenMembership.getUuid())))
|
||||||
|
.header("Location", startsWith("http://localhost"))
|
||||||
|
.extract()
|
||||||
|
.header("Location"); // @formatter:on
|
||||||
|
|
||||||
// finally, the new coopSharesTransaction can be accessed under the generated UUID
|
// finally, the new coopSharesTransaction can be accessed under the generated UUID
|
||||||
final var newShareTxUuid = UUID.fromString(location.substring(location.lastIndexOf('/') + 1));
|
final var newShareTxUuid = UUID.fromString(location.substring(location.lastIndexOf('/') + 1));
|
||||||
@ -197,7 +213,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
@Test
|
@Test
|
||||||
void globalAdmin_canAddCoopSharesReversalTransaction() {
|
void globalAdmin_canAddCoopSharesReversalTransaction() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN");
|
||||||
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
||||||
final var givenTransaction = jpaAttempt.transacted(() -> {
|
final var givenTransaction = jpaAttempt.transacted(() -> {
|
||||||
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
||||||
@ -214,46 +230,46 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"membership.uuid": "%s",
|
"membership.uuid": "%s",
|
||||||
"transactionType": "REVERSAL",
|
"transactionType": "REVERSAL",
|
||||||
"shareCount": %s,
|
"shareCount": %s,
|
||||||
"valueDate": "2022-10-30",
|
"valueDate": "2022-10-30",
|
||||||
"reference": "test reversal ref",
|
"reference": "test reversal ref",
|
||||||
"comment": "some coop shares reversal transaction",
|
"comment": "some coop shares reversal transaction",
|
||||||
"revertedShareTx.uuid": "%s"
|
"revertedShareTx.uuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
givenMembership.getUuid(),
|
givenMembership.getUuid(),
|
||||||
-givenTransaction.getShareCount(),
|
-givenTransaction.getShareCount(),
|
||||||
givenTransaction.getUuid()))
|
givenTransaction.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/coopsharestransactions")
|
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"transactionType": "REVERSAL",
|
"transactionType": "REVERSAL",
|
||||||
"shareCount": -13,
|
"shareCount": -13,
|
||||||
"valueDate": "2022-10-30",
|
"valueDate": "2022-10-30",
|
||||||
"reference": "test reversal ref",
|
"reference": "test reversal ref",
|
||||||
"comment": "some coop shares reversal transaction",
|
"comment": "some coop shares reversal transaction",
|
||||||
"revertedShareTx": {
|
"revertedShareTx": {
|
||||||
"transactionType": "SUBSCRIPTION",
|
"transactionType": "SUBSCRIPTION",
|
||||||
"shareCount": 13,
|
"shareCount": 13,
|
||||||
"valueDate": "2022-10-20",
|
"valueDate": "2022-10-20",
|
||||||
"reference": "test ref"
|
"reference": "test ref"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"""))
|
}
|
||||||
.header("Location", startsWith("http://localhost"))
|
"""))
|
||||||
.extract().header("Location"); // @formatter:on
|
.header("Location", startsWith("http://localhost"))
|
||||||
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
// finally, the new coopAssetsTransaction can be accessed under the generated UUID
|
// finally, the new coopAssetsTransaction can be accessed under the generated UUID
|
||||||
final var newShareTxUuid = UUID.fromString(
|
final var newShareTxUuid = UUID.fromString(
|
||||||
@ -269,22 +285,34 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given().header("current-subject", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body("""
|
.given()
|
||||||
{
|
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||||
"membership.uuid": "%s",
|
.contentType(ContentType.JSON)
|
||||||
"transactionType": "CANCELLATION",
|
.body("""
|
||||||
"shareCount": -80,
|
|
||||||
"valueDate": "2022-10-13",
|
|
||||||
"reference": "temp ref X",
|
|
||||||
"comment": "just some test coop shares transaction"
|
|
||||||
}
|
|
||||||
""".formatted(givenMembership.getUuid())).port(port).when().post("http://localhost/api/hs/office/coopsharestransactions").then().log().all().assertThat().statusCode(400).contentType(ContentType.JSON).body("", lenientlyEquals("""
|
|
||||||
{
|
{
|
||||||
"statusCode": 400,
|
"membership.uuid": "%s",
|
||||||
"statusPhrase": "Bad Request",
|
"transactionType": "CANCELLATION",
|
||||||
"message": "ERROR: [400] coop shares transaction would result in a negative number of shares"
|
"shareCount": -80,
|
||||||
}
|
"valueDate": "2022-10-13",
|
||||||
""")); // @formatter:on
|
"reference": "temp ref X",
|
||||||
|
"comment": "just some test coop shares transaction"
|
||||||
|
}
|
||||||
|
""".formatted(givenMembership.getUuid()))
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||||
|
.then()
|
||||||
|
.log().all()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(400)
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body("", lenientlyEquals("""
|
||||||
|
{
|
||||||
|
"statusCode": 400,
|
||||||
|
"statusPhrase": "Bad Request",
|
||||||
|
"message": "ERROR: [400] coop shares transaction would result in a negative number of shares"
|
||||||
|
}
|
||||||
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
@ -31,16 +32,19 @@ class HsOfficeCoopSharesTransactionControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||||
StandardMapper mapper;
|
StrictMapper mapper;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo;
|
HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo;
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
|
HsOfficeMembershipRepository membershipRepo;
|
||||||
|
|
||||||
static final String VALID_INSERT_REQUEST_BODY = """
|
static final String VALID_INSERT_REQUEST_BODY = """
|
||||||
{
|
{
|
||||||
"membership.uuid": "%s",
|
"membership.uuid": "%s",
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -50,7 +50,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -6,7 +6,7 @@ import net.hostsharing.hsadminng.HsadminNgApplication;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||||
@ -28,6 +28,7 @@ import jakarta.persistence.PersistenceContext;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -57,7 +58,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
HsOfficeDebitorRepository debitorRepo;
|
HsOfficeDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRbacRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeContactRealRepository contactRealRepo;
|
HsOfficeContactRealRepository contactRealRepo;
|
||||||
@ -467,7 +468,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.statusCode(400)
|
||||||
.body("message", is("ERROR: [400] Unable to find RealContact by debitorRel.contactUuid: 00000000-0000-0000-0000-000000000000"));
|
.body("message", is("ERROR: [400] Unable to find debitorRel.contact.uuid: 00000000-0000-0000-0000-000000000000"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +496,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.statusCode(400)
|
||||||
.body("message", is("ERROR: [400] Unable to find RealRelation by debitorRelUuid: 00000000-0000-0000-0000-000000000000"));
|
.body("message", is("ERROR: [400] Unable to find debitorRel.uuid: 00000000-0000-0000-0000-000000000000"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,16 +696,16 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void theContactOwner_canNotPatchARelatedDebitor() {
|
void theContactAdmin_canNotPatchARelatedDebitor() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor();
|
final var givenDebitor = givenSomeTemporaryDebitor();
|
||||||
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||||
.header("assumed-roles", "hs_office.contact#tenthcontact:ADMIN")
|
.header("assumed-roles", givenDebitor.getDebitorRel().getContact().roleId(ADMIN) )
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@ -712,9 +713,9 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
.patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(403)
|
.statusCode(403)
|
||||||
.body("message", containsString("ERROR: [403] Subject"))
|
.body("message", containsString("ERROR: [403] Subject"))
|
||||||
.body("message", containsString("is not allowed to update hs_office.debitor uuid "));
|
.body("message", containsString("is not allowed to update hs_office.debitor uuid "));
|
||||||
@ -802,7 +803,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.vatReverseCharge(false)
|
.vatReverseCharge(false)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return debitorRepo.save(newDebitor).load();
|
return debitorRepo.save(newDebitor).reload(em);
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.debitor;
|
package net.hostsharing.hsadminng.hs.office.debitor;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
@ -30,7 +30,7 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
.debitorNumberSuffix("67")
|
.debitorNumberSuffix("67")
|
||||||
.debitorRel(givenDebitorRel)
|
.debitorRel(givenDebitorRel)
|
||||||
.defaultPrefix("som")
|
.defaultPrefix("som")
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
@ -45,7 +45,7 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorRel(givenDebitorRel)
|
.debitorRel(givenDebitorRel)
|
||||||
.debitorNumberSuffix("67")
|
.debitorNumberSuffix("67")
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
@ -60,7 +60,7 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorRel(givenDebitorRel)
|
.debitorRel(givenDebitorRel)
|
||||||
.debitorNumberSuffix("67")
|
.debitorNumberSuffix("67")
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
@ -88,7 +88,7 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorRel(givenDebitorRel)
|
.debitorRel(givenDebitorRel)
|
||||||
.debitorNumberSuffix("67")
|
.debitorNumberSuffix("67")
|
||||||
.partner(HsOfficePartnerEntity.builder().build())
|
.partner(HsOfficePartnerRealEntity.builder().build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.getTaggedDebitorNumber();
|
final var result = given.getTaggedDebitorNumber();
|
||||||
@ -101,7 +101,7 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorRel(givenDebitorRel)
|
.debitorRel(givenDebitorRel)
|
||||||
.debitorNumberSuffix(null)
|
.debitorNumberSuffix(null)
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.debitor;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
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 org.springframework.transaction.annotation.Transactional;
|
||||||
@ -48,7 +48,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
HsOfficeDebitorRepository debitorRepo;
|
HsOfficeDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRealRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeContactRealRepository contactRealRepo;
|
HsOfficeContactRealRepository contactRealRepo;
|
||||||
@ -74,7 +74,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
@Autowired
|
@Autowired
|
||||||
RbacGrantsDiagramService mermaidService;
|
RbacGrantsDiagramService mermaidService;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
@Nested
|
@Nested
|
||||||
class CreateDebitor {
|
class CreateDebitor {
|
||||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealTestEntity.TEST_REAL_CONTACT;
|
import static net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealTestEntity.TEST_REAL_CONTACT;
|
||||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class TestHsOfficeDebitor {
|
public class TestHsOfficeDebitor {
|
||||||
|
@ -5,7 +5,7 @@ import io.restassured.RestAssured;
|
|||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||||
@ -54,7 +54,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
HsOfficeMembershipRepository membershipRepo;
|
HsOfficeMembershipRepository membershipRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRealRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
@ -430,7 +430,6 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerName).get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerName).get(0);
|
||||||
final var newMembership = HsOfficeMembershipEntity.builder()
|
final var newMembership = HsOfficeMembershipEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX)
|
.memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX)
|
||||||
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
||||||
|
@ -2,8 +2,10 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
|
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@ -12,7 +14,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
@ -34,11 +36,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsOfficeMembershipController.class)
|
@WebMvcTest(HsOfficeMembershipController.class)
|
||||||
@Import({StandardMapper.class, DisableSecurityConfig.class})
|
@Import({StrictMapper.class, DisableSecurityConfig.class})
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
public class HsOfficeMembershipControllerRestTest {
|
public class HsOfficeMembershipControllerRestTest {
|
||||||
|
|
||||||
private static final HsOfficePartnerEntity PARTNER_12345 = HsOfficePartnerEntity.builder()
|
private static final HsOfficePartnerRealEntity PARTNER_12345 = HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.build();
|
.build();
|
||||||
public static final HsOfficeMembershipEntity MEMBERSHIP_1234501 = HsOfficeMembershipEntity.builder()
|
public static final HsOfficeMembershipEntity MEMBERSHIP_1234501 = HsOfficeMembershipEntity.builder()
|
||||||
@ -69,16 +71,19 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
|
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
|
HsOfficePartnerRealRepository partnerRepo;
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
HsOfficeMembershipRepository membershipRepo;
|
HsOfficeMembershipRepository membershipRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerWrapper em;
|
EntityManagerWrapper em;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@ -252,7 +257,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
|
|
||||||
// given
|
// given
|
||||||
final var givenPartnerUuid = UUID.randomUUID();
|
final var givenPartnerUuid = UUID.randomUUID();
|
||||||
when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null);
|
when(em.find(HsOfficePartnerRbacEntity.class, givenPartnerUuid)).thenReturn(null);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
@ -275,7 +280,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
|
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
|
||||||
.andExpect(jsonPath(
|
.andExpect(jsonPath(
|
||||||
"message",
|
"message",
|
||||||
is("ERROR: [400] Unable to find Partner by partner.uuid: " + givenPartnerUuid)));
|
is("ERROR: [400] partnerUuid " + givenPartnerUuid + " not found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
|
|||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipStatusResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipStatusResource;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -17,7 +17,7 @@ import java.time.LocalDate;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
@ -40,7 +40,7 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
@Mock
|
@Mock
|
||||||
private EntityManagerWrapper em;
|
private EntityManagerWrapper em;
|
||||||
|
|
||||||
private StandardMapper mapper = new StandardMapper(em);
|
private StrictMapper mapper = new StrictMapper(em);
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void initMocks() {
|
void initMocks() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.membership;
|
package net.hostsharing.hsadminng.hs.office.membership;
|
||||||
|
|
||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator;
|
import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class HsOfficeMembershipEntityUnitTest {
|
class HsOfficeMembershipEntityUnitTest {
|
||||||
@ -57,7 +57,7 @@ class HsOfficeMembershipEntityUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getMemberNumberWithoutPartnerNumberButWithSuffix() {
|
void getMemberNumberWithoutPartnerNumberButWithSuffix() {
|
||||||
givenMembership.setPartner(HsOfficePartnerEntity.builder().build());
|
givenMembership.setPartner(HsOfficePartnerRealEntity.builder().build());
|
||||||
final var result = givenMembership.getMemberNumber();
|
final var result = givenMembership.getMemberNumber();
|
||||||
assertThat(result).isEqualTo(null);
|
assertThat(result).isEqualTo(null);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
||||||
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
HsOfficeMembershipRepository membershipRepo;
|
HsOfficeMembershipRepository membershipRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRealRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeDebitorRepository debitorRepo;
|
HsOfficeDebitorRepository debitorRepo;
|
||||||
@ -54,7 +54,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
|
|||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||||
|
|
||||||
public class TestHsMembership {
|
public class TestHsMembership {
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
private Integer port;
|
private Integer port;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRbacRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationRealRepository relationRepo;
|
HsOfficeRelationRealRepository relationRepo;
|
||||||
@ -541,12 +541,12 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
return partnerRel;
|
return partnerRel;
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
private HsOfficePartnerRbacEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var partnerRel = em.merge(givenSomeTemporaryPartnerRel("Erben Bessler", "fourth contact"));
|
final var partnerRel = em.merge(givenSomeTemporaryPartnerRel("Erben Bessler", "fourth contact"));
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||||
.partnerRel(partnerRel)
|
.partnerRel(partnerRel)
|
||||||
.partnerNumber(partnerNumber)
|
.partnerNumber(partnerNumber)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder()
|
.details(HsOfficePartnerDetailsEntity.builder()
|
||||||
@ -561,7 +561,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
cleanupAllNew(HsOfficePartnerRbacEntity.class);
|
||||||
|
|
||||||
// TODO: should not be necessary anymore, once it's deleted via after delete trigger
|
// TODO: should not be necessary anymore, once it's deleted via after delete trigger
|
||||||
cleanupAllNew(HsOfficeRelationRealEntity.class);
|
cleanupAllNew(HsOfficeRelationRealEntity.class);
|
||||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
@ -38,7 +38,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsOfficePartnerController.class)
|
@WebMvcTest(HsOfficePartnerController.class)
|
||||||
@Import({StandardMapper.class, DisableSecurityConfig.class})
|
@Import({StrictMapper.class, DisableSecurityConfig.class})
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
class HsOfficePartnerControllerRestTest {
|
class HsOfficePartnerControllerRestTest {
|
||||||
|
|
||||||
@ -50,19 +50,19 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MockMvc mockMvc;
|
MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRbacRepository partnerRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HsOfficeRelationRealRepository relationRepo;
|
HsOfficeRelationRealRepository relationRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerWrapper em;
|
EntityManagerWrapper em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
EntityManagerFactory emf;
|
EntityManagerFactory emf;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
@ -75,7 +75,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
HsOfficeContactRbacEntity contactMock;
|
HsOfficeContactRbacEntity contactMock;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
HsOfficePartnerEntity partnerMock;
|
HsOfficePartnerRbacEntity partnerMock;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void init() {
|
void init() {
|
||||||
@ -174,7 +174,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
@Test
|
@Test
|
||||||
void respondWithPartner_ifPartnerNumberIsAvailable() throws Exception {
|
void respondWithPartner_ifPartnerNumberIsAvailable() throws Exception {
|
||||||
// given
|
// given
|
||||||
when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerEntity.builder()
|
when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerRbacEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.build()));
|
.build()));
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import static org.mockito.Mockito.lenient;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||||
HsOfficePartnerPatchResource,
|
HsOfficePartnerPatchResource,
|
||||||
HsOfficePartnerEntity
|
HsOfficePartnerRbacEntity
|
||||||
> {
|
> {
|
||||||
|
|
||||||
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
|
||||||
@ -53,8 +53,8 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficePartnerEntity newInitialEntity() {
|
protected HsOfficePartnerRbacEntity newInitialEntity() {
|
||||||
final var entity = HsOfficePartnerEntity.builder()
|
final var entity = HsOfficePartnerRbacEntity.builder()
|
||||||
.uuid(INITIAL_PARTNER_UUID)
|
.uuid(INITIAL_PARTNER_UUID)
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.partnerRel(HsOfficeRelationRealEntity.builder()
|
.partnerRel(HsOfficeRelationRealEntity.builder()
|
||||||
@ -72,7 +72,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerEntity partner) {
|
protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerRbacEntity partner) {
|
||||||
return new HsOfficePartnerEntityPatcher(em, partner);
|
return new HsOfficePartnerEntityPatcher(em, partner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
"partnerRel",
|
"partnerRel",
|
||||||
HsOfficePartnerPatchResource::setPartnerRelUuid,
|
HsOfficePartnerPatchResource::setPartnerRelUuid,
|
||||||
PATCHED_PARTNER_ROLE_UUID,
|
PATCHED_PARTNER_ROLE_UUID,
|
||||||
HsOfficePartnerEntity::setPartnerRel,
|
HsOfficePartnerRbacEntity::setPartnerRel,
|
||||||
newPartnerRel(PATCHED_PARTNER_ROLE_UUID))
|
newPartnerRel(PATCHED_PARTNER_ROLE_UUID))
|
||||||
.notNullable()
|
.notNullable()
|
||||||
);
|
);
|
||||||
|
@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
class HsOfficePartnerEntityUnitTest {
|
class HsOfficePartnerEntityUnitTest {
|
||||||
|
|
||||||
private final HsOfficePartnerEntity givenPartner = HsOfficePartnerEntity.builder()
|
private final HsOfficePartnerRbacEntity givenPartner = HsOfficePartnerRbacEntity.builder()
|
||||||
.partnerNumber(12345)
|
.partnerNumber(12345)
|
||||||
.partnerRel(HsOfficeRelationRealEntity.builder()
|
.partnerRel(HsOfficeRelationRealEntity.builder()
|
||||||
.anchor(HsOfficePersonRealEntity.builder()
|
.anchor(HsOfficePersonRealEntity.builder()
|
||||||
@ -42,7 +42,7 @@ class HsOfficePartnerEntityUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void definesRbac() {
|
void definesRbac() {
|
||||||
final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerEntity.rbac()).toString();
|
final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerRbacEntity.rbac()).toString();
|
||||||
assertThat(rbacFlowchart).isEqualTo("""
|
assertThat(rbacFlowchart).isEqualTo("""
|
||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
@ -6,19 +6,19 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.role.RawRbacObjectRepository;
|
import net.hostsharing.hsadminng.rbac.role.RawRbacObjectRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
||||||
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
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.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
@ -27,20 +27,21 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.mapper.Array.from;
|
||||||
import static net.hostsharing.hsadminng.rbac.grant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
import static net.hostsharing.hsadminng.rbac.grant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||||
import static net.hostsharing.hsadminng.rbac.role.RawRbacObjectEntity.objectDisplaysOf;
|
import static net.hostsharing.hsadminng.rbac.role.RawRbacObjectEntity.objectDisplaysOf;
|
||||||
import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf;
|
import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||||
import static net.hostsharing.hsadminng.mapper.Array.from;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.AGENT;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@Import( { Context.class, JpaAttempt.class })
|
@Import({ Context.class, JpaAttempt.class })
|
||||||
class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRbacRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationRealRepository relationRepo;
|
HsOfficeRelationRealRepository relationRepo;
|
||||||
@ -66,7 +67,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@ -80,18 +81,19 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var partnerRel = givenSomeTemporaryHostsharingPartnerRel("Winkler", "first contact");
|
final var partnerRel = givenSomeTemporaryHostsharingPartnerRel("Winkler", "first contact");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
em, () -> {
|
||||||
.partnerNumber(20031)
|
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||||
.partnerRel(partnerRel)
|
.partnerNumber(20031)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.partnerRel(partnerRel)
|
||||||
.build();
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
return partnerRepo.save(newPartner);
|
.build();
|
||||||
});
|
return partnerRepo.save(newPartner);
|
||||||
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerEntity::getUuid).isNotNull();
|
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerRbacEntity::getUuid).isNotNull();
|
||||||
assertThatPartnerIsPersisted(result.returnedValue());
|
assertThatPartnerIsPersisted(result.returnedValue());
|
||||||
assertThat(partnerRepo.count()).isEqualTo(count + 1);
|
assertThat(partnerRepo.count()).isEqualTo(count + 1);
|
||||||
}
|
}
|
||||||
@ -108,26 +110,27 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
attempt(em, () -> {
|
attempt(
|
||||||
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
em, () -> {
|
||||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").get(0);
|
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").get(0);
|
||||||
|
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
||||||
|
|
||||||
final var newRelation = HsOfficeRelationRealEntity.builder()
|
final var newRelation = HsOfficeRelationRealEntity.builder()
|
||||||
.holder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.type(HsOfficeRelationType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.anchor(givenMandantPerson)
|
.anchor(givenMandantPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationRepo.save(newRelation);
|
relationRepo.save(newRelation);
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||||
.partnerNumber(20032)
|
.partnerNumber(20032)
|
||||||
.partnerRel(newRelation)
|
.partnerRel(newRelation)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
.build();
|
.build();
|
||||||
return partnerRepo.save(newPartner);
|
return partnerRepo.save(newPartner);
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(from(
|
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(from(
|
||||||
@ -179,7 +182,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
null)));
|
null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatPartnerIsPersisted(final HsOfficePartnerEntity saved) {
|
private void assertThatPartnerIsPersisted(final HsOfficePartnerRbacEntity saved) {
|
||||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||||
assertThat(found).isNotEmpty().get().extracting(Object::toString).isEqualTo(saved.toString());
|
assertThat(found).isNotEmpty().get().extracting(Object::toString).isEqualTo(saved.toString());
|
||||||
}
|
}
|
||||||
@ -207,15 +210,32 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewOnlyRelatedPartners() {
|
public void partnerAgent_canViewOnlyRelatedPartnersWithDetails() {
|
||||||
// given:
|
// given:
|
||||||
context("person-FirstGmbH@example.com");
|
context(
|
||||||
|
"person-FirstGmbH@example.com",
|
||||||
|
"hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT");
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)");
|
exactlyThesePartnersAreReturned(result,
|
||||||
|
"partner(P-10001: LP First GmbH, first contact)+(partnerDetails(Hamburg, RegNo123456789))");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void partnerTenant_canViewRelatedPartnersButWithoutDetails() {
|
||||||
|
// given:
|
||||||
|
context(
|
||||||
|
"person-FirstGmbH@example.com",
|
||||||
|
"hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT");
|
||||||
|
|
||||||
|
// when:
|
||||||
|
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||||
|
|
||||||
|
// then:
|
||||||
|
exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)+null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +243,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
class FindByNameLike {
|
class FindByNameLike {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void globalAdmin_withoutAssumedRole_canViewAllPartners() {
|
public void globalAdmin_withoutAssumedRole_canViewAllPartnersWithDetails() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
|
|
||||||
@ -231,7 +251,8 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
|
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyThesePartnersAreReturned(result, "partner(P-10003: IF Third OHG, third contact)");
|
exactlyThesePartnersAreReturned(result,
|
||||||
|
"partner(P-10003: IF Third OHG, third contact)+(partnerDetails(Hamburg, RegNo123456789))");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,19 +310,20 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void partnerRelationAgent_canUpdateRelatedPartner() {
|
public void partnerRelationAgent_canUpdateRelatedPartnerDetails() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
givenPartner.getPartnerRel().roleId(AGENT));
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net",
|
context(
|
||||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
"superuser-alex@hostsharing.net",
|
||||||
|
givenPartner.getPartnerRel().roleId(AGENT));
|
||||||
givenPartner.getDetails().setBirthName("new birthname");
|
givenPartner.getDetails().setBirthName("new birthname");
|
||||||
return partnerRepo.save(givenPartner);
|
return partnerRepo.save(givenPartner);
|
||||||
});
|
});
|
||||||
@ -310,37 +332,17 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerRbacEntity saved) {
|
||||||
public void partnerRelationTenant_canNotUpdateRelatedPartner() {
|
|
||||||
// given
|
|
||||||
context("superuser-alex@hostsharing.net");
|
|
||||||
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
|
||||||
givenPartner,
|
|
||||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
|
||||||
context("superuser-alex@hostsharing.net",
|
|
||||||
"hs_office.relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT");
|
|
||||||
givenPartner.getDetails().setBirthName("new birthname");
|
|
||||||
return partnerRepo.save(givenPartner);
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
|
||||||
"ERROR: [403] insert into hs_office.partner_details ",
|
|
||||||
" not allowed for current subjects {hs_office.relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {
|
|
||||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||||
assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerEntity::toString).isEqualTo(saved.toString());
|
assertThat(found).isNotEmpty()
|
||||||
|
.get()
|
||||||
|
.isNotSameAs(saved)
|
||||||
|
.extracting(HsOfficePartnerRbacEntity::toString)
|
||||||
|
.isEqualTo(saved.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatPartnerIsVisibleForUserWithRole(
|
private void assertThatPartnerIsVisibleForUserWithRole(
|
||||||
final HsOfficePartnerEntity entity,
|
final HsOfficePartnerRbacEntity entity,
|
||||||
final String assumedRoles) {
|
final String assumedRoles) {
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||||
@ -349,7 +351,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatPartnerIsNotVisibleForUserWithRole(
|
private void assertThatPartnerIsNotVisibleForUserWithRole(
|
||||||
final HsOfficePartnerEntity entity,
|
final HsOfficePartnerRbacEntity entity,
|
||||||
final String assumedRoles) {
|
final String assumedRoles) {
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||||
@ -437,7 +439,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
select currentTask, targetTable, targetOp, targetdelta->>'partnernumber'
|
select currentTask, targetTable, targetOp, targetdelta->>'partnernumber'
|
||||||
from base.tx_journal_v
|
from base.tx_journal_v
|
||||||
where targettable = 'hs_office.partner';
|
where targettable = 'hs_office.partner';
|
||||||
""");
|
""");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
|
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
|
||||||
@ -451,19 +453,22 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
"[creating partner test-data , hs_office.partner, INSERT, 10010]");
|
"[creating partner test-data , hs_office.partner, INSERT, 10010]");
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerEntity givenSomeTemporaryHostsharingPartner(
|
private HsOfficePartnerRbacEntity givenSomeTemporaryHostsharingPartner(
|
||||||
final Integer partnerNumber, final String person, final String contact) {
|
final Integer partnerNumber, final String person, final String contact) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var partnerRel = givenSomeTemporaryHostsharingPartnerRel(person, contact);
|
final var partnerRel = givenSomeTemporaryHostsharingPartnerRel(person, contact);
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||||
.partnerNumber(partnerNumber)
|
.partnerNumber(partnerNumber)
|
||||||
.partnerRel(partnerRel)
|
.partnerRel(partnerRel)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return partnerRepo.save(newPartner);
|
final var savedPartner = partnerRepo.save(newPartner);
|
||||||
|
em.flush();
|
||||||
|
final var partner = em.find(savedPartner.getClass(), savedPartner.getUuid());
|
||||||
|
return savedPartner;
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,21 +487,23 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
return partnerRel;
|
return partnerRel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exactlyThesePartnersAreReturned(final List<HsOfficePartnerEntity> actualResult, final String... partnerNames) {
|
void exactlyThesePartnersAreReturned(final List<HsOfficePartnerRbacEntity> actualResult, final String... partnerNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(partnerEntity -> partnerEntity.toString())
|
.extracting(partner ->
|
||||||
|
partner.toString() + "+" +
|
||||||
|
(partner.getDetails() != null ? ("(" + partner.getDetails() + ")") : "null"))
|
||||||
.containsExactlyInAnyOrder(partnerNames);
|
.containsExactlyInAnyOrder(partnerNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allThesePartnersAreReturned(final List<HsOfficePartnerEntity> actualResult, final String... partnerNames) {
|
void allThesePartnersAreReturned(final List<HsOfficePartnerRbacEntity> actualResult, final String... partnerNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(partnerEntity -> partnerEntity.toString())
|
.extracting(HsOfficePartnerRbacEntity::toString)
|
||||||
.contains(partnerNames);
|
.contains(partnerNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
cleanupAllNew(HsOfficePartnerRbacEntity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] distinct(final String[] strings) {
|
private String[] distinct(final String[] strings) {
|
@ -7,12 +7,12 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
|||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
||||||
|
|
||||||
public class TestHsOfficePartner {
|
public class HsOfficeTestRealPartner {
|
||||||
|
|
||||||
public static final HsOfficePartnerEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
|
public static final HsOfficePartnerRealEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
|
||||||
|
|
||||||
static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
|
static public HsOfficePartnerRealEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
|
||||||
return HsOfficePartnerEntity.builder()
|
return HsOfficePartnerRealEntity.builder()
|
||||||
.partnerNumber(10001)
|
.partnerNumber(10001)
|
||||||
.partnerRel(
|
.partnerRel(
|
||||||
HsOfficeRelationRealEntity.builder()
|
HsOfficeRelationRealEntity.builder()
|
@ -331,7 +331,6 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define(creatingUser);
|
context.define(creatingUser);
|
||||||
final var newPerson = HsOfficePersonRealEntity.builder()
|
final var newPerson = HsOfficePersonRealEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.personType(HsOfficePersonType.LEGAL_PERSON)
|
.personType(HsOfficePersonType.LEGAL_PERSON)
|
||||||
.tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2))
|
.tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2))
|
||||||
.familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org")
|
.familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org")
|
||||||
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -46,7 +46,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -10,7 +10,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -44,7 +44,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficePersonRealRepository hsOfficePersonRealRepository;
|
private HsOfficePersonRealRepository hsOfficePersonRealRepository;
|
||||||
|
@ -9,7 +9,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@ -35,7 +35,7 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -180,10 +180,9 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
void globalAdmin_canNotPostNewSepaMandateWhenDebitorUuidIsMissing() {
|
void globalAdmin_canNotPostNewSepaMandateWhenDebitorUuidIsMissing() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = debitorRepo.findDebitorsByOptionalNameLike("Third").get(0);
|
|
||||||
final var givenBankAccount = bankAccountRepo.findByIbanOrderByIbanAsc("DE02200505501015871393").get(0);
|
final var givenBankAccount = bankAccountRepo.findByIbanOrderByIbanAsc("DE02200505501015871393").get(0);
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
@ -227,12 +226,12 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
.post("http://localhost/api/hs/office/sepamandates")
|
.post("http://localhost/api/hs/office/sepamandates")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.statusCode(400)
|
||||||
.body("message", is("ERROR: [400] Unable to find BankAccount with uuid 00000000-0000-0000-0000-000000000000"));
|
.body("message", is("ERROR: [400] bankAccount.uuid='00000000-0000-0000-0000-000000000000' not found or not accessible"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_canNotPostNewSepaMandate_ifPersonDoesNotExist() {
|
void globalAdmin_canNotPostNewSepaMandate_ifDebitorDoesNotExist() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitorUuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
final var givenDebitorUuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||||
@ -257,7 +256,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
.post("http://localhost/api/hs/office/sepamandates")
|
.post("http://localhost/api/hs/office/sepamandates")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.statusCode(400)
|
||||||
.body("message", is("ERROR: [400] Unable to find Debitor with uuid 00000000-0000-0000-0000-000000000000"));
|
.body("message", is("ERROR: [400] debitor.uuid='00000000-0000-0000-0000-000000000000' not found or not accessible"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,7 +528,6 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
.orElse(givenDebitor.getPartner().getPartnerRel().getHolder().getFamilyName());
|
.orElse(givenDebitor.getPartner().getPartnerRel().getHolder().getFamilyName());
|
||||||
final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0);
|
final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0);
|
||||||
final var newSepaMandate = HsOfficeSepaMandateEntity.builder()
|
final var newSepaMandate = HsOfficeSepaMandateEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.debitor(givenDebitor)
|
.debitor(givenDebitor)
|
||||||
.bankAccount(givenBankAccount)
|
.bankAccount(givenBankAccount)
|
||||||
.reference("temp ref CAT Z")
|
.reference("temp ref CAT Z")
|
||||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC
|
|||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|
||||||
@MockBean
|
@MockitoBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user