introduce-partner-business-role (#16)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #16 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
parent
188cb9733e
commit
2c0101b46d
2
.aliases
2
.aliases
@ -46,7 +46,7 @@ postgresAutodoc () {
|
||||
alias postgres-autodoc=postgresAutodoc
|
||||
|
||||
function importOfficeData() {
|
||||
export HSADMINNG_POSTGRES_JDBC=jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
|
||||
export HSADMINNG_POSTGRES_JDBC_URL=jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
|
||||
export HSADMINNG_POSTGRES_ADMIN_USERNAME=admin
|
||||
export HSADMINNG_POSTGRES_ADMIN_PASSWORD=password
|
||||
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
||||
|
@ -53,7 +53,7 @@ To be able to build and run the Java Spring Boot application, you need the follo
|
||||
- Docker 20.x (on MacOS you also need *Docker Desktop* or similar) or Podman
|
||||
- optionally: PostgreSQL Server 15.5-bookworm
|
||||
(see instructions below to install and run in Docker)
|
||||
- The matching Java JDK at will be automatically installed by Gradle toolchain support.
|
||||
- The matching Java JDK at will be automatically installed by Gradle toolchain support to `~/.gradle/jdks/`.
|
||||
- You also might need an IDE (e.g. *IntelliJ IDEA* or *Eclipse* or *VS Code* with *[STS](https://spring.io/tools)* and a GUI Frontend for *PostgreSQL* like *Postbird*.
|
||||
|
||||
If you have at least Docker and the Java JDK installed in appropriate versions and in your `PATH`, then you can start like this:
|
||||
|
@ -308,6 +308,8 @@ tasks.register('importOfficeData', Test) {
|
||||
|
||||
group 'verification'
|
||||
description 'run the import jobs as tests'
|
||||
|
||||
mustRunAfter spotlessJava
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
package net.hostsharing.hsadminng.errors;
|
||||
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ReferenceNotFoundException extends RuntimeException {
|
||||
|
||||
private final Class<?> entityClass;
|
||||
private final UUID uuid;
|
||||
public <E extends HasUuid> ReferenceNotFoundException(final Class<E> entityClass, final UUID uuid, final Throwable exc) {
|
||||
super(exc);
|
||||
this.entityClass = entityClass;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Cannot resolve " + entityClass.getSimpleName() +" with uuid " + uuid;
|
||||
}
|
||||
}
|
@ -45,7 +45,7 @@ public class RestResponseEntityExceptionHandler
|
||||
protected ResponseEntity<CustomErrorResponse> handleJpaExceptions(
|
||||
final RuntimeException exc, final WebRequest request) {
|
||||
final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0);
|
||||
return errorResponse(request, httpStatus(message).orElse(HttpStatus.INTERNAL_SERVER_ERROR), message);
|
||||
return errorResponse(request, httpStatus(exc, message).orElse(HttpStatus.INTERNAL_SERVER_ERROR), message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoSuchElementException.class)
|
||||
@ -55,6 +55,12 @@ public class RestResponseEntityExceptionHandler
|
||||
return errorResponse(request, HttpStatus.NOT_FOUND, message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ReferenceNotFoundException.class)
|
||||
protected ResponseEntity<CustomErrorResponse> handleReferenceNotFoundException(
|
||||
final ReferenceNotFoundException exc, final WebRequest request) {
|
||||
return errorResponse(request, HttpStatus.BAD_REQUEST, exc.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler({ JpaObjectRetrievalFailureException.class, EntityNotFoundException.class })
|
||||
protected ResponseEntity<CustomErrorResponse> handleJpaObjectRetrievalFailureException(
|
||||
final RuntimeException exc, final WebRequest request) {
|
||||
@ -74,8 +80,9 @@ public class RestResponseEntityExceptionHandler
|
||||
@ExceptionHandler(Throwable.class)
|
||||
protected ResponseEntity<CustomErrorResponse> handleOtherExceptions(
|
||||
final Throwable exc, final WebRequest request) {
|
||||
final var message = firstMessageLine(NestedExceptionUtils.getMostSpecificCause(exc));
|
||||
return errorResponse(request, httpStatus(message).orElse(HttpStatus.INTERNAL_SERVER_ERROR), message);
|
||||
final var causingException = NestedExceptionUtils.getMostSpecificCause(exc);
|
||||
final var message = firstMessageLine(causingException);
|
||||
return errorResponse(request, httpStatus(causingException, message).orElse(HttpStatus.INTERNAL_SERVER_ERROR), message);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -138,7 +145,10 @@ public class RestResponseEntityExceptionHandler
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<HttpStatus> httpStatus(final String message) {
|
||||
private Optional<HttpStatus> httpStatus(final Throwable causingException, final String message) {
|
||||
if ( EntityNotFoundException.class.isInstance(causingException) ) {
|
||||
return Optional.of(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (message.startsWith("ERROR: [")) {
|
||||
for (HttpStatus status : HttpStatus.values()) {
|
||||
if (message.startsWith("ERROR: [" + status.value() + "]")) {
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
|
@ -13,13 +13,15 @@ public interface HsOfficeBankAccountRepository extends Repository<HsOfficeBankAc
|
||||
|
||||
@Query("""
|
||||
SELECT c FROM HsOfficeBankAccountEntity c
|
||||
WHERE :holder is null
|
||||
OR lower(c.holder) like lower(concat(:holder, '%'))
|
||||
WHERE lower(c.holder) like lower(concat(:holder, '%'))
|
||||
ORDER BY c.holder
|
||||
""")
|
||||
List<HsOfficeBankAccountEntity> findByOptionalHolderLike(String holder);
|
||||
List<HsOfficeBankAccountEntity> findByOptionalHolderLikeImpl(String holder);
|
||||
default List<HsOfficeBankAccountEntity> findByOptionalHolderLike(String holder) {
|
||||
return findByOptionalHolderLikeImpl(holder == null ? "" : holder);
|
||||
}
|
||||
|
||||
List<HsOfficeBankAccountEntity> findByIbanOrderByIban(String iban);
|
||||
List<HsOfficeBankAccountEntity> findByIbanOrderByIbanAsc(String iban);
|
||||
|
||||
<S extends HsOfficeBankAccountEntity> S save(S entity);
|
||||
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
@ -36,7 +36,7 @@ public class HsOfficeContactEntity implements Stringifyable, HasUuid {
|
||||
private String label;
|
||||
|
||||
@Column(name = "postaladdress")
|
||||
private String postalAddress;
|
||||
private String postalAddress; // TODO: check if we really want multiple, if so: JSON-Array or Postgres-Array?
|
||||
|
||||
@Column(name = "emailaddresses", columnDefinition = "json")
|
||||
private String emailAddresses; // TODO: check if we can really add multiple. format: ["eins@...", "zwei@..."]
|
||||
|
@ -4,7 +4,7 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -25,7 +25,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUuid {
|
||||
|
||||
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
||||
.withProp(HsOfficeCoopSharesTransactionEntity::getMemberNumber)
|
||||
.withProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged)
|
||||
.withProp(HsOfficeCoopSharesTransactionEntity::getValueDate)
|
||||
.withProp(HsOfficeCoopSharesTransactionEntity::getTransactionType)
|
||||
.withProp(HsOfficeCoopSharesTransactionEntity::getShareCount)
|
||||
@ -76,12 +76,12 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUu
|
||||
return stringify.apply(this);
|
||||
}
|
||||
|
||||
public Integer getMemberNumber() {
|
||||
return ofNullable(membership).map(HsOfficeMembershipEntity::getMemberNumber).orElse(null);
|
||||
private String getMemberNumberTagged() {
|
||||
return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return "M-%s%+d".formatted(getMemberNumber(), shareCount);
|
||||
return "%s%+d".formatted(getMemberNumberTagged(), shareCount);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
@ -5,7 +5,7 @@ import com.vladmihalcea.hibernate.type.range.Range;
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
@ -1,12 +1,21 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.errors.ReferenceNotFoundException;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartnersApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerRoleInsertResource;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -30,6 +39,9 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
@Autowired
|
||||
private HsOfficePartnerRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeRelationshipRepository relationshipRepo;
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@ -56,7 +68,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficePartnerEntity.class);
|
||||
final var entityToSave = createPartnerEntity(body);
|
||||
|
||||
final var saved = partnerRepo.save(entityToSave);
|
||||
|
||||
@ -93,11 +105,17 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
final UUID partnerUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
|
||||
final var result = partnerRepo.deleteByUuid(partnerUuid);
|
||||
if (result == 0) {
|
||||
final var partnerToDelete = partnerRepo.findByUuid(partnerUuid);
|
||||
if (partnerToDelete.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
if (partnerRepo.deleteByUuid(partnerUuid) != 1 ||
|
||||
// TODO: move to after delete trigger in partner
|
||||
relationshipRepo.deleteByUuid(partnerToDelete.get().getPartnerRole().getUuid()) != 1 ) {
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@ -119,4 +137,32 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
||||
final var entityToSave = new HsOfficePartnerEntity();
|
||||
entityToSave.setPartnerNumber(body.getPartnerNumber());
|
||||
entityToSave.setPartnerRole(persistPartnerRole(body.getPartnerRole()));
|
||||
entityToSave.setContact(ref(HsOfficeContactEntity.class, body.getContactUuid()));
|
||||
entityToSave.setPerson(ref(HsOfficePersonEntity.class, body.getPersonUuid()));
|
||||
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
||||
return entityToSave;
|
||||
}
|
||||
|
||||
private HsOfficeRelationshipEntity persistPartnerRole(final HsOfficePartnerRoleInsertResource resource) {
|
||||
final var entity = new HsOfficeRelationshipEntity();
|
||||
entity.setRelType(HsOfficeRelationshipType.PARTNER);
|
||||
entity.setRelAnchor(ref(HsOfficePersonEntity.class, resource.getRelAnchorUuid()));
|
||||
entity.setRelHolder(ref(HsOfficePersonEntity.class, resource.getRelHolderUuid()));
|
||||
entity.setContact(ref(HsOfficeContactEntity.class, resource.getContactUuid()));
|
||||
em.persist(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private <E extends HasUuid> E ref(final Class<E> entityClass, final UUID uuid) {
|
||||
try {
|
||||
return em.getReference(entityClass, uuid);
|
||||
} catch (final Throwable exc) {
|
||||
throw new ReferenceNotFoundException(entityClass, uuid, exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
|
@ -3,8 +3,9 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.NotFound;
|
||||
@ -39,10 +40,16 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
||||
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
|
||||
private Integer partnerNumber;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "partnerroleuuid", nullable = false)
|
||||
private HsOfficeRelationshipEntity partnerRole;
|
||||
|
||||
// TODO: remove, is replaced by partnerRole
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "personuuid", nullable = false)
|
||||
private HsOfficePersonEntity person;
|
||||
|
||||
// TODO: remove, is replaced by partnerRole
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "contactuuid", nullable = false)
|
||||
private HsOfficeContactEntity contact;
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.relationship;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.relationship;
|
||||
|
||||
public enum HsOfficeRelationshipType {
|
||||
UNKNOWN,
|
||||
PARTNER,
|
||||
EX_PARTNER,
|
||||
REPRESENTATIVE,
|
||||
VIP_CONTACT,
|
||||
|
@ -6,7 +6,7 @@ import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.hs.office.migration;
|
||||
package net.hostsharing.hsadminng.persistence;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -15,6 +15,8 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
|
||||
""")
|
||||
RbacGrantEntity findById(RbacGrantId rbacGrantId);
|
||||
|
||||
long count();
|
||||
|
||||
List<RbacGrantEntity> findAll();
|
||||
|
||||
RbacGrantEntity save(final RbacGrantEntity grant);
|
||||
|
@ -8,9 +8,12 @@ import java.util.UUID;
|
||||
public interface RbacRoleRepository extends Repository<RbacRoleEntity, UUID> {
|
||||
|
||||
/**
|
||||
* Returns all instances of the type.
|
||||
*
|
||||
* @return all entities
|
||||
* @return the number of persistent RbacRoleEntity instances, mostly for testing purposes.
|
||||
*/
|
||||
long count(); // TODO: move to test sources
|
||||
|
||||
/**
|
||||
* @return all persistent RbacRoleEntity instances, assigned to the current subject (user or assumed roles)
|
||||
*/
|
||||
List<RbacRoleEntity> findAll();
|
||||
|
||||
|
@ -96,6 +96,8 @@ components:
|
||||
format: int8
|
||||
minimum: 10000
|
||||
maximum: 99999
|
||||
partnerRole:
|
||||
$ref: '#/components/schemas/HsOfficePartnerRoleInsert'
|
||||
personUuid:
|
||||
type: string
|
||||
format: uuid
|
||||
@ -110,6 +112,24 @@ components:
|
||||
- contactUuid
|
||||
- details
|
||||
|
||||
HsOfficePartnerRoleInsert:
|
||||
type: object
|
||||
nullable: false
|
||||
properties:
|
||||
relAnchorUuid:
|
||||
type: string
|
||||
format: uuid
|
||||
relHolderUuid:
|
||||
type: string
|
||||
format: uuid
|
||||
contactUuid:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- relAnchorUuid
|
||||
- relHolderUuid
|
||||
- relContactUuid
|
||||
|
||||
HsOfficePartnerDetailsInsert:
|
||||
type: object
|
||||
nullable: false
|
||||
|
@ -7,6 +7,7 @@ components:
|
||||
type: string
|
||||
enum:
|
||||
- UNKNOWN
|
||||
- PARTNER
|
||||
- EX_PARTNER
|
||||
- REPRESENTATIVE,
|
||||
- VIP_CONTACT
|
||||
@ -61,3 +62,4 @@ components:
|
||||
- relAnchorUuid
|
||||
- relHolderUuid
|
||||
- relType
|
||||
- relContactUuid
|
||||
|
@ -53,6 +53,19 @@ create table tx_journal
|
||||
create index on tx_journal (targetTable, targetUuid);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset audit-TX-JOURNAL-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
A view combining tx_journal with tx_context.
|
||||
*/
|
||||
create view tx_journal_v as
|
||||
select txc.*, txj.targettable, txj.targetop, txj.targetuuid, txj.targetdelta
|
||||
from tx_journal txj
|
||||
left join tx_context txc using (contextid)
|
||||
order by txc.txtimestamp;
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset audit-TX-JOURNAL-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
@ -120,6 +120,7 @@ $$;
|
||||
create table RbacObject
|
||||
(
|
||||
uuid uuid primary key default uuid_generate_v4(),
|
||||
serialId serial, -- TODO: we might want to remove this once test data deletion works properly
|
||||
objectTable varchar(64) not null,
|
||||
unique (objectTable, uuid)
|
||||
);
|
||||
|
@ -61,7 +61,7 @@ do language plpgsql $$
|
||||
call createHsOfficeContactTestData('first contact');
|
||||
call createHsOfficeContactTestData('second contact');
|
||||
call createHsOfficeContactTestData('third contact');
|
||||
call createHsOfficeContactTestData('forth contact');
|
||||
call createHsOfficeContactTestData('fourth contact');
|
||||
call createHsOfficeContactTestData('fifth contact');
|
||||
call createHsOfficeContactTestData('sixth contact');
|
||||
call createHsOfficeContactTestData('seventh contact');
|
||||
|
@ -46,7 +46,7 @@ create or replace procedure createTestPersonTestData(
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call createHsOfficePersonTestData('LEGAL', intToVarChar(t, 4));
|
||||
call createHsOfficePersonTestData('LP', intToVarChar(t, 4));
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
@ -59,11 +59,15 @@ end; $$;
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficePersonTestData('LP', 'Hostsharing eG');
|
||||
call createHsOfficePersonTestData('LP', 'First GmbH');
|
||||
call createHsOfficePersonTestData('NP', null, 'Firby', 'Susan');
|
||||
call createHsOfficePersonTestData('NP', null, 'Smith', 'Peter');
|
||||
call createHsOfficePersonTestData('LP', 'Second e.K.', 'Sandra', 'Miller');
|
||||
call createHsOfficePersonTestData('NP', null, 'Tucker', 'Jack');
|
||||
call createHsOfficePersonTestData('NP', null, 'Fouler', 'Ellie');
|
||||
call createHsOfficePersonTestData('LP', 'Second e.K.', 'Smith', 'Peter');
|
||||
call createHsOfficePersonTestData('IF', 'Third OHG');
|
||||
call createHsOfficePersonTestData('IF', 'Fourth e.G.');
|
||||
call createHsOfficePersonTestData('IF', 'Fourth eG');
|
||||
call createHsOfficePersonTestData('UF', 'Erben Bessler', 'Mel', 'Bessler');
|
||||
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Anita');
|
||||
call createHsOfficePersonTestData('NP', null, 'Winkler', 'Paul');
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
CREATE TYPE HsOfficeRelationshipType AS ENUM (
|
||||
'UNKNOWN',
|
||||
'PARTNER',
|
||||
'EX_PARTNER',
|
||||
'REPRESENTATIVE',
|
||||
'VIP_CONTACT',
|
@ -9,9 +9,9 @@
|
||||
Creates a single relationship test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeRelationshipTestData(
|
||||
anchorPersonTradeName varchar,
|
||||
holderPersonFamilyName varchar,
|
||||
holderPersonName varchar,
|
||||
relationshipType HsOfficeRelationshipType,
|
||||
anchorPersonTradeName varchar,
|
||||
contactLabel varchar,
|
||||
mark varchar default null)
|
||||
language plpgsql as $$
|
||||
@ -23,14 +23,27 @@ declare
|
||||
contact hs_office_contact;
|
||||
|
||||
begin
|
||||
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonFamilyName);
|
||||
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonName);
|
||||
currentTask := 'creating relationship test-data ' || idName;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select p.* from hs_office_person p where p.tradeName = anchorPersonTradeName into anchorPerson;
|
||||
select p.* from hs_office_person p where p.familyName = holderPersonFamilyName into holderPerson;
|
||||
if anchorPerson is null then
|
||||
raise exception 'anchorPerson "%" not found', anchorPersonTradeName;
|
||||
end if;
|
||||
|
||||
select p.* from hs_office_person p
|
||||
where p.tradeName = holderPersonName or p.familyName = holderPersonName
|
||||
into holderPerson;
|
||||
if holderPerson is null then
|
||||
raise exception 'holderPerson "%" not found', holderPersonName;
|
||||
end if;
|
||||
|
||||
select c.* from hs_office_contact c where c.label = contactLabel into contact;
|
||||
if contact is null then
|
||||
raise exception 'contact "%" not found', contactLabel;
|
||||
end if;
|
||||
|
||||
raise notice 'creating test relationship: %', idName;
|
||||
raise notice '- using anchor person (%): %', anchorPerson.uuid, anchorPerson;
|
||||
@ -72,13 +85,20 @@ end; $$;
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeRelationshipTestData('First GmbH', 'Smith', 'REPRESENTATIVE', 'first contact');
|
||||
call createHsOfficeRelationshipTestData('First GmbH', 'PARTNER', 'Hostsharing eG', 'first contact');
|
||||
call createHsOfficeRelationshipTestData('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
|
||||
|
||||
call createHsOfficeRelationshipTestData('Second e.K.', 'Smith', 'REPRESENTATIVE', 'second contact');
|
||||
call createHsOfficeRelationshipTestData('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
|
||||
call createHsOfficeRelationshipTestData('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
|
||||
|
||||
call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'REPRESENTATIVE', 'third contact');
|
||||
call createHsOfficeRelationshipTestData('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
|
||||
call createHsOfficeRelationshipTestData('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||
|
||||
call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'SUBSCRIBER', 'third contact', 'members-announce');
|
||||
call createHsOfficeRelationshipTestData('Fourth eG', 'PARTNER', 'Hostsharing eG', 'fourth contact');
|
||||
call createHsOfficeRelationshipTestData('Fouler', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||
|
||||
call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
|
||||
call createHsOfficeRelationshipTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -32,14 +32,47 @@ call create_journal('hs_office_partner_details');
|
||||
create table hs_office_partner
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
partnerNumber numeric(5),
|
||||
personUuid uuid not null references hs_office_person(uuid),
|
||||
contactUuid uuid not null references hs_office_contact(uuid),
|
||||
detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade
|
||||
partnerNumber numeric(5) unique not null,
|
||||
partnerRoleUuid uuid not null references hs_office_relationship(uuid), -- TODO: delete in after delete trigger
|
||||
personUuid uuid not null references hs_office_person(uuid), -- TODO: remove, replaced by partnerRoleUuid
|
||||
contactUuid uuid not null references hs_office_contact(uuid), -- TODO: remove, replaced by partnerRoleUuid
|
||||
detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-DELETE-DETAILS-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
Trigger function to delete related details of a partner to delete.
|
||||
*/
|
||||
create or replace function deleteHsOfficeDetailsOnPartnerDelete()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
declare
|
||||
counter integer;
|
||||
begin
|
||||
DELETE FROM hs_office_partner_details d WHERE d.uuid = OLD.detailsUuid;
|
||||
GET DIAGNOSTICS counter = ROW_COUNT;
|
||||
if counter = 0 then
|
||||
raise exception 'partner details % could not be deleted', OLD.detailsUuid;
|
||||
end if;
|
||||
RETURN OLD;
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Triggers deletion of related details of a partner to delete.
|
||||
*/
|
||||
create trigger hs_office_partner_delete_details_trigger
|
||||
after delete
|
||||
on hs_office_partner
|
||||
for each row
|
||||
execute procedure deleteHsOfficeDetailsOnPartnerDelete();
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
@ -27,12 +27,17 @@ create or replace function hsOfficePartnerRbacRolesTrigger()
|
||||
language plpgsql
|
||||
strict as $$
|
||||
declare
|
||||
oldPartnerRole hs_office_relationship;
|
||||
newPartnerRole hs_office_relationship;
|
||||
|
||||
oldPerson hs_office_person;
|
||||
newPerson hs_office_person;
|
||||
|
||||
oldContact hs_office_contact;
|
||||
newContact hs_office_contact;
|
||||
begin
|
||||
|
||||
select * from hs_office_relationship as r where r.uuid = NEW.partnerroleuuid into newPartnerRole;
|
||||
select * from hs_office_person as p where p.uuid = NEW.personUuid into newPerson;
|
||||
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
||||
|
||||
@ -52,6 +57,7 @@ begin
|
||||
incomingSuperRoles => array[
|
||||
hsOfficePartnerOwner(NEW)],
|
||||
outgoingSubRoles => array[
|
||||
hsOfficeRelationshipTenant(newPartnerRole),
|
||||
hsOfficePersonTenant(newPerson),
|
||||
hsOfficeContactTenant(newContact)]
|
||||
);
|
||||
@ -60,6 +66,7 @@ begin
|
||||
hsOfficePartnerAgent(NEW),
|
||||
incomingSuperRoles => array[
|
||||
hsOfficePartnerAdmin(NEW),
|
||||
hsOfficeRelationshipAdmin(newPartnerRole),
|
||||
hsOfficePersonAdmin(newPerson),
|
||||
hsOfficeContactAdmin(newContact)]
|
||||
);
|
||||
@ -69,6 +76,7 @@ begin
|
||||
incomingSuperRoles => array[
|
||||
hsOfficePartnerAgent(NEW)],
|
||||
outgoingSubRoles => array[
|
||||
hsOfficeRelationshipTenant(newPartnerRole),
|
||||
hsOfficePersonGuest(newPerson),
|
||||
hsOfficeContactGuest(newContact)]
|
||||
);
|
||||
@ -109,6 +117,19 @@ begin
|
||||
|
||||
elsif TG_OP = 'UPDATE' then
|
||||
|
||||
if OLD.partnerRoleUuid <> NEW.partnerRoleUuid then
|
||||
select * from hs_office_relationship as r where r.uuid = OLD.partnerRoleUuid into oldPartnerRole;
|
||||
|
||||
call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRole), hsOfficePartnerAdmin(OLD));
|
||||
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRole), hsOfficePartnerAdmin(NEW));
|
||||
|
||||
call revokeRoleFromRole(hsOfficePartnerAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRole));
|
||||
call grantRoleToRole(hsOfficePartnerAgent(NEW), hsOfficeRelationshipAdmin(newPartnerRole));
|
||||
|
||||
call revokeRoleFromRole(hsOfficeRelationshipGuest(oldPartnerRole), hsOfficePartnerTenant(OLD));
|
||||
call grantRoleToRole(hsOfficeRelationshipGuest(newPartnerRole), hsOfficePartnerTenant(NEW));
|
||||
end if;
|
||||
|
||||
if OLD.personUuid <> NEW.personUuid then
|
||||
select * from hs_office_person as p where p.uuid = OLD.personUuid into oldPerson;
|
||||
|
||||
@ -179,6 +200,7 @@ call generateRbacIdentityView('hs_office_partner', $idName$
|
||||
call generateRbacRestrictedView('hs_office_partner',
|
||||
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
|
||||
$updates$
|
||||
partnerRoleUuid = new.partnerRoleUuid,
|
||||
personUuid = new.personUuid,
|
||||
contactUuid = new.contactUuid
|
||||
$updates$);
|
||||
@ -189,7 +211,7 @@ call generateRbacRestrictedView('hs_office_partner',
|
||||
--changeset hs-office-partner-rbac-NEW-PARTNER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a global permission for new-partner and assigns it to the hostsharing admins role.
|
||||
Creates a global permission for new-partner and assigns it to the Hostsharing admins role.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
@ -9,30 +9,49 @@
|
||||
Creates a single partner test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficePartnerTestData(
|
||||
mandantTradeName varchar,
|
||||
partnerNumber numeric(5),
|
||||
personTradeOrFamilyName varchar,
|
||||
partnerPersonName varchar,
|
||||
contactLabel varchar )
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
idName varchar;
|
||||
mandantPerson hs_office_person;
|
||||
partnerRole hs_office_relationship;
|
||||
relatedPerson hs_office_person;
|
||||
relatedContact hs_office_contact;
|
||||
relatedDetailsUuid uuid;
|
||||
begin
|
||||
idName := cleanIdentifier( personTradeOrFamilyName|| '-' || contactLabel);
|
||||
idName := cleanIdentifier( partnerPersonName|| '-' || contactLabel);
|
||||
currentTask := 'creating partner test-data ' || idName;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select p.* from hs_office_person p
|
||||
where p.tradeName = personTradeOrFamilyName or p.familyName = personTradeOrFamilyName
|
||||
where p.tradeName = mandantTradeName
|
||||
into mandantPerson;
|
||||
if mandantPerson is null then
|
||||
raise exception 'mandant "%" not found', mandantTradeName;
|
||||
end if;
|
||||
|
||||
select p.* from hs_office_person p
|
||||
where p.tradeName = partnerPersonName or p.familyName = partnerPersonName
|
||||
into relatedPerson;
|
||||
select c.* from hs_office_contact c
|
||||
where c.label = contactLabel
|
||||
into relatedContact;
|
||||
|
||||
select r.* from hs_office_relationship r
|
||||
where r.reltype = 'PARTNER'
|
||||
and r.relanchoruuid = mandantPerson.uuid and r.relholderuuid = relatedPerson.uuid
|
||||
into partnerRole;
|
||||
if partnerRole is null then
|
||||
raise exception 'partnerRole "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
|
||||
end if;
|
||||
|
||||
raise notice 'creating test partner: %', idName;
|
||||
raise notice '- using partnerRole (%): %', partnerRole.uuid, partnerRole;
|
||||
raise notice '- using person (%): %', relatedPerson.uuid, relatedPerson;
|
||||
raise notice '- using contact (%): %', relatedContact.uuid, relatedContact;
|
||||
|
||||
@ -44,13 +63,13 @@ begin
|
||||
else
|
||||
insert
|
||||
into hs_office_partner_details (uuid, registrationOffice, registrationNumber)
|
||||
values (uuid_generate_v4(), 'Hamburg', '12345')
|
||||
values (uuid_generate_v4(), 'Hamburg', 'RegNo123456789')
|
||||
returning uuid into relatedDetailsUuid;
|
||||
end if;
|
||||
|
||||
insert
|
||||
into hs_office_partner (uuid, partnerNumber, personuuid, contactuuid, detailsUuid)
|
||||
values (uuid_generate_v4(), partnerNumber, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
||||
into hs_office_partner (uuid, partnerNumber, partnerRoleUuid, personuuid, contactuuid, detailsUuid)
|
||||
values (uuid_generate_v4(), partnerNumber, partnerRole.uuid, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
@ -62,11 +81,11 @@ end; $$;
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficePartnerTestData(10001, 'First GmbH', 'first contact');
|
||||
call createHsOfficePartnerTestData(10002, 'Second e.K.', 'second contact');
|
||||
call createHsOfficePartnerTestData(10003, 'Third OHG', 'third contact');
|
||||
call createHsOfficePartnerTestData(10004, 'Fourth e.G.', 'forth contact');
|
||||
call createHsOfficePartnerTestData(10010, 'Smith', 'fifth contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10001, 'First GmbH', 'first contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10002, 'Second e.K.', 'second contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10003, 'Third OHG', 'third contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10010, 'Smith', 'fifth contact');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -41,7 +41,7 @@ do language plpgsql $$
|
||||
call createHsOfficeBankAccountTestData('Peter Smith', 'DE02500105170137075030', 'INGDDEFF');
|
||||
call createHsOfficeBankAccountTestData('Second e.K.', 'DE02100500000054540402', 'BELADEBE');
|
||||
call createHsOfficeBankAccountTestData('Third OHG', 'DE02300209000106531065', 'CMCIDEDD');
|
||||
call createHsOfficeBankAccountTestData('Fourth e.G.', 'DE02200505501015871393', 'HASPDEHH');
|
||||
call createHsOfficeBankAccountTestData('Fourth eG', 'DE02200505501015871393', 'HASPDEHH');
|
||||
call createHsOfficeBankAccountTestData('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');
|
||||
call createHsOfficeBankAccountTestData('Anita Bessler', 'DE02300606010002474689', 'DAAEDEDD');
|
||||
call createHsOfficeBankAccountTestData('Paul Winkler', 'DE02600501010002034304', 'SOLADEST600');
|
||||
|
@ -66,21 +66,21 @@ databaseChangeLog:
|
||||
- include:
|
||||
file: db/changelog/218-hs-office-person-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/220-hs-office-partner.sql
|
||||
file: db/changelog/220-hs-office-relationship.sql
|
||||
- include:
|
||||
file: db/changelog/223-hs-office-partner-rbac.sql
|
||||
file: db/changelog/223-hs-office-relationship-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/224-hs-office-partner-details-rbac.sql
|
||||
file: db/changelog/228-hs-office-relationship-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/226-hs-office-partner-migration.sql
|
||||
file: db/changelog/230-hs-office-partner.sql
|
||||
- include:
|
||||
file: db/changelog/228-hs-office-partner-test-data.sql
|
||||
file: db/changelog/233-hs-office-partner-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/230-hs-office-relationship.sql
|
||||
file: db/changelog/234-hs-office-partner-details-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/233-hs-office-relationship-rbac.sql
|
||||
file: db/changelog/236-hs-office-partner-migration.sql
|
||||
- include:
|
||||
file: db/changelog/238-hs-office-relationship-test-data.sql
|
||||
file: db/changelog/238-hs-office-partner-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/240-hs-office-bankaccount.sql
|
||||
- include:
|
||||
|
@ -30,6 +30,7 @@ public class ArchitectureTest {
|
||||
"..test.pac",
|
||||
"..context",
|
||||
"..generated..",
|
||||
"..persistence..",
|
||||
"..hs.office.bankaccount",
|
||||
"..hs.office.contact",
|
||||
"..hs.office.coopassets",
|
||||
@ -164,6 +165,7 @@ public class ArchitectureTest {
|
||||
.that().resideInAPackage("..hs.office.relationship..")
|
||||
.should().onlyBeAccessed().byClassesThat()
|
||||
.resideInAnyPackage("..hs.office.relationship..",
|
||||
"..hs.office.partner..",
|
||||
"..hs.office.migration..");
|
||||
|
||||
@ArchTest
|
||||
|
@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
public abstract class ContextBasedTest {
|
||||
|
||||
@Autowired
|
||||
Context context;
|
||||
protected Context context;
|
||||
|
||||
TestInfo test;
|
||||
|
||||
|
@ -4,6 +4,7 @@ import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.test.Accepts;
|
||||
import net.hostsharing.test.JpaAttempt;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
@ -29,7 +30,7 @@ import static org.hamcrest.Matchers.startsWith;
|
||||
classes = { HsadminNgApplication.class, JpaAttempt.class }
|
||||
)
|
||||
@Transactional
|
||||
class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||
|
||||
@LocalServerPort
|
||||
private Integer port;
|
||||
@ -51,7 +52,7 @@ class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
class ListBankAccounts {
|
||||
|
||||
@Test
|
||||
void globalAdmin_withoutAssumedRoles_canViewAllBankAaccounts_ifNoCriteriaGiven() throws JSONException {
|
||||
void globalAdmin_withoutAssumedRoles_canViewAllBankAccounts_ifNoCriteriaGiven() throws JSONException {
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -75,7 +76,7 @@ class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
"bic": "BYLADEM1001"
|
||||
},
|
||||
{
|
||||
"holder": "Fourth e.G.",
|
||||
"holder": "Fourth eG",
|
||||
"iban": "DE02200505501015871393",
|
||||
"bic": "HASPDEHH"
|
||||
},
|
||||
|
@ -1,14 +1,12 @@
|
||||
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.test.Array;
|
||||
import net.hostsharing.test.JpaAttempt;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -24,14 +22,14 @@ import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.bankaccount.TestHsOfficeBankAccount.hsOfficeBankAccount;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DataJpaTest
|
||||
@Import({ Context.class, JpaAttempt.class })
|
||||
class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTest {
|
||||
class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||
|
||||
@Autowired
|
||||
HsOfficeBankAccountRepository bankAccountRepo;
|
||||
@ -61,8 +59,8 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTest {
|
||||
final var count = bankAccountRepo.count();
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> bankAccountRepo.save(
|
||||
hsOfficeBankAccount("some temp acc A", "DE37500105177419788228", "")));
|
||||
final var result = attempt(em, () -> toCleanup(bankAccountRepo.save(
|
||||
hsOfficeBankAccount("some temp acc A", "DE37500105177419788228", ""))));
|
||||
|
||||
// then
|
||||
result.assertSuccessful();
|
||||
@ -78,8 +76,8 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTest {
|
||||
final var count = bankAccountRepo.count();
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> bankAccountRepo.save(
|
||||
hsOfficeBankAccount("some temp acc B", "DE49500105174516484892", "INGDDEFFXXX")));
|
||||
final var result = attempt(em, () -> toCleanup(bankAccountRepo.save(
|
||||
hsOfficeBankAccount("some temp acc B", "DE49500105174516484892", "INGDDEFFXXX")) |