Compare commits
17 Commits
5280527eae
...
368170d27e
Author | SHA1 | Date | |
---|---|---|---|
|
368170d27e | ||
|
980524e7ab | ||
e427bb1784 | |||
|
238e413aa7 | ||
5f9a6d53d8 | |||
|
fef9fba073 | ||
3d77dcc2ce | |||
|
38e4b00107 | ||
|
7e31e95d57 | ||
|
53d46da49a | ||
|
b0bfb127b6 | ||
|
96ef490207 | ||
|
0a996a9a8f | ||
|
242b6f88c9 | ||
63b02ff9cb | |||
845857c14d | |||
|
cec31055a5 |
47
README.md
47
README.md
@ -5,7 +5,6 @@ For architecture consider the files in the `doc` and `adr` folder.
|
|||||||
|
|
||||||
<!-- generated TOC begin: -->
|
<!-- generated TOC begin: -->
|
||||||
- [Setting up the Development Environment](#setting-up-the-development-environment)
|
- [Setting up the Development Environment](#setting-up-the-development-environment)
|
||||||
- [SDKMAN](#sdkman)
|
|
||||||
- [PostgreSQL Server](#postgresql-server)
|
- [PostgreSQL Server](#postgresql-server)
|
||||||
- [Markdown](#markdown)
|
- [Markdown](#markdown)
|
||||||
- [Render Markdown embedded PlantUML](#render-markdown-embedded-plantuml)
|
- [Render Markdown embedded PlantUML](#render-markdown-embedded-plantuml)
|
||||||
@ -51,15 +50,13 @@ Everything is tested on _Ubuntu Linux 22.04_ and _MacOS Monterey (12.4)_.
|
|||||||
|
|
||||||
To be able to build and run the Java Spring Boot application, you need the following tools:
|
To be able to build and run the Java Spring Boot application, you need the following tools:
|
||||||
|
|
||||||
- Docker 20.x (on MacOS you also need *Docker Desktop* or similar)
|
- Docker 20.x (on MacOS you also need *Docker Desktop* or similar) or Podman
|
||||||
- PostgreSQL Server 15.5-bookworm
|
- optionally: PostgreSQL Server 15.5-bookworm
|
||||||
(see instructions below to install and run in Docker)
|
(see instructions below to install and run in Docker)
|
||||||
- Java JDK at least recent enough to run Gradle
|
- The matching Java JDK at will be automatically installed by Gradle toolchain support.
|
||||||
(JDK 17.x will be automatically installed by Gradle toolchain support)
|
- 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*.
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
If you have at least Docker, the Java JDK and Gradle installed in appropriate versions and in your `PATH`, then you can start like this:
|
|
||||||
|
|
||||||
cd your-hsadmin-ng-directory
|
cd your-hsadmin-ng-directory
|
||||||
|
|
||||||
@ -105,30 +102,9 @@ And to see the full, currently implemented, API, open http://localhost:8080/swag
|
|||||||
If you still need to install some of these tools, find some hints in the next chapters.
|
If you still need to install some of these tools, find some hints in the next chapters.
|
||||||
|
|
||||||
|
|
||||||
### SDKMAN
|
|
||||||
|
|
||||||
*SdkMan* is not necessary, but helpful to install and switch between different versions of SDKs (Software-Development-Kits) and development tools in general, e.g. *JDK* and *Gradle*.
|
|
||||||
It is available for _Linux_ and _MacOS_, _WSL_, _Cygwin_, _Solaris_ and _FreeBSD_.
|
|
||||||
|
|
||||||
You can get it from: https://sdkman.io/.
|
|
||||||
|
|
||||||
<big>**⚠**</big>
|
|
||||||
Yeah, the `curl ... | bash` install method looks quite scary;
|
|
||||||
but in a development environment you're downloading executables all the time,
|
|
||||||
e.g. through `npm`, `Maven` or `Gradle` when downloading dependencies.
|
|
||||||
Thus, maybe you should at least use a separate Linux account for development.
|
|
||||||
|
|
||||||
Once it's installed, you can install *JDK* and *Gradle*:
|
|
||||||
|
|
||||||
sdk install java 17.0.3-tem
|
|
||||||
sdk install gradle
|
|
||||||
|
|
||||||
sdk use java 17.0.3-tem # use this to switch between installed JDK versions
|
|
||||||
|
|
||||||
|
|
||||||
### PostgreSQL Server
|
### PostgreSQL Server
|
||||||
|
|
||||||
You could use any PostgreSQL Server (from version 13 on) installed on your machine.
|
You could use any PostgreSQL Server (version 15) installed on your machine.
|
||||||
You might amend the port and user settings in `src/main/resources/application.yml`, though.
|
You might amend the port and user settings in `src/main/resources/application.yml`, though.
|
||||||
|
|
||||||
But the easiest way to run PostgreSQL is via Docker.
|
But the easiest way to run PostgreSQL is via Docker.
|
||||||
@ -616,7 +592,16 @@ Summary for Debian-based Linux systems:
|
|||||||
sudo apt-get -y install podman
|
sudo apt-get -y install podman
|
||||||
```
|
```
|
||||||
|
|
||||||
Then start it like this:
|
It is possible to move the storage directory to /tmp, e.g. to increase performance or to avoid issues with NFS mounted home directories:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cat .config/containers/storage.conf
|
||||||
|
[storage]
|
||||||
|
driver = "vfs"
|
||||||
|
graphRoot = "/tmp/containers/storage"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Then start it like this:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
systemctl --user enable --now podman.socket
|
systemctl --user enable --now podman.socket
|
||||||
|
@ -207,7 +207,7 @@ project.tasks.spotlessJava.dependsOn(
|
|||||||
// OWASP Dependency Security Test
|
// OWASP Dependency Security Test
|
||||||
dependencyCheck {
|
dependencyCheck {
|
||||||
nvd {
|
nvd {
|
||||||
apiKey = project.property('OWASP_API_KEY') // set it in ~/.gradle/gradle.properties
|
apiKey = project.properties['OWASP_API_KEY'] // set it in ~/.gradle/gradle.properties
|
||||||
delay = 16000
|
delay = 16000
|
||||||
}
|
}
|
||||||
format = 'ALL'
|
format = 'ALL'
|
||||||
|
@ -59,9 +59,6 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
|||||||
|
|
||||||
|
|
||||||
final var saved = bankAccountRepo.save(entityToSave);
|
final var saved = bankAccountRepo.save(entityToSave);
|
||||||
// em.persist(entityToSave);
|
|
||||||
// final var saved = entityToSave;
|
|
||||||
// em.flush();
|
|
||||||
|
|
||||||
final var uri =
|
final var uri =
|
||||||
MvcUriComponentsBuilder.fromController(getClass())
|
MvcUriComponentsBuilder.fromController(getClass())
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.repository.HasUuid;
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
@ -23,7 +24,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("CoopAssetsTransaction")
|
@DisplayName("CoopAssetsTransaction")
|
||||||
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable {
|
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
||||||
.withProp(e -> e.getMembership().getMemberNumber())
|
.withProp(e -> e.getMembership().getMemberNumber())
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||||
|
|
||||||
public enum HsOfficeCoopAssetsTransactionType {
|
public enum HsOfficeCoopAssetsTransactionType {
|
||||||
ADJUSTMENT, DEPOSIT, DISBURSAL, TRANSFER, ADOPTION, CLEARING, LOSS
|
ADJUSTMENT, // correction of wrong bookings
|
||||||
|
DEPOSIT, // payment received from member after signing shares, >0
|
||||||
|
DISBURSAL, // payment send to member after cancellation of shares, <0
|
||||||
|
TRANSFER, // transferring shares to another member, <0
|
||||||
|
ADOPTION, // receiving shares from another member, >0
|
||||||
|
CLEARING, // settlement with members dept, <0
|
||||||
|
LOSS, // assignment of balance sheet loss in case of cancellation of shares, <0
|
||||||
|
LIMITATION // limitation period was reached after impossible disbursal, <0
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("CoopShareTransaction")
|
@DisplayName("CoopShareTransaction")
|
||||||
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable {
|
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUuid {
|
||||||
|
|
||||||
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
||||||
.withProp(e -> e.getMembership().getMemberNumber())
|
.withProp(e -> e.getMembership().getMemberNumber())
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||||
|
|
||||||
public enum HsOfficeCoopSharesTransactionType {
|
public enum HsOfficeCoopSharesTransactionType {
|
||||||
ADJUSTMENT, SUBSCRIPTION, CANCELLATION;
|
ADJUSTMENT, // correction of wrong bookings
|
||||||
|
SUBSCRIPTION, // shares signed, e.g. with the declaration of accession, >0
|
||||||
|
CANCELLATION; // shares terminated, e.g. when a membership is resigned, <0
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,16 @@ public class HsOfficeDebitorEntity implements Stringifyable {
|
|||||||
@JoinColumn(name = "partneruuid")
|
@JoinColumn(name = "partneruuid")
|
||||||
private HsOfficePartnerEntity partner;
|
private HsOfficePartnerEntity partner;
|
||||||
|
|
||||||
@Column(name = "debitornumber")
|
@Column(name = "debitornumbersuffix", columnDefinition = "numeric(2)")
|
||||||
private Integer debitorNumber;
|
private Byte debitorNumberSuffix; // TODO maybe rather as a formatted String?
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "billingcontactuuid")
|
@JoinColumn(name = "billingcontactuuid")
|
||||||
private HsOfficeContactEntity billingContact;
|
private HsOfficeContactEntity billingContact;
|
||||||
|
|
||||||
|
@Column(name = "billable")
|
||||||
|
private boolean billable;
|
||||||
|
|
||||||
@Column(name = "vatid")
|
@Column(name = "vatid")
|
||||||
private String vatId;
|
private String vatId;
|
||||||
|
|
||||||
@ -60,6 +63,17 @@ public class HsOfficeDebitorEntity implements Stringifyable {
|
|||||||
@JoinColumn(name = "refundbankaccountuuid")
|
@JoinColumn(name = "refundbankaccountuuid")
|
||||||
private HsOfficeBankAccountEntity refundBankAccount;
|
private HsOfficeBankAccountEntity refundBankAccount;
|
||||||
|
|
||||||
|
public String getDebitorNumberString() {
|
||||||
|
return partner.getDebitorNumberPrefix() + String.format("%02d", debitorNumberSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDebitorNumber() {
|
||||||
|
return Integer.parseInt(getDebitorNumberString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column(name = "defaultprefix", columnDefinition = "char(3) not null")
|
||||||
|
private String defaultPrefix;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
@ -67,6 +81,6 @@ public class HsOfficeDebitorEntity implements Stringifyable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return debitorNumber.toString();
|
return getDebitorNumberString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,10 @@ class HsOfficeDebitorEntityPatcher implements EntityPatcher<HsOfficeDebitorPatch
|
|||||||
verifyNotNull(newValue, "vatBusiness");
|
verifyNotNull(newValue, "vatBusiness");
|
||||||
entity.setVatBusiness(newValue);
|
entity.setVatBusiness(newValue);
|
||||||
});
|
});
|
||||||
|
OptionalFromJson.of(resource.getDefaultPrefix()).ifPresent(newValue -> {
|
||||||
|
verifyNotNull(newValue, "defaultPrefix");
|
||||||
|
entity.setDefaultPrefix(newValue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyNotNull(final Object newValue, final String propertyName) {
|
private void verifyNotNull(final Object newValue, final String propertyName) {
|
||||||
|
@ -13,9 +13,14 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
|||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||||
WHERE debitor.debitorNumber = :debitorNumber
|
WHERE cast(debitor.partner.debitorNumberPrefix as integer) = :debitorNumberPrefix
|
||||||
|
AND cast(debitor.debitorNumberSuffix as integer) = :debitorNumberSuffix
|
||||||
""")
|
""")
|
||||||
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber);
|
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumberPrefix, byte debitorNumberSuffix);
|
||||||
|
|
||||||
|
default List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
|
||||||
|
return findDebitorByDebitorNumber( debitorNumber/100, (byte) (debitorNumber%100));
|
||||||
|
}
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||||
|
@ -58,6 +58,9 @@ public class HsOfficeMembershipEntity implements Stringifyable {
|
|||||||
@Type(PostgreSQLRangeType.class)
|
@Type(PostgreSQLRangeType.class)
|
||||||
private Range<LocalDate> validity;
|
private Range<LocalDate> validity;
|
||||||
|
|
||||||
|
@Column(name = "membership_fee_billable")
|
||||||
|
private boolean membershipFeeBillable;
|
||||||
|
|
||||||
@Column(name = "reasonfortermination")
|
@Column(name = "reasonfortermination")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private HsOfficeReasonForTermination reasonForTermination;
|
private HsOfficeReasonForTermination reasonForTermination;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.repository;
|
package net.hostsharing.hsadminng.hs.office.migration;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -3,14 +3,15 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.repository.HasUuid;
|
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.NotFound;
|
import org.hibernate.annotations.NotFound;
|
||||||
import org.hibernate.annotations.NotFoundAction;
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
@ -35,6 +36,9 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
|||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
|
@Column(name = "debitornumberprefix", columnDefinition = "numeric(5) not null")
|
||||||
|
private Integer debitorNumberPrefix;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "personuuid", nullable = false)
|
@JoinColumn(name = "personuuid", nullable = false)
|
||||||
private HsOfficePersonEntity person;
|
private HsOfficePersonEntity person;
|
||||||
@ -44,7 +48,7 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
|||||||
private HsOfficeContactEntity contact;
|
private HsOfficeContactEntity contact;
|
||||||
|
|
||||||
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, optional = true)
|
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, optional = true)
|
||||||
@JoinColumn(name = "detailsuuid", nullable = true)
|
@JoinColumn(name = "detailsuuid")
|
||||||
@NotFound(action = NotFoundAction.IGNORE)
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
private HsOfficePartnerDetailsEntity details;
|
private HsOfficePartnerDetailsEntity details;
|
||||||
|
|
||||||
@ -55,6 +59,6 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return person.toShortString();
|
return Optional.ofNullable(person).map(HsOfficePersonEntity::toShortString).orElse("<person=null>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import lombok.*;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.repository.HasUuid;
|
import net.hostsharing.hsadminng.hs.office.migration.HasUuid;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
|
@ -12,8 +12,13 @@ components:
|
|||||||
debitorNumber:
|
debitorNumber:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
minimum: 10000
|
minimum: 1000000
|
||||||
maximum: 99999
|
maximum: 9999999
|
||||||
|
debitorNumberSuffix:
|
||||||
|
type: integer
|
||||||
|
format: int8
|
||||||
|
minimum: 00
|
||||||
|
maximum: 99
|
||||||
partner:
|
partner:
|
||||||
$ref: './hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
$ref: './hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
||||||
billingContact:
|
billingContact:
|
||||||
@ -27,6 +32,9 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
refundBankAccount:
|
refundBankAccount:
|
||||||
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
|
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
|
||||||
|
defaultPrefix:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-z0-9]{3}$'
|
||||||
|
|
||||||
HsOfficeDebitorPatch:
|
HsOfficeDebitorPatch:
|
||||||
type: object
|
type: object
|
||||||
@ -49,6 +57,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
defaultPrefix:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-z0-9]{3}$'
|
||||||
|
nullable: true
|
||||||
|
|
||||||
HsOfficeDebitorInsert:
|
HsOfficeDebitorInsert:
|
||||||
type: object
|
type: object
|
||||||
@ -61,11 +73,11 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
debitorNumber:
|
debitorNumberSuffix:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int8
|
||||||
minimum: 10000
|
minimum: 00
|
||||||
maximum: 99999
|
maximum: 99
|
||||||
vatId:
|
vatId:
|
||||||
type: string
|
type: string
|
||||||
vatCountryCode:
|
vatCountryCode:
|
||||||
@ -76,6 +88,11 @@ components:
|
|||||||
refundBankAccountUuid:
|
refundBankAccountUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
defaultPrefix:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-z]{3}$'
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- partnerUuid
|
- partnerUuid
|
||||||
- billingContactUuid
|
- billingContactUuid
|
||||||
|
- defaultPrefix
|
||||||
|
@ -155,7 +155,7 @@ create or replace function cleanIdentifier(rawIdentifier varchar)
|
|||||||
declare
|
declare
|
||||||
cleanIdentifier varchar;
|
cleanIdentifier varchar;
|
||||||
begin
|
begin
|
||||||
cleanIdentifier := regexp_replace(rawIdentifier, '[^A-Za-z0-9\-._]+', '', 'g');
|
cleanIdentifier := regexp_replace(rawIdentifier, '[^A-Za-z0-9\-._:]+', '', 'g');
|
||||||
return cleanIdentifier;
|
return cleanIdentifier;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ create or replace function determineCurrentSubjectsUuids(currentUserUuid uuid, a
|
|||||||
stable leakproof
|
stable leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
roleName varchar(63);
|
roleName text;
|
||||||
roleNameParts varchar(63);
|
roleNameParts text;
|
||||||
objectTableToAssume varchar(63);
|
objectTableToAssume varchar(63);
|
||||||
objectNameToAssume varchar(63);
|
objectNameToAssume varchar(63);
|
||||||
objectUuidToAssume uuid;
|
objectUuidToAssume uuid;
|
||||||
|
@ -31,6 +31,7 @@ call create_journal('hs_office_partner_details');
|
|||||||
create table hs_office_partner
|
create table hs_office_partner
|
||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
|
debitorNumberPrefix varchar(5),
|
||||||
personUuid uuid not null references hs_office_person(uuid),
|
personUuid uuid not null references hs_office_person(uuid),
|
||||||
contactUuid uuid not null references hs_office_contact(uuid),
|
contactUuid uuid not null references hs_office_contact(uuid),
|
||||||
detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade
|
detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade
|
||||||
|
@ -27,7 +27,6 @@ create or replace function hsOfficePartnerRbacRolesTrigger()
|
|||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
declare
|
||||||
hsOfficePartnerTenant RbacRoleDescriptor;
|
|
||||||
oldPerson hs_office_person;
|
oldPerson hs_office_person;
|
||||||
newPerson hs_office_person;
|
newPerson hs_office_person;
|
||||||
oldContact hs_office_contact;
|
oldContact hs_office_contact;
|
||||||
@ -166,6 +165,8 @@ execute procedure hsOfficePartnerRbacRolesTrigger();
|
|||||||
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityView('hs_office_partner', $idName$
|
call generateRbacIdentityView('hs_office_partner', $idName$
|
||||||
|
-- TODO: simplify by using just debitorNumberPrefix for the essential part
|
||||||
|
debitorNumberPrefix || ':' ||
|
||||||
(select idName from hs_office_person_iv p where p.uuid = target.personuuid)
|
(select idName from hs_office_person_iv p where p.uuid = target.personuuid)
|
||||||
|| '-' ||
|
|| '-' ||
|
||||||
(select idName from hs_office_contact_iv c where c.uuid = target.contactuuid)
|
(select idName from hs_office_contact_iv c where c.uuid = target.contactuuid)
|
||||||
|
@ -8,7 +8,10 @@
|
|||||||
/*
|
/*
|
||||||
Creates a single partner test record.
|
Creates a single partner test record.
|
||||||
*/
|
*/
|
||||||
create or replace procedure createHsOfficePartnerTestData( personTradeOrFamilyName varchar, contactLabel varchar )
|
create or replace procedure createHsOfficePartnerTestData(
|
||||||
|
debitorNumberPrefix numeric(5),
|
||||||
|
personTradeOrFamilyName varchar,
|
||||||
|
contactLabel varchar )
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
@ -51,8 +54,8 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
insert
|
insert
|
||||||
into hs_office_partner (uuid, personuuid, contactuuid, detailsUuid)
|
into hs_office_partner (uuid, debitorNumberPrefix, personuuid, contactuuid, detailsUuid)
|
||||||
values (uuid_generate_v4(), relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
values (uuid_generate_v4(), debitorNumberPrefix, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -64,11 +67,11 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficePartnerTestData('First GmbH', 'first contact');
|
call createHsOfficePartnerTestData(10001, 'First GmbH', 'first contact');
|
||||||
call createHsOfficePartnerTestData('Second e.K.', 'second contact');
|
call createHsOfficePartnerTestData(10002, 'Second e.K.', 'second contact');
|
||||||
call createHsOfficePartnerTestData('Third OHG', 'third contact');
|
call createHsOfficePartnerTestData(10003, 'Third OHG', 'third contact');
|
||||||
call createHsOfficePartnerTestData('Fourth e.G.', 'forth contact');
|
call createHsOfficePartnerTestData(10004, 'Fourth e.G.', 'forth contact');
|
||||||
call createHsOfficePartnerTestData('Smith', 'fifth contact');
|
call createHsOfficePartnerTestData(10010, 'Smith', 'fifth contact');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -8,12 +8,17 @@ create table hs_office_debitor
|
|||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
partnerUuid uuid not null references hs_office_partner(uuid),
|
partnerUuid uuid not null references hs_office_partner(uuid),
|
||||||
debitorNumber numeric(5) not null,
|
billable boolean not null default true,
|
||||||
|
debitorNumberSuffix numeric(2) not null,
|
||||||
billingContactUuid uuid not null references hs_office_contact(uuid),
|
billingContactUuid uuid not null references hs_office_contact(uuid),
|
||||||
vatId varchar(24), -- TODO.spec: here or in person?
|
vatId varchar(24), -- TODO.spec: here or in person?
|
||||||
vatCountryCode varchar(2),
|
vatCountryCode varchar(2),
|
||||||
vatBusiness boolean not null, -- TODO.spec: more of such?
|
vatBusiness boolean not null, -- TODO.spec: more of such?
|
||||||
refundBankAccountUuid uuid references hs_office_bankaccount(uuid)
|
refundBankAccountUuid uuid references hs_office_bankaccount(uuid),
|
||||||
|
defaultPrefix char(3) not null
|
||||||
|
constraint check_member_code check (
|
||||||
|
defaultPrefix::text ~ '^([a-z]{3}|al0|bh1|c4s|f3k|k8i|l3d|mh1|o13|p2m|s80|t4w)$'
|
||||||
|
)
|
||||||
-- TODO.impl: SEPA-mandate
|
-- TODO.impl: SEPA-mandate
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
@ -172,8 +172,10 @@ execute procedure hsOfficeDebitorRbacRolesTrigger();
|
|||||||
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityView('hs_office_debitor', $idName$
|
call generateRbacIdentityView('hs_office_debitor', $idName$
|
||||||
'#' || debitorNumber || ':' ||
|
'#' ||
|
||||||
(select idName from hs_office_partner_iv p where p.uuid = target.partnerUuid)
|
(select debitornumberprefix from hs_office_partner p where p.uuid = target.partnerUuid) ||
|
||||||
|
to_char(debitorNumberSuffix, 'fm00') ||
|
||||||
|
':' || (select split_part(idName, ':', 2) from hs_office_partner_iv pi where pi.uuid = target.partnerUuid)
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -181,14 +183,17 @@ call generateRbacIdentityView('hs_office_debitor', $idName$
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumber',
|
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumberSuffix',
|
||||||
$updates$
|
$updates$
|
||||||
partnerUuid = new.partnerUuid,
|
partnerUuid = new.partnerUuid,
|
||||||
|
billable = new.billable,
|
||||||
billingContactUuid = new.billingContactUuid,
|
billingContactUuid = new.billingContactUuid,
|
||||||
|
debitorNumberSuffix = new.debitorNumberSuffix,
|
||||||
refundBankAccountUuid = new.refundBankAccountUuid,
|
refundBankAccountUuid = new.refundBankAccountUuid,
|
||||||
vatId = new.vatId,
|
vatId = new.vatId,
|
||||||
vatCountryCode = new.vatCountryCode,
|
vatCountryCode = new.vatCountryCode,
|
||||||
vatBusiness = new.vatBusiness
|
vatBusiness = new.vatBusiness,
|
||||||
|
defaultPrefix = new.defaultPrefix
|
||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
/*
|
/*
|
||||||
Creates a single debitor test record.
|
Creates a single debitor test record.
|
||||||
*/
|
*/
|
||||||
create or replace procedure createHsOfficeDebitorTestData( partnerTradeName varchar, billingContactLabel varchar )
|
create or replace procedure createHsOfficeDebitorTestData(
|
||||||
|
debitorNumberSuffix numeric(5),
|
||||||
|
partnerTradeName varchar,
|
||||||
|
billingContactLabel varchar,
|
||||||
|
defaultPrefix varchar
|
||||||
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
@ -16,7 +21,6 @@ declare
|
|||||||
relatedPartner hs_office_partner;
|
relatedPartner hs_office_partner;
|
||||||
relatedContact hs_office_contact;
|
relatedContact hs_office_contact;
|
||||||
relatedBankAccountUuid uuid;
|
relatedBankAccountUuid uuid;
|
||||||
newDebitorNumber numeric(6);
|
|
||||||
begin
|
begin
|
||||||
idName := cleanIdentifier( partnerTradeName|| '-' || billingContactLabel);
|
idName := cleanIdentifier( partnerTradeName|| '-' || billingContactLabel);
|
||||||
currentTask := 'creating debitor test-data ' || idName;
|
currentTask := 'creating debitor test-data ' || idName;
|
||||||
@ -28,14 +32,14 @@ begin
|
|||||||
where person.tradeName = partnerTradeName into relatedPartner;
|
where person.tradeName = partnerTradeName into relatedPartner;
|
||||||
select c.* from hs_office_contact c where c.label = billingContactLabel into relatedContact;
|
select c.* from hs_office_contact c where c.label = billingContactLabel into relatedContact;
|
||||||
select b.uuid from hs_office_bankaccount b where b.holder = partnerTradeName into relatedBankAccountUuid;
|
select b.uuid from hs_office_bankaccount b where b.holder = partnerTradeName into relatedBankAccountUuid;
|
||||||
select coalesce(max(debitorNumber)+1, 10001) from hs_office_debitor into newDebitorNumber;
|
|
||||||
|
|
||||||
raise notice 'creating test debitor: % (#%)', idName, newDebitorNumber;
|
-- raise notice 'creating test debitor: % (#%)', idName, relatedPartner.debitorNumberPrefix || '00';
|
||||||
|
raise notice 'creating test debitor: % (#%)', idName, debitorNumberSuffix;
|
||||||
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
||||||
raise notice '- using billingContact (%): %', relatedContact.uuid, relatedContact;
|
raise notice '- using billingContact (%): %', relatedContact.uuid, relatedContact;
|
||||||
insert
|
insert
|
||||||
into hs_office_debitor (uuid, partneruuid, debitornumber, billingcontactuuid, vatbusiness, refundbankaccountuuid)
|
into hs_office_debitor (uuid, partneruuid, debitornumbersuffix, billable, billingcontactuuid, vatbusiness, refundbankaccountuuid, defaultprefix)
|
||||||
values (uuid_generate_v4(), relatedPartner.uuid, newDebitorNumber, relatedContact.uuid, true, relatedBankAccountUuid);
|
values (uuid_generate_v4(), relatedPartner.uuid, debitorNumberSuffix, true, relatedContact.uuid, true, relatedBankAccountUuid, defaultPrefix);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -46,9 +50,9 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficeDebitorTestData('First GmbH', 'first contact');
|
call createHsOfficeDebitorTestData(11, 'First GmbH', 'first contact', 'fir');
|
||||||
call createHsOfficeDebitorTestData('Second e.K.', 'second contact');
|
call createHsOfficeDebitorTestData(12, 'Second e.K.', 'second contact', 'sec');
|
||||||
call createHsOfficeDebitorTestData('Third OHG', 'third contact');
|
call createHsOfficeDebitorTestData(13, 'Third OHG', 'third contact', 'thi');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -15,7 +15,8 @@ create table if not exists hs_office_membership
|
|||||||
mainDebitorUuid uuid not null references hs_office_debitor(uuid),
|
mainDebitorUuid uuid not null references hs_office_debitor(uuid),
|
||||||
memberNumber numeric(5) not null unique,
|
memberNumber numeric(5) not null unique,
|
||||||
validity daterange not null,
|
validity daterange not null,
|
||||||
reasonForTermination HsOfficeReasonForTermination not null default 'NONE'
|
reasonForTermination HsOfficeReasonForTermination not null default 'NONE',
|
||||||
|
membership_fee_billable boolean not null default true
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ create or replace function hsOfficeMembershipRbacRolesTrigger()
|
|||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
declare
|
||||||
newHsOfficePartner hs_office_partner;
|
newHsOfficePartner hs_office_partner;
|
||||||
newHsOfficeDebitor hs_office_debitor;
|
newHsOfficeDebitor hs_office_debitor;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@ -92,7 +92,8 @@ execute procedure hsOfficeMembershipRbacRolesTrigger();
|
|||||||
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityView('hs_office_membership', idNameExpression => $idName$
|
call generateRbacIdentityView('hs_office_membership', idNameExpression => $idName$
|
||||||
target.memberNumber || (select idName from hs_office_partner_iv p where p.uuid = target.partnerUuid)
|
target.memberNumber ||
|
||||||
|
':' || (select split_part(idName, ':', 2) from hs_office_partner_iv p where p.uuid = target.partnerUuid)
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -104,7 +105,8 @@ call generateRbacRestrictedView('hs_office_membership',
|
|||||||
orderby => 'target.memberNumber',
|
orderby => 'target.memberNumber',
|
||||||
columnUpdates => $updates$
|
columnUpdates => $updates$
|
||||||
validity = new.validity,
|
validity = new.validity,
|
||||||
reasonForTermination = new.reasonForTermination
|
reasonForTermination = new.reasonForTermination,
|
||||||
|
membership_fee_billable = new.membership_fee_billable
|
||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -8,14 +8,17 @@
|
|||||||
/*
|
/*
|
||||||
Creates a single membership test record.
|
Creates a single membership test record.
|
||||||
*/
|
*/
|
||||||
|
-- create or replace procedure createHsOfficeMembershipTestData( forPartnerTradeName varchar, forMainDebitorNumber integer )
|
||||||
create or replace procedure createHsOfficeMembershipTestData( forPartnerTradeName varchar, forMainDebitorNumber numeric )
|
create or replace procedure createHsOfficeMembershipTestData( forPartnerTradeName varchar, forMainDebitorNumber numeric )
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
idName varchar;
|
idName varchar;
|
||||||
relatedPartner hs_office_partner;
|
-- forDebitorNumberPrefix integer;
|
||||||
relatedDebitor hs_office_debitor;
|
-- forDebitorNumberSuffix integer;
|
||||||
newMemberNumber numeric;
|
relatedPartner hs_office_partner;
|
||||||
|
relatedDebitor hs_office_debitor;
|
||||||
|
newMemberNumber numeric;
|
||||||
begin
|
begin
|
||||||
idName := cleanIdentifier( forPartnerTradeName || '#' || forMainDebitorNumber);
|
idName := cleanIdentifier( forPartnerTradeName || '#' || forMainDebitorNumber);
|
||||||
currentTask := 'creating Membership test-data ' || idName;
|
currentTask := 'creating Membership test-data ' || idName;
|
||||||
@ -25,7 +28,10 @@ begin
|
|||||||
select partner.* from hs_office_partner partner
|
select partner.* from hs_office_partner partner
|
||||||
join hs_office_person person on person.uuid = partner.personUuid
|
join hs_office_person person on person.uuid = partner.personUuid
|
||||||
where person.tradeName = forPartnerTradeName into relatedPartner;
|
where person.tradeName = forPartnerTradeName into relatedPartner;
|
||||||
select d.* from hs_office_debitor d where d.debitorNumber = forMainDebitorNumber into relatedDebitor;
|
-- forDebitorNumberPrefix := forMainDebitorNumber/ 100;
|
||||||
|
-- forDebitorNumberSuffix := mod(forMainDebitorNumber, 100);
|
||||||
|
-- select d.* from hs_office_debitor d where d.debitorNumberSuffix = forDebitorNumberSuffix into relatedDebitor;
|
||||||
|
select d.* from hs_office_debitor d where d.debitorNumberSuffix = forMainDebitorNumber into relatedDebitor;
|
||||||
select coalesce(max(memberNumber)+1, 10001) from hs_office_membership into newMemberNumber;
|
select coalesce(max(memberNumber)+1, 10001) from hs_office_membership into newMemberNumber;
|
||||||
|
|
||||||
raise notice 'creating test Membership: %', idName;
|
raise notice 'creating test Membership: %', idName;
|
||||||
@ -33,6 +39,7 @@ begin
|
|||||||
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
||||||
insert
|
insert
|
||||||
into hs_office_membership (uuid, partneruuid, maindebitoruuid, membernumber, validity, reasonfortermination)
|
into hs_office_membership (uuid, partneruuid, maindebitoruuid, membernumber, validity, reasonfortermination)
|
||||||
|
-- values (uuid_generate_v4(), relatedPartner.uuid, relatedDebitor.uuid, forDebitorNumberPrefix, daterange('20221001' , null, '[]'), 'NONE');
|
||||||
values (uuid_generate_v4(), relatedPartner.uuid, relatedDebitor.uuid, newMemberNumber, daterange('20221001' , null, '[]'), 'NONE');
|
values (uuid_generate_v4(), relatedPartner.uuid, relatedDebitor.uuid, newMemberNumber, daterange('20221001' , null, '[]'), 'NONE');
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
@ -44,9 +51,14 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficeMembershipTestData('First GmbH', 10001);
|
call createHsOfficeMembershipTestData('First GmbH', 11);
|
||||||
call createHsOfficeMembershipTestData('Second e.K.', 10002);
|
call createHsOfficeMembershipTestData('Second e.K.', 12);
|
||||||
call createHsOfficeMembershipTestData('Third OHG', 10003);
|
call createHsOfficeMembershipTestData('Third OHG', 13);
|
||||||
end;
|
end;
|
||||||
|
-- begin
|
||||||
|
-- call createHsOfficeMembershipTestData('First GmbH', 1000100);
|
||||||
|
-- call createHsOfficeMembershipTestData('Second e.K.', 1000200);
|
||||||
|
-- call createHsOfficeMembershipTestData('Third OHG', 1000300);
|
||||||
|
-- end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
||||||
|
@ -200,7 +200,9 @@ public class ArchitectureTest {
|
|||||||
public static final ArchRule hsOfficeCoopSharesPackageRule = classes()
|
public static final ArchRule hsOfficeCoopSharesPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.coopshares..")
|
.that().resideInAPackage("..hs.office.coopshares..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.coopshares..");
|
.resideInAnyPackage(
|
||||||
|
"..hs.office.coopshares..",
|
||||||
|
"..hs.office.migration..");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -117,7 +117,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm view on coopassetstransaction#temprefB to role membership#10001....tenant by system and assume }",
|
"{ grant perm view on coopassetstransaction#temprefB to role membership#10001:....tenant by system and assume }",
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,8 +200,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewOnlyRelatedCoopAssetsTransactions() {
|
public void normalUser_canViewOnlyRelatedCoopAssetsTransactions() {
|
||||||
// given:
|
// given:
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.admin");
|
||||||
// "hs_office_person#FirstGmbH.admin",
|
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
|
final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
|
@ -116,7 +116,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm view on coopsharestransaction#temprefB to role membership#10001....tenant by system and assume }",
|
"{ grant perm view on coopsharestransaction#temprefB to role membership#10001:....tenant by system and assume }",
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,8 +199,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewOnlyRelatedCoopSharesTransactions() {
|
public void normalUser_canViewOnlyRelatedCoopSharesTransactions() {
|
||||||
// given:
|
// given:
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.admin");
|
||||||
// "hs_office_person#FirstGmbH.admin",
|
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
|
@ -35,8 +35,8 @@ import static org.hamcrest.Matchers.*;
|
|||||||
@Transactional
|
@Transactional
|
||||||
class HsOfficeDebitorControllerAcceptanceTest {
|
class HsOfficeDebitorControllerAcceptanceTest {
|
||||||
|
|
||||||
private static final int LOWEST_TEMP_DEBITOR_NUMBER = 20000;
|
private static final int LOWEST_TEMP_DEBITOR_SUFFIX = 90;
|
||||||
private static int nextDebitorNumber = LOWEST_TEMP_DEBITOR_NUMBER;
|
private static byte nextDebitorSuffix = LOWEST_TEMP_DEBITOR_SUFFIX;
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
private Integer port;
|
private Integer port;
|
||||||
@ -81,7 +81,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
|
"debitorNumberSuffix": 11,
|
||||||
"partner": { "person": { "personType": "LEGAL" } },
|
"partner": { "person": { "personType": "LEGAL" } },
|
||||||
"billingContact": { "label": "first contact" },
|
"billingContact": { "label": "first contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -90,7 +91,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
"refundBankAccount": { "holder": "First GmbH" }
|
"refundBankAccount": { "holder": "First GmbH" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitorNumber": 10002,
|
"debitorNumber": 1000212,
|
||||||
|
"debitorNumberSuffix": 12,
|
||||||
"partner": { "person": { "tradeName": "Second e.K." } },
|
"partner": { "person": { "tradeName": "Second e.K." } },
|
||||||
"billingContact": { "label": "second contact" },
|
"billingContact": { "label": "second contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -99,7 +101,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
"refundBankAccount": { "holder": "Second e.K." }
|
"refundBankAccount": { "holder": "Second e.K." }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitorNumber": 10003,
|
"debitorNumber": 1000313,
|
||||||
|
"debitorNumberSuffix": 13,
|
||||||
"partner": { "person": { "tradeName": "Third OHG" } },
|
"partner": { "person": { "tradeName": "Third OHG" } },
|
||||||
"billingContact": { "label": "third contact" },
|
"billingContact": { "label": "third contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -120,14 +123,14 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors?debitorNumber=10002")
|
.get("http://localhost/api/hs/office/debitors?debitorNumber=1000212")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitorNumber": 10002,
|
"debitorNumber": 1000212,
|
||||||
"partner": { "person": { "tradeName": "Second e.K." } },
|
"partner": { "person": { "tradeName": "Second e.K." } },
|
||||||
"billingContact": { "label": "second contact" },
|
"billingContact": { "label": "second contact" },
|
||||||
"vatId": null,
|
"vatId": null,
|
||||||
@ -160,13 +163,14 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s",
|
"debitorNumberSuffix": "%s",
|
||||||
"vatId": "VAT123456",
|
"vatId": "VAT123456",
|
||||||
"vatCountryCode": "DE",
|
"vatCountryCode": "DE",
|
||||||
"vatBusiness": true,
|
"vatBusiness": true,
|
||||||
"refundBankAccountUuid": "%s"
|
"refundBankAccountUuid": "%s",
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber, givenBankAccount.getUuid()))
|
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorSuffix, givenBankAccount.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -175,6 +179,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("vatId", is("VAT123456"))
|
.body("vatId", is("VAT123456"))
|
||||||
|
.body("defaultPrefix", is("for"))
|
||||||
.body("billingContact.label", is(givenContact.getLabel()))
|
.body("billingContact.label", is(givenContact.getLabel()))
|
||||||
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName()))
|
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName()))
|
||||||
.body("refundBankAccount.holder", is(givenBankAccount.getHolder()))
|
.body("refundBankAccount.holder", is(givenBankAccount.getHolder()))
|
||||||
@ -202,9 +207,10 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s"
|
"debitorNumberSuffix": "%s",
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber))
|
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorSuffix))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -218,6 +224,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.body("vatCountryCode", equalTo(null))
|
.body("vatCountryCode", equalTo(null))
|
||||||
.body("vatBusiness", equalTo(false))
|
.body("vatBusiness", equalTo(false))
|
||||||
.body("refundBankAccount", equalTo(null))
|
.body("refundBankAccount", equalTo(null))
|
||||||
|
.body("defaultPrefix", equalTo("for"))
|
||||||
.header("Location", startsWith("http://localhost"))
|
.header("Location", startsWith("http://localhost"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
@ -242,12 +249,14 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s",
|
"debitorNumberSuffix": "%s",
|
||||||
"vatId": "VAT123456",
|
"vatId": "VAT123456",
|
||||||
"vatCountryCode": "DE",
|
"vatCountryCode": "DE",
|
||||||
"vatBusiness": true
|
"vatBusiness": true,
|
||||||
|
"defaultPrefix": "thi"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorNumber))
|
"""
|
||||||
|
.formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorSuffix))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -272,12 +281,13 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partnerUuid": "%s",
|
"partnerUuid": "%s",
|
||||||
"billingContactUuid": "%s",
|
"billingContactUuid": "%s",
|
||||||
"debitorNumber": "%s",
|
"debitorNumberSuffix": "%s",
|
||||||
"vatId": "VAT123456",
|
"vatId": "VAT123456",
|
||||||
"vatCountryCode": "DE",
|
"vatCountryCode": "DE",
|
||||||
"vatBusiness": true
|
"vatBusiness": true,
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorNumber))
|
""".formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorSuffix))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/debitors")
|
.post("http://localhost/api/hs/office/debitors")
|
||||||
@ -375,7 +385,8 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"vatId": "VAT222222",
|
"vatId": "VAT222222",
|
||||||
"vatCountryCode": "AA",
|
"vatCountryCode": "AA",
|
||||||
"vatBusiness": true
|
"vatBusiness": true,
|
||||||
|
"defaultPrefix": "for"
|
||||||
}
|
}
|
||||||
""".formatted(givenContact.getUuid()))
|
""".formatted(givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -388,6 +399,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
.body("vatId", is("VAT222222"))
|
.body("vatId", is("VAT222222"))
|
||||||
.body("vatCountryCode", is("AA"))
|
.body("vatCountryCode", is("AA"))
|
||||||
.body("vatBusiness", is(true))
|
.body("vatBusiness", is(true))
|
||||||
|
.body("defaultPrefix", is("for"))
|
||||||
.body("billingContact.label", is(givenContact.getLabel()))
|
.body("billingContact.label", is(givenContact.getLabel()))
|
||||||
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName()));
|
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName()));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
@ -522,9 +534,10 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(++nextDebitorNumber)
|
.debitorNumberSuffix(++nextDebitorSuffix)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
|
.defaultPrefix("abc")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
@ -537,7 +550,7 @@ class HsOfficeDebitorControllerAcceptanceTest {
|
|||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var count = em.createQuery(
|
final var count = em.createQuery(
|
||||||
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumber > " + LOWEST_TEMP_DEBITOR_NUMBER)
|
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX)
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
System.out.printf("deleted %d entities%n", count);
|
System.out.printf("deleted %d entities%n", count);
|
||||||
});
|
});
|
||||||
|
@ -31,6 +31,7 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
||||||
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
||||||
|
|
||||||
|
private static final String PATCHED_DEFAULT_PREFIX = "xyz";
|
||||||
private static final String PATCHED_VAT_COUNTRY_CODE = "ZZ";
|
private static final String PATCHED_VAT_COUNTRY_CODE = "ZZ";
|
||||||
|
|
||||||
private static final boolean PATCHED_VAT_BUSINESS = false;
|
private static final boolean PATCHED_VAT_BUSINESS = false;
|
||||||
@ -62,6 +63,7 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
entity.setVatId("initial VAT-ID");
|
entity.setVatId("initial VAT-ID");
|
||||||
entity.setVatCountryCode("AA");
|
entity.setVatCountryCode("AA");
|
||||||
entity.setVatBusiness(true);
|
entity.setVatBusiness(true);
|
||||||
|
entity.setDefaultPrefix("abc");
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +102,12 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
HsOfficeDebitorPatchResource::setVatBusiness,
|
HsOfficeDebitorPatchResource::setVatBusiness,
|
||||||
PATCHED_VAT_BUSINESS,
|
PATCHED_VAT_BUSINESS,
|
||||||
HsOfficeDebitorEntity::setVatBusiness)
|
HsOfficeDebitorEntity::setVatBusiness)
|
||||||
|
.notNullable(),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"defaultPrefix",
|
||||||
|
HsOfficeDebitorPatchResource::setDefaultPrefix,
|
||||||
|
PATCHED_DEFAULT_PREFIX,
|
||||||
|
HsOfficeDebitorEntity::setDefaultPrefix)
|
||||||
.notNullable()
|
.notNullable()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,30 +13,50 @@ class HsOfficeDebitorEntityUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void toStringContainsPartnerAndContact() {
|
void toStringContainsPartnerAndContact() {
|
||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(123456)
|
.debitorNumberSuffix((byte)67)
|
||||||
.partner(HsOfficePartnerEntity.builder()
|
.partner(HsOfficePartnerEntity.builder()
|
||||||
.person(HsOfficePersonEntity.builder()
|
.person(HsOfficePersonEntity.builder()
|
||||||
.tradeName("some trade name")
|
.tradeName("some trade name")
|
||||||
.build())
|
.build())
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
|
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
|
||||||
|
.debitorNumberPrefix(12345)
|
||||||
.build())
|
.build())
|
||||||
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
|
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.toString();
|
final var result = given.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("debitor(123456: some trade name)");
|
assertThat(result).isEqualTo("debitor(1234567: some trade name)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsPartnerAndContact() {
|
void toStringWithoutPersonContainsDebitorNumber() {
|
||||||
final var given = HsOfficeDebitorEntity.builder()
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(123456)
|
.debitorNumberSuffix((byte)67)
|
||||||
|
.partner(HsOfficePartnerEntity.builder()
|
||||||
|
.person(null)
|
||||||
|
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
|
||||||
|
.debitorNumberPrefix(12345)
|
||||||
|
.build())
|
||||||
|
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final var result = given.toString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("debitor(1234567: <person=null>)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toShortStringContainsDebitorNumber() {
|
||||||
|
final var given = HsOfficeDebitorEntity.builder()
|
||||||
|
.partner(HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(12345)
|
||||||
|
.build())
|
||||||
|
.debitorNumberSuffix((byte)67)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var result = given.toShortString();
|
final var result = given.toShortString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("123456");
|
assertThat(result).isEqualTo("1234567");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,9 +81,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(20001)
|
.debitorNumberSuffix((byte)21)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
|
.defaultPrefix("abc")
|
||||||
.build();
|
.build();
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
});
|
});
|
||||||
@ -95,14 +96,43 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
assertThat(debitorRepo.count()).isEqualTo(count + 1);
|
assertThat(debitorRepo.count()).isEqualTo(count + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ParameterizedTest
|
||||||
|
// @ValueSource(strings = {"", "a", "ab", "a12", "123", "12a"})
|
||||||
|
// public void canNotCreateNewDebitorWithInvalidDefaultPrefix(final String givenPrefix) {
|
||||||
|
// // given
|
||||||
|
// context("superuser-alex@hostsharing.net");
|
||||||
|
// final var count = debitorRepo.count();
|
||||||
|
// final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First GmbH").get(0);
|
||||||
|
// final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
||||||
|
//
|
||||||
|
// // when
|
||||||
|
// final var result = attempt(em, () -> {
|
||||||
|
// final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
|
// .debitorNumberSuffix((byte)21)
|
||||||
|
// .partner(givenPartner)
|
||||||
|
// .billingContact(givenContact)
|
||||||
|
// .defaultPrefix(givenPrefix)
|
||||||
|
// .build();
|
||||||
|
// return debitorRepo.save(newDebitor);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // then
|
||||||
|
// result.assertSuccessful();
|
||||||
|
// assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeDebitorEntity::getUuid).isNotNull();
|
||||||
|
// assertThatDebitorIsPersisted(result.returnedValue());
|
||||||
|
// assertThat(debitorRepo.count()).isEqualTo(count + 1);
|
||||||
|
// }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createsAndGrantsRoles() {
|
public void createsAndGrantsRoles() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
|
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
|
||||||
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll()).stream()
|
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll()).stream()
|
||||||
|
// some search+replace to make the output fit into the screen width
|
||||||
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
||||||
.map(s -> s.replace("20002Fourthe.G.-forthcontact", "FeG"))
|
// .map(s -> s.replace("1000422Fourthe.G.-forthcontact", "FeG"))
|
||||||
|
.map(s -> s.replace("22Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("forthcontact", "4th"))
|
.map(s -> s.replace("forthcontact", "4th"))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
@ -113,9 +143,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(20002)
|
.debitorNumberSuffix((byte)22)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
|
.defaultPrefix("abc")
|
||||||
.build();
|
.build();
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
@ -123,42 +154,43 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.owner",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.owner",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.admin",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.admin",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.agent",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.agent",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.tenant",
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.tenant",
|
||||||
"hs_office_debitor#20002Fourthe.G.-forthcontact.guest"));
|
"hs_office_debitor#1000422:Fourthe.G.-forthcontact.guest"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
.map(s -> s.replace("superuser-alex@hostsharing.net", "superuser-alex"))
|
||||||
.map(s -> s.replace("20002Fourthe.G.-forthcontact", "FeG"))
|
// .map(s -> s.replace("1000422Fourthe.G.-forthcontact", "FeG"))
|
||||||
|
.map(s -> s.replace("22Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
.map(s -> s.replace("Fourthe.G.-forthcontact", "FeG"))
|
||||||
.map(s -> s.replace("forthcontact", "4th"))
|
.map(s -> s.replace("forthcontact", "4th"))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on debitor#FeG to role debitor#FeG.owner by system and assume }",
|
"{ grant perm * on debitor#1000422:FeG to role debitor#1000422:FeG.owner by system and assume }",
|
||||||
"{ grant role debitor#FeG.owner to role global#global.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.owner to role global#global.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.owner to user superuser-alex by global#global.admin and assume }",
|
"{ grant role debitor#1000422:FeG.owner to user superuser-alex by global#global.admin and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on debitor#FeG to role debitor#FeG.admin by system and assume }",
|
"{ grant perm edit on debitor#1000422:FeG to role debitor#1000422:FeG.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.admin to role debitor#FeG.owner by system and assume }",
|
"{ grant role debitor#1000422:FeG.admin to role debitor#1000422:FeG.owner by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role debitor#FeG.agent to role debitor#FeG.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.agent to role debitor#1000422:FeG.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.agent to role contact#4th.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.agent to role contact#4th.admin by system and assume }",
|
||||||
"{ grant role debitor#FeG.agent to role partner#FeG.admin by system and assume }",
|
"{ grant role debitor#1000422:FeG.agent to role partner#10004:FeG.admin by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role contact#4th.guest to role debitor#FeG.tenant by system and assume }",
|
"{ grant role contact#4th.guest to role debitor#1000422:FeG.tenant by system and assume }",
|
||||||
"{ grant role debitor#FeG.tenant to role debitor#FeG.agent by system and assume }",
|
"{ grant role debitor#1000422:FeG.tenant to role debitor#1000422:FeG.agent by system and assume }",
|
||||||
"{ grant role debitor#FeG.tenant to role partner#FeG.agent by system and assume }",
|
"{ grant role debitor#1000422:FeG.tenant to role partner#10004:FeG.agent by system and assume }",
|
||||||
"{ grant role partner#FeG.tenant to role debitor#FeG.tenant by system and assume }",
|
"{ grant role partner#10004:FeG.tenant to role debitor#1000422:FeG.tenant by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on debitor#FeG to role debitor#FeG.guest by system and assume }",
|
"{ grant perm view on debitor#1000422:FeG to role debitor#1000422:FeG.guest by system and assume }",
|
||||||
"{ grant role debitor#FeG.guest to role debitor#FeG.tenant by system and assume }",
|
"{ grant role debitor#1000422:FeG.guest to role debitor#1000422:FeG.tenant by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -183,14 +215,14 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
allTheseDebitorsAreReturned(
|
allTheseDebitorsAreReturned(
|
||||||
result,
|
result,
|
||||||
"debitor(10001: First GmbH)",
|
"debitor(1000111: First GmbH)",
|
||||||
"debitor(10002: Second e.K.)",
|
"debitor(1000212: Second e.K.)",
|
||||||
"debitor(10003: Third OHG)");
|
"debitor(1000313: Third OHG)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {
|
@ValueSource(strings = {
|
||||||
"hs_office_partner#FirstGmbH-firstcontact.admin",
|
"hs_office_partner#10001:FirstGmbH-firstcontact.admin",
|
||||||
"hs_office_person#FirstGmbH.admin",
|
"hs_office_person#FirstGmbH.admin",
|
||||||
"hs_office_contact#firstcontact.admin",
|
"hs_office_contact#firstcontact.admin",
|
||||||
})
|
})
|
||||||
@ -202,7 +234,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
|
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseDebitorsAreReturned(result, "debitor(10001: First GmbH)");
|
exactlyTheseDebitorsAreReturned(result, "debitor(1000111: First GmbH)", "debitor(1000120: First GmbH)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -227,10 +259,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = debitorRepo.findDebitorByDebitorNumber(10003);
|
final var result = debitorRepo.findDebitorByDebitorNumber(1000313);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
|
// exactlyTheseDebitorsAreReturned(result, "debitor(1000313: Third OHG)", "debitor(1000413: Fourth e.G.)");
|
||||||
|
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: Third OHG)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +279,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
|
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
|
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: Third OHG)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +290,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canUpdateArbitraryDebitor() {
|
public void globalAdmin_canUpdateArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fif");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
final var givenNewPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0);
|
final var givenNewPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0);
|
||||||
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
|
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
|
||||||
@ -290,10 +323,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// ... partner role was reassigned:
|
// ... partner role was reassigned:
|
||||||
assertThatDebitorIsNotVisibleForUserWithRole(
|
assertThatDebitorIsNotVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.agent");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.agent");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office_partner#FirstGmbH-firstcontact.agent");
|
"hs_office_partner#10001:FirstGmbH-firstcontact.agent");
|
||||||
|
|
||||||
// ... contact role was reassigned:
|
// ... contact role was reassigned:
|
||||||
assertThatDebitorIsNotVisibleForUserWithRole(
|
assertThatDebitorIsNotVisibleForUserWithRole(
|
||||||
@ -316,10 +349,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canUpdateNullRefundBankAccountToNotNullBankAccountForArbitraryDebitor() {
|
public void globalAdmin_canUpdateNullRefundBankAccountToNotNullBankAccountForArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null);
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fif");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0);
|
final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0);
|
||||||
|
|
||||||
@ -346,10 +379,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canUpdateRefundBankAccountToNullForArbitraryDebitor() {
|
public void globalAdmin_canUpdateRefundBankAccountToNullForArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fif");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -375,15 +408,15 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void partnerAdmin_canNotUpdateRelatedDebitor() {
|
public void partnerAdmin_canNotUpdateRelatedDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_partner#Fourthe.G.-forthcontact.admin");
|
"hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
assertThatDebitorActuallyInDatabase(givenDebitor);
|
assertThatDebitorActuallyInDatabase(givenDebitor);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#Fourthe.G.-forthcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_partner#10004:Fourthe.G.-forthcontact.admin");
|
||||||
givenDebitor.setVatId("NEW-VAT-ID");
|
givenDebitor.setVatId("NEW-VAT-ID");
|
||||||
return debitorRepo.save(givenDebitor);
|
return debitorRepo.save(givenDebitor);
|
||||||
});
|
});
|
||||||
@ -397,7 +430,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void contactAdmin_canNotUpdateRelatedDebitor() {
|
public void contactAdmin_canNotUpdateRelatedDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth", "nin");
|
||||||
assertThatDebitorIsVisibleForUserWithRole(
|
assertThatDebitorIsVisibleForUserWithRole(
|
||||||
givenDebitor,
|
givenDebitor,
|
||||||
"hs_office_contact#ninthcontact.admin");
|
"hs_office_contact#ninthcontact.admin");
|
||||||
@ -448,7 +481,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_canDeleteAnyDebitor() {
|
public void globalAdmin_canDeleteAnyDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth", "Fourth", "ten");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -468,7 +501,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void relatedPerson_canNotDeleteTheirRelatedDebitor() {
|
public void relatedPerson_canNotDeleteTheirRelatedDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth", "ele");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -494,7 +527,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
||||||
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
||||||
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth", "Fourth");
|
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth", "Fourth", "twe");
|
||||||
assertThat(rawRoleRepo.findAll().size()).as("precondition failed: unexpected number of roles created")
|
assertThat(rawRoleRepo.findAll().size()).as("precondition failed: unexpected number of roles created")
|
||||||
.isEqualTo(initialRoleNames.length + 5);
|
.isEqualTo(initialRoleNames.length + 5);
|
||||||
assertThat(rawGrantRepo.findAll().size()).as("precondition failed: unexpected number of grants created")
|
assertThat(rawGrantRepo.findAll().size()).as("precondition failed: unexpected number of grants created")
|
||||||
@ -536,7 +569,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
private HsOfficeDebitorEntity givenSomeTemporaryDebitor(
|
private HsOfficeDebitorEntity givenSomeTemporaryDebitor(
|
||||||
final String partner,
|
final String partner,
|
||||||
final String contact,
|
final String contact,
|
||||||
final String bankAccount) {
|
final String bankAccount,
|
||||||
|
final String defaultPrefix) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0);
|
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0);
|
||||||
@ -544,10 +578,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenBankAccount =
|
final var givenBankAccount =
|
||||||
bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null;
|
bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null;
|
||||||
final var newDebitor = HsOfficeDebitorEntity.builder()
|
final var newDebitor = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(20000)
|
.debitorNumberSuffix((byte)20)
|
||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.billingContact(givenContact)
|
.billingContact(givenContact)
|
||||||
.refundBankAccount(givenBankAccount)
|
.refundBankAccount(givenBankAccount)
|
||||||
|
.defaultPrefix(defaultPrefix)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return debitorRepo.save(newDebitor);
|
return debitorRepo.save(newDebitor);
|
||||||
@ -558,7 +593,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
@AfterEach
|
@AfterEach
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
em.createQuery("DELETE FROM HsOfficeDebitorEntity d where d.debitorNumber >= 20000").executeUpdate();
|
// TODO em.createQuery("DELETE FROM HsOfficeDebitorEntity d where d.debitorNumberSuffix >= 20").executeUpdate();
|
||||||
|
em.createQuery("DELETE FROM HsOfficeDebitorEntity d where d.debitorNumberSuffix >= 20000").executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void exactlyTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
|
void exactlyTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
|
||||||
|
@ -9,8 +9,10 @@ import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TE
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class TestHsOfficeDebitor {
|
public class TestHsOfficeDebitor {
|
||||||
|
|
||||||
|
public byte DEFAULT_DEBITOR_SUFFIX = 0;
|
||||||
|
|
||||||
public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder()
|
public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder()
|
||||||
.debitorNumber(10001)
|
.debitorNumberSuffix(DEFAULT_DEBITOR_SUFFIX)
|
||||||
.partner(TEST_PARTNER)
|
.partner(TEST_PARTNER)
|
||||||
.billingContact(TEST_CONTACT)
|
.billingContact(TEST_CONTACT)
|
||||||
.build();
|
.build();
|
||||||
|
@ -83,7 +83,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "First GmbH" } },
|
"partner": { "person": { "tradeName": "First GmbH" } },
|
||||||
"mainDebitor": { "debitorNumber": 10001 },
|
"mainDebitor": { "debitorNumber": 1000111 },
|
||||||
"memberNumber": 10001,
|
"memberNumber": 10001,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -91,7 +91,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "Second e.K." } },
|
"partner": { "person": { "tradeName": "Second e.K." } },
|
||||||
"mainDebitor": { "debitorNumber": 10002 },
|
"mainDebitor": { "debitorNumber": 1000212 },
|
||||||
"memberNumber": 10002,
|
"memberNumber": 10002,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -99,7 +99,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "Third OHG" } },
|
"partner": { "person": { "tradeName": "Third OHG" } },
|
||||||
"mainDebitor": { "debitorNumber": 10003 },
|
"mainDebitor": { "debitorNumber": 1000313 },
|
||||||
"memberNumber": 10003,
|
"memberNumber": 10003,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -142,6 +142,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumber()))
|
.body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumber()))
|
||||||
|
// .body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumberSuffix()))
|
||||||
.body("partner.person.tradeName", is("Third OHG"))
|
.body("partner.person.tradeName", is("Third OHG"))
|
||||||
.body("memberNumber", is(20001))
|
.body("memberNumber", is(20001))
|
||||||
.body("validFrom", is("2022-10-13"))
|
.body("validFrom", is("2022-10-13"))
|
||||||
@ -182,7 +183,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "First GmbH" } },
|
"partner": { "person": { "tradeName": "First GmbH" } },
|
||||||
"mainDebitor": { "debitorNumber": 10001 },
|
"mainDebitor": { "debitorNumber": 1000111 },
|
||||||
"memberNumber": 10001,
|
"memberNumber": 10001,
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
@ -224,7 +225,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.header("assumed-roles", "hs_office_debitor#10003ThirdOHG-thirdcontact.agent")
|
.header("assumed-roles", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.agent")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
||||||
@ -235,7 +236,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
{
|
{
|
||||||
"partner": { "person": { "tradeName": "Third OHG" } },
|
"partner": { "person": { "tradeName": "Third OHG" } },
|
||||||
"mainDebitor": {
|
"mainDebitor": {
|
||||||
"debitorNumber": 10003,
|
"debitorNumber": 1000313,
|
||||||
"billingContact": { "label": "third contact" }
|
"billingContact": { "label": "third contact" }
|
||||||
},
|
},
|
||||||
"memberNumber": 10003,
|
"memberNumber": 10003,
|
||||||
@ -276,6 +277,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
||||||
.body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber()))
|
.body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber()))
|
||||||
|
// .body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumberSuffix()))
|
||||||
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
||||||
.body("validFrom", is("2022-11-01"))
|
.body("validFrom", is("2022-11-01"))
|
||||||
.body("validTo", is("2023-12-31"))
|
.body("validTo", is("2023-12-31"))
|
||||||
@ -299,7 +301,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
||||||
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(10003).get(0);
|
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(1000313).get(0);
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -318,7 +320,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName()))
|
||||||
.body("mainDebitor.debitorNumber", is(10003))
|
.body("mainDebitor.debitorNumber", is(1000313))
|
||||||
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
.body("memberNumber", is(givenMembership.getMemberNumber()))
|
||||||
.body("validFrom", is("2022-11-01"))
|
.body("validFrom", is("2022-11-01"))
|
||||||
.body("validTo", nullValue())
|
.body("validTo", nullValue())
|
||||||
@ -340,13 +342,13 @@ class HsOfficeMembershipControllerAcceptanceTest {
|
|||||||
@Test
|
@Test
|
||||||
void partnerAgent_canViewButNotPatchValidityOfRelatedMembership() {
|
void partnerAgent_canViewButNotPatchValidityOfRelatedMembership() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net", "hs_office_partner#FirstGmbH-firstcontact.agent");
|
context.define("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.agent");
|
||||||
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
final var givenMembership = givenSomeTemporaryMembershipBessler();
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.header("assumed-roles", "hs_office_partner#FirstGmbH-firstcontact.agent")
|
.header("assumed-roles", "hs_office_partner#10001:FirstGmbH-firstcontact.agent")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,8 @@ class HsOfficeMembershipEntityUnitTest {
|
|||||||
void toStringContainsAllProps() {
|
void toStringContainsAllProps() {
|
||||||
final var result = givenMembership.toString();
|
final var result = givenMembership.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("Membership(10001, Test Ltd., 10001, [2020-01-01,))");
|
assertThat(result).isEqualTo("Membership(10001, Test Ltd., 1000100, [2020-01-01,))");
|
||||||
|
// assertThat(result).isEqualTo("Membership(10001, Test Ltd., 1000100, [2020-01-01,))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -119,11 +119,11 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var all = rawRoleRepo.findAll();
|
final var all = rawRoleRepo.findAll();
|
||||||
assertThat(roleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.admin",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.admin",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.agent",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.agent",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.guest",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.guest",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.owner",
|
"hs_office_membership#20002:FirstGmbH-firstcontact.owner",
|
||||||
"hs_office_membership#20002FirstGmbH-firstcontact.tenant"));
|
"hs_office_membership#20002:FirstGmbH-firstcontact.tenant"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("GmbH-firstcontact", ""))
|
.map(s -> s.replace("GmbH-firstcontact", ""))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
@ -131,32 +131,36 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on membership#20002First to role membership#20002First.owner by system and assume }",
|
"{ grant perm * on membership#20002:First to role membership#20002:First.owner by system and assume }",
|
||||||
"{ grant role membership#20002First.owner to role global#global.admin by system and assume }",
|
"{ grant role membership#20002:First.owner to role global#global.admin by system and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on membership#20002First to role membership#20002First.admin by system and assume }",
|
"{ grant perm edit on membership#20002:First to role membership#20002:First.admin by system and assume }",
|
||||||
"{ grant role membership#20002First.admin to role membership#20002First.owner by system and assume }",
|
"{ grant role membership#20002:First.admin to role membership#20002:First.owner by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role membership#20002First.agent to role membership#20002First.admin by system and assume }",
|
"{ grant role membership#20002:First.agent to role membership#20002:First.admin by system and assume }",
|
||||||
"{ grant role partner#First.tenant to role membership#20002First.agent by system and assume }",
|
"{ grant role partner#10001:First.tenant to role membership#20002:First.agent by system and assume }",
|
||||||
"{ grant role membership#20002First.agent to role debitor#10001First.admin by system and assume }",
|
"{ grant role membership#20002:First.agent to role debitor#1000111:First.admin by system and assume }",
|
||||||
"{ grant role membership#20002First.agent to role partner#First.admin by system and assume }",
|
"{ grant role membership#20002:First.agent to role partner#10001:First.admin by system and assume }",
|
||||||
"{ grant role debitor#10001First.tenant to role membership#20002First.agent by system and assume }",
|
"{ grant role debitor#1000111:First.tenant to role membership#20002:First.agent by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role membership#20002First.tenant to role membership#20002First.agent by system and assume }",
|
"{ grant role membership#20002:First.tenant to role membership#20002:First.agent by system and assume }",
|
||||||
"{ grant role partner#First.guest to role membership#20002First.tenant by system and assume }",
|
"{ grant role partner#10001:First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
"{ grant role debitor#10001First.guest to role membership#20002First.tenant by system and assume }",
|
// "{ grant role debitor#1100First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
"{ grant role membership#20002First.tenant to role debitor#10001First.agent by system and assume }",
|
// "{ grant role membership#20002:First.tenant to role debitor#1100First.agent by system and assume }",
|
||||||
"{ grant role membership#20002First.tenant to role partner#First.agent by system and assume }",
|
"{ grant role debitor#1000111:First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
|
"{ grant role membership#20002:First.tenant to role debitor#1000111:First.agent by system and assume }",
|
||||||
|
|
||||||
|
"{ grant role membership#20002:First.tenant to role partner#10001:First.agent by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on membership#20002First to role membership#20002First.guest by system and assume }",
|
"{ grant perm view on membership#20002:First to role membership#20002:First.guest by system and assume }",
|
||||||
"{ grant role membership#20002First.guest to role membership#20002First.tenant by system and assume }",
|
"{ grant role membership#20002:First.guest to role membership#20002:First.tenant by system and assume }",
|
||||||
"{ grant role membership#20002First.guest to role partner#First.tenant by system and assume }",
|
"{ grant role membership#20002:First.guest to role partner#10001:First.tenant by system and assume }",
|
||||||
"{ grant role membership#20002First.guest to role debitor#10001First.tenant by system and assume }",
|
// "{ grant role membership#20002:First.guest to role debitor#1100First.tenant by system and assume }",
|
||||||
|
"{ grant role membership#20002:First.guest to role debitor#1000111:First.tenant by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -181,9 +185,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(
|
exactlyTheseMembershipsAreReturned(
|
||||||
result,
|
result,
|
||||||
"Membership(10001, First GmbH, 10001, [2022-10-01,), NONE)",
|
"Membership(10001, First GmbH, 1000111, [2022-10-01,), NONE)",
|
||||||
"Membership(10002, Second e.K., 10002, [2022-10-01,), NONE)",
|
"Membership(10002, Second e.K., 1000212, [2022-10-01,), NONE)",
|
||||||
"Membership(10003, Third OHG, 10003, [2022-10-01,), NONE)");
|
"Membership(10003, Third OHG, 1000313, [2022-10-01,), NONE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -198,7 +202,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
null);
|
null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(result, "Membership(10001, First GmbH, 10001, [2022-10-01,), NONE)");
|
exactlyTheseMembershipsAreReturned(result, "Membership(10001, First GmbH, 1000111, [2022-10-01,), NONE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -210,7 +214,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002);
|
final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(result, "Membership(10002, Second e.K., 10002, [2022-10-01,), NONE)");
|
exactlyTheseMembershipsAreReturned(result, "Membership(10002, Second e.K., 1000212, [2022-10-01,), NONE)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +228,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
||||||
assertThatMembershipIsVisibleForUserWithRole(
|
assertThatMembershipIsVisibleForUserWithRole(
|
||||||
givenMembership,
|
givenMembership,
|
||||||
"hs_office_debitor#10001FirstGmbH-firstcontact.admin");
|
"hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
|
||||||
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
||||||
final var newValidityEnd = LocalDate.now();
|
final var newValidityEnd = LocalDate.now();
|
||||||
|
|
||||||
@ -251,13 +255,13 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
final var givenMembership = givenSomeTemporaryMembership("First", "First");
|
||||||
assertThatMembershipIsVisibleForUserWithRole(
|
assertThatMembershipIsVisibleForUserWithRole(
|
||||||
givenMembership,
|
givenMembership,
|
||||||
"hs_office_debitor#10001FirstGmbH-firstcontact.admin");
|
"hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
|
||||||
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
||||||
final var newValidityEnd = LocalDate.now();
|
final var newValidityEnd = LocalDate.now();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_debitor#10001FirstGmbH-firstcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_debitor#1000111:FirstGmbH-firstcontact.admin");
|
||||||
givenMembership.setValidity(Range.closedOpen(
|
givenMembership.setValidity(Range.closedOpen(
|
||||||
givenMembership.getValidity().lower(), newValidityEnd));
|
givenMembership.getValidity().lower(), newValidityEnd));
|
||||||
return membershipRepo.save(givenMembership);
|
return membershipRepo.save(givenMembership);
|
||||||
@ -325,7 +329,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_debitor#10003ThirdOHG-thirdcontact.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.admin");
|
||||||
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
|
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
|
||||||
|
|
||||||
membershipRepo.deleteByUuid(givenMembership.getUuid());
|
membershipRepo.deleteByUuid(givenMembership.getUuid());
|
||||||
@ -382,8 +386,8 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
||||||
"[creating Membership test-data FirstGmbH10001, hs_office_membership, INSERT]",
|
"[creating Membership test-data FirstGmbH11, hs_office_membership, INSERT]",
|
||||||
"[creating Membership test-data Seconde.K.10002, hs_office_membership, INSERT]");
|
"[creating Membership test-data Seconde.K.12, hs_office_membership, INSERT]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -7,6 +7,10 @@ import net.hostsharing.hsadminng.context.Context;
|
|||||||
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.coopshares.HsOfficeCoopSharesTransactionEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.coopshares.HsOfficeCoopSharesTransactionType;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
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.HsOfficeReasonForTermination;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeReasonForTermination;
|
||||||
@ -15,23 +19,14 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||||
import net.hostsharing.hsadminng.repository.HasUuid;
|
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.*;
|
||||||
import org.junit.jupiter.api.Order;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
|
||||||
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.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.test.annotation.Commit;
|
import org.springframework.test.annotation.Commit;
|
||||||
import org.springframework.test.annotation.Rollback;
|
|
||||||
import org.springframework.transaction.TransactionStatus;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
import org.springframework.util.ReflectionUtils;
|
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
@ -40,12 +35,11 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||||
@ -57,23 +51,26 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* This 'test' includes the complete legacy 'office' data import.
|
* This 'test' includes the complete legacy 'office' data import.
|
||||||
*
|
*
|
||||||
* There is no code in 'main' because the import is not needed a normal runtime.
|
* There is no code in 'main' because the import is not needed a normal runtime.
|
||||||
* There is some test data in Java resources to verfiy the data conversion.
|
* There is some test data in Java resources to verify the data conversion.
|
||||||
* For a real import a main method will be added later
|
* For a real import a main method will be added later
|
||||||
* which reads CSV files from the file system.
|
* which reads CSV files from the file system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Disabled
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@Import({ Context.class, JpaAttempt.class })
|
@Import({ Context.class, JpaAttempt.class })
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
public class ImportOfficeTables extends ContextBasedTest {
|
public class ImportOfficeTables extends ContextBasedTest {
|
||||||
|
|
||||||
private static Map<Integer, HsOfficeContactEntity> contacts = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficeContactEntity> contacts = new TreeMap<>();
|
||||||
private static Map<Integer, HsOfficePersonEntity> persons = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficePersonEntity> persons = new TreeMap<>();
|
||||||
private static Map<Integer, HsOfficePartnerEntity> partners = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficePartnerEntity> partners = new TreeMap<>();
|
||||||
private static Map<Integer, HsOfficeDebitorEntity> debitors = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficeDebitorEntity> debitors = new TreeMap<>();
|
||||||
private static Map<Integer, HsOfficeMembershipEntity> memberships = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficeMembershipEntity> memberships = new TreeMap<>();
|
||||||
private static Map<Integer, HsOfficeSepaMandateEntity> sepaMandates = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficeSepaMandateEntity> sepaMandates = new TreeMap<>();
|
||||||
private static Map<Integer, HsOfficeBankAccountEntity> bankAccounts = new HashMap<>();
|
private static NavigableMap<Integer, HsOfficeBankAccountEntity> bankAccounts = new TreeMap<>();
|
||||||
|
private static NavigableMap<Integer, HsOfficeCoopSharesTransactionEntity> coopShares = new TreeMap<>();
|
||||||
|
private static NavigableMap<Integer, HsOfficeCoopAssetsTransactionEntity> coopAssets = new TreeMap<>();
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
@ -142,9 +139,9 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
""");
|
""");
|
||||||
assertThat(contacts.toString()).isEqualToIgnoringWhitespace("""
|
assertThat(contacts.toString()).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
|
71=contact(label='Herr Michael Mellies ', emailAddresses='mih@example.org'),
|
||||||
101=contact(label='Frau Dr. Jenny Meyer , JM e.K.', emailAddresses='jm@example.org'),
|
101=contact(label='Frau Dr. Jenny Meyer , JM e.K.', emailAddresses='jm@example.org'),
|
||||||
102=contact(label='Herr Andrew Meyer , JM e.K.', emailAddresses='am@example.org'),
|
102=contact(label='Herr Andrew Meyer , JM e.K.', emailAddresses='am@example.org'),
|
||||||
71=contact(label='Herr Michael Mellies ', emailAddresses='mih@example.org'),
|
|
||||||
121=contact(label='Paule Schmidt , Test PS', emailAddresses='ps@example.com')
|
121=contact(label='Paule Schmidt , Test PS', emailAddresses='ps@example.com')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -196,6 +193,52 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
void importCoopShares() {
|
||||||
|
|
||||||
|
try (Reader reader = resourceReader("migration/share-transactions.csv")) {
|
||||||
|
final var lines = readAllLines(reader);
|
||||||
|
importCoopShares(justHeader(lines), withoutHeader(lines));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(coopShares.toString()).isEqualToIgnoringWhitespace("""
|
||||||
|
{
|
||||||
|
33443=CoopShareTransaction(10007, 2000-12-06, SUBSCRIPTION, 20, initial share subscription),
|
||||||
|
33451=CoopShareTransaction(10010, 2000-12-06, SUBSCRIPTION, 2, initial share subscription),
|
||||||
|
33701=CoopShareTransaction(10007, 2005-01-10, SUBSCRIPTION, 40, increase),
|
||||||
|
33810=CoopShareTransaction(10010, 2016-12-31, CANCELLATION, 22, membership ended)
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
void importCoopAssets() {
|
||||||
|
|
||||||
|
try (Reader reader = resourceReader("migration/asset-transactions.csv")) {
|
||||||
|
final var lines = readAllLines(reader);
|
||||||
|
importCoopAssets(justHeader(lines), withoutHeader(lines));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(coopAssets.toString()).isEqualToIgnoringWhitespace("""
|
||||||
|
{
|
||||||
|
30000=CoopAssetsTransaction(10007, 2000-12-06, DEPOSIT, 1280.00, for subscription A),
|
||||||
|
31000=CoopAssetsTransaction(10010, 2000-12-06, DEPOSIT, 128.00, for subscription B),
|
||||||
|
32000=CoopAssetsTransaction(10007, 2005-01-10, DEPOSIT, 2560.00, for subscription C),
|
||||||
|
33001=CoopAssetsTransaction(10007, 2005-01-10, TRANSFER, -512.00, for transfer to 10),
|
||||||
|
33002=CoopAssetsTransaction(10010, 2005-01-10, ADOPTION, 512.00, for transfer from 7),
|
||||||
|
34001=CoopAssetsTransaction(10010, 2016-12-31, CLEARING, -8.00, for cancellation D),
|
||||||
|
34002=CoopAssetsTransaction(10010, 2016-12-31, DISBURSAL, -100.00, for cancellation D),
|
||||||
|
34003=CoopAssetsTransaction(10010, 2016-12-31, LOSS, -20.00, for cancellation D)
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(10)
|
@Order(10)
|
||||||
@Commit
|
@Commit
|
||||||
@ -219,7 +262,11 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
sepaMandates.forEach((id, mandate) -> em.persist(mandate));
|
sepaMandates.forEach((id, mandate) -> em.persist(mandate));
|
||||||
updateLegacyIds(sepaMandates, "hs_office_sepamandate_legacy_id", "sepa_mandate_id");
|
updateLegacyIds(sepaMandates, "hs_office_sepamandate_legacy_id", "sepa_mandate_id");
|
||||||
|
|
||||||
// TODO: coopshares+coopassets
|
coopShares.forEach((id, shareTransaction) -> em.persist(shareTransaction));
|
||||||
|
updateLegacyIds(coopShares, "hs_office_coopsharestransaction_legacy_id", "member_share_id");
|
||||||
|
|
||||||
|
coopAssets.forEach((id, assetTransaction) -> em.persist(assetTransaction));
|
||||||
|
updateLegacyIds(coopShares, "hs_office_coopassetstransaction_legacy_id", "member_asset_id");
|
||||||
|
|
||||||
em.flush();
|
em.flush();
|
||||||
}
|
}
|
||||||
@ -263,49 +310,117 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
final var person = HsOfficePersonEntity.builder()
|
final var person = HsOfficePersonEntity.builder()
|
||||||
.personType(HsOfficePersonType.UNKNOWN) // TODO
|
.personType(HsOfficePersonType.UNKNOWN) // TODO
|
||||||
.build();
|
.build();
|
||||||
persons.put(toInt(rec.get("bp_id")), person);
|
persons.put(rec.getInteger("bp_id"), person);
|
||||||
|
|
||||||
final var partner = HsOfficePartnerEntity.builder()
|
final var partner = HsOfficePartnerEntity.builder()
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
.contact(HsOfficeContactEntity.builder().build())
|
.contact(HsOfficeContactEntity.builder().build())
|
||||||
.person(person)
|
.person(person)
|
||||||
.build();
|
.build();
|
||||||
partners.put(toInt(rec.get("bp_id")), partner);
|
partners.put(rec.getInteger("bp_id"), partner);
|
||||||
|
|
||||||
final var debitor = HsOfficeDebitorEntity.builder()
|
final var debitor = HsOfficeDebitorEntity.builder()
|
||||||
.partner(partner)
|
.partner(partner)
|
||||||
.debitorNumber(toInt(rec.get("member_id")))
|
// .debitorNumberSuffix(rec.getByte("member_id"))
|
||||||
// .memberCode(rec.get("member_code")) TODO
|
// .defaultPrefix(rec.getString("member_code"))
|
||||||
.partner(partner)
|
.partner(partner)
|
||||||
.billingContact(partner.getContact())
|
.billingContact(partner.getContact())
|
||||||
// .memberRoles(toBool(rec.get("member_role")) TODO
|
.billable(rec.isEmpty("free"))
|
||||||
// .authorContract(toBool(rec.get("author_contract")) TODO
|
// .vatExempt(toBool(rec.get("exempt_vat")) (reverse-charge) TODO: add as vat-reverse-charge to debitor
|
||||||
// .nonDisclosureContract(toBool(rec.get("nondisc_contract")) TODO
|
.vatBusiness("GROSS".equals(rec.getString("indicator_vat"))) // TODO: remove
|
||||||
// .free(toBool(rec.get("free")) TODO
|
.vatId(rec.getString("uid_vat"))
|
||||||
// .vatExempt(toBool(rec.get("exempt_vat")) TODO
|
|
||||||
.vatBusiness("GROSS".equals(rec.get("indicator_vat")))
|
|
||||||
.vatId(rec.get("uid_vat"))
|
|
||||||
.build();
|
.build();
|
||||||
debitors.put(toInt(rec.get("bp_id")), debitor);
|
debitors.put(rec.getInteger("bp_id"), debitor);
|
||||||
|
|
||||||
partners.put(toInt(rec.get("bp_id")), partner);
|
partners.put(rec.getInteger("bp_id"), partner);
|
||||||
|
|
||||||
if (isNotBlank(rec.get("member_since"))) {
|
if (isNotBlank(rec.getString("member_since"))) {
|
||||||
final var membership = HsOfficeMembershipEntity.builder()
|
final var membership = HsOfficeMembershipEntity.builder()
|
||||||
.partner(partner)
|
.partner(partner)
|
||||||
.memberNumber(toInt(rec.get("member_id")))
|
.memberNumber(rec.getInteger("member_id"))
|
||||||
.validity(toPostgresDateRange(localDate(rec.get("member_since")), localDate(rec.get("member_until"))))
|
.validity(toPostgresDateRange(rec.getLocalDate("member_since"), rec.getLocalDate("member_until")))
|
||||||
|
.membershipFeeBillable(rec.isEmpty("member_role"))
|
||||||
.reasonForTermination(
|
.reasonForTermination(
|
||||||
isBlank(rec.get("member_until"))
|
isBlank(rec.getString("member_until"))
|
||||||
? HsOfficeReasonForTermination.NONE
|
? HsOfficeReasonForTermination.NONE
|
||||||
: HsOfficeReasonForTermination.UNKNOWN) // TODO
|
: HsOfficeReasonForTermination.UNKNOWN)
|
||||||
.mainDebitor(debitor)
|
.mainDebitor(debitor)
|
||||||
.build();
|
.build();
|
||||||
memberships.put(toInt(rec.get("bp_id")), membership);
|
memberships.put(rec.getInteger("bp_id"), membership);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void importCoopShares(final String[] header, final List<String[]> records) {
|
||||||
|
|
||||||
|
final var columns = new Columns(header);
|
||||||
|
|
||||||
|
records.stream()
|
||||||
|
.map(this::trimAll)
|
||||||
|
.map(row -> new Record(columns, row))
|
||||||
|
.forEach(rec -> {
|
||||||
|
final var member = memberships.get(rec.getInteger("bp_id"));
|
||||||
|
|
||||||
|
final var shareTransaction = HsOfficeCoopSharesTransactionEntity.builder()
|
||||||
|
.membership(member)
|
||||||
|
.valueDate(rec.getLocalDate("date"))
|
||||||
|
.transactionType(
|
||||||
|
"SUBSCRIPTION".equals(rec.getString("action"))
|
||||||
|
? HsOfficeCoopSharesTransactionType.SUBSCRIPTION
|
||||||
|
: "UNSUBSCRIPTION".equals(rec.getString("action"))
|
||||||
|
? HsOfficeCoopSharesTransactionType.CANCELLATION
|
||||||
|
: HsOfficeCoopSharesTransactionType.ADJUSTMENT
|
||||||
|
)
|
||||||
|
.shareCount(rec.getInteger("quantity"))
|
||||||
|
.reference(rec.getString("comment"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
coopShares.put(rec.getInteger("member_share_id"), shareTransaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void importCoopAssets(final String[] header, final List<String[]> records) {
|
||||||
|
|
||||||
|
final var columns = new Columns(header);
|
||||||
|
|
||||||
|
records.stream()
|
||||||
|
.map(this::trimAll)
|
||||||
|
.map(row -> new Record(columns, row))
|
||||||
|
.forEach(rec -> {
|
||||||
|
final var member = memberships.get(rec.getInteger("bp_id"));
|
||||||
|
|
||||||
|
final var assetTypeMapping = new HashMap<String, HsOfficeCoopAssetsTransactionType>() {
|
||||||
|
{
|
||||||
|
put("HANDOVER", HsOfficeCoopAssetsTransactionType.TRANSFER);
|
||||||
|
put("ADOPTION", HsOfficeCoopAssetsTransactionType.ADOPTION);
|
||||||
|
put("LOSS", HsOfficeCoopAssetsTransactionType.LOSS);
|
||||||
|
put("CLEARING", HsOfficeCoopAssetsTransactionType.CLEARING);
|
||||||
|
put("PRESCRIPTION", HsOfficeCoopAssetsTransactionType.LIMITATION);
|
||||||
|
put("PAYBACK", HsOfficeCoopAssetsTransactionType.DISBURSAL);
|
||||||
|
put("PAYMENT", HsOfficeCoopAssetsTransactionType.DEPOSIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HsOfficeCoopAssetsTransactionType get(final String key) {
|
||||||
|
final var value = super.get(key);
|
||||||
|
if ( value != null ) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("no mapping value found for: " + key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final var assetTransaction = HsOfficeCoopAssetsTransactionEntity.builder()
|
||||||
|
.membership(member)
|
||||||
|
.valueDate(rec.getLocalDate("date"))
|
||||||
|
.transactionType(assetTypeMapping.get(rec.getString("action")))
|
||||||
|
.assetValue(rec.getBigDecimal("amount"))
|
||||||
|
.reference(rec.getString("comment"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
coopAssets.put(rec.getInteger("member_asset_id"), assetTransaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void importSepaMandates(final String[] header, final List<String[]> records) {
|
private void importSepaMandates(final String[] header, final List<String[]> records) {
|
||||||
|
|
||||||
final var columns = new Columns(header);
|
final var columns = new Columns(header);
|
||||||
@ -314,25 +429,25 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
.map(this::trimAll)
|
.map(this::trimAll)
|
||||||
.map(row -> new Record(columns, row))
|
.map(row -> new Record(columns, row))
|
||||||
.forEach(rec -> {
|
.forEach(rec -> {
|
||||||
final var debitor = debitors.get(toInt(rec.get("bp_id")));
|
final var debitor = debitors.get(rec.getInteger("bp_id"));
|
||||||
|
|
||||||
final var sepaMandate = HsOfficeSepaMandateEntity.builder()
|
final var sepaMandate = HsOfficeSepaMandateEntity.builder()
|
||||||
.debitor(debitor)
|
.debitor(debitor)
|
||||||
.bankAccount(HsOfficeBankAccountEntity.builder()
|
.bankAccount(HsOfficeBankAccountEntity.builder()
|
||||||
.holder(rec.get("bank_customer"))
|
.holder(rec.getString("bank_customer"))
|
||||||
// .bankName(rec.get("bank_name")) // TODO
|
// .bankName(rec.get("bank_name")) // not supported
|
||||||
.iban(rec.get("bank_iban"))
|
.iban(rec.getString("bank_iban"))
|
||||||
.bic(rec.get("bank_bic"))
|
.bic(rec.getString("bank_bic"))
|
||||||
.build())
|
.build())
|
||||||
.reference(rec.get("mandat_ref"))
|
.reference(rec.getString("mandat_ref"))
|
||||||
.agreement(LocalDate.parse(rec.get("mandat_signed")))
|
.agreement(LocalDate.parse(rec.getString("mandat_signed")))
|
||||||
.validity(toPostgresDateRange(
|
.validity(toPostgresDateRange(
|
||||||
toLocalDate(rec.get("mandat_since")),
|
rec.getLocalDate("mandat_since"),
|
||||||
toLocalDate(rec.get("mandat_until"))))
|
rec.getLocalDate("mandat_until")))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
sepaMandates.put(toInt(rec.get("sepa_mandat_id")), sepaMandate);
|
sepaMandates.put(rec.getInteger("sepa_mandat_id"), sepaMandate);
|
||||||
bankAccounts.put(toInt(rec.get("sepa_mandat_id")), sepaMandate.getBankAccount());
|
bankAccounts.put(rec.getInteger("sepa_mandat_id"), sepaMandate.getBankAccount());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,15 +459,15 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
.map(this::trimAll)
|
.map(this::trimAll)
|
||||||
.map(row -> new Record(columns, row))
|
.map(row -> new Record(columns, row))
|
||||||
.forEach(rec -> {
|
.forEach(rec -> {
|
||||||
if (isNotBlank(rec.get("roles")) && rec.get("roles").contains("billing")) {
|
if (isNotBlank(rec.getString("roles")) && rec.getString("roles").contains("billing")) {
|
||||||
|
|
||||||
final var partner = partners.get(toInt(rec.get("bp_id")));
|
final var partner = partners.get(rec.getInteger("bp_id"));
|
||||||
|
|
||||||
final var person = partner.getPerson();
|
final var person = partner.getPerson();
|
||||||
person.setTradeName(rec.get("firma"));
|
person.setTradeName(rec.getString("firma"));
|
||||||
// TODO: title+salutation
|
// TODO: title+salutation: add to person
|
||||||
person.setGivenName(rec.get("first_name"));
|
person.setGivenName(rec.getString("first_name"));
|
||||||
person.setFamilyName(rec.get("last_name"));
|
person.setFamilyName(rec.getString("last_name"));
|
||||||
|
|
||||||
initContact(partner.getContact(), rec);
|
initContact(partner.getContact(), rec);
|
||||||
|
|
||||||
@ -364,10 +479,10 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initContact(final HsOfficeContactEntity contact, final Record rec) {
|
private void initContact(final HsOfficeContactEntity contact, final Record rec) {
|
||||||
contacts.put(toInt(rec.get("contact_id")), contact);
|
contacts.put(rec.getInteger("contact_id"), contact);
|
||||||
|
|
||||||
contact.setLabel(toLabel(rec.get("salut"), rec.get("title"), rec.get("first_name"), rec.get("last_name"), rec.get("firma")));
|
contact.setLabel(toLabel(rec.getString("salut"), rec.getString("title"), rec.getString("first_name"), rec.getString("last_name"), rec.getString("firma")));
|
||||||
contact.setEmailAddresses(rec.get("email"));
|
contact.setEmailAddresses(rec.getString("email"));
|
||||||
contact.setPostalAddress(toAddress(rec));
|
contact.setPostalAddress(toAddress(rec));
|
||||||
contact.setPhoneNumbers(toPhoneNumbers(rec));
|
contact.setPhoneNumbers(toPhoneNumbers(rec));
|
||||||
}
|
}
|
||||||
@ -382,28 +497,28 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
}
|
}
|
||||||
private String toPhoneNumbers(final Record rec) {
|
private String toPhoneNumbers(final Record rec) {
|
||||||
final var result = new StringBuilder("{\n");
|
final var result = new StringBuilder("{\n");
|
||||||
if (isNotBlank(rec.get("phone_private")))
|
if (isNotBlank(rec.getString("phone_private")))
|
||||||
result.append(" \"private\": " + "\"" + rec.get("phone_private") + "\",\n");
|
result.append(" \"private\": " + "\"" + rec.getString("phone_private") + "\",\n");
|
||||||
if (isNotBlank(rec.get("phone_office")))
|
if (isNotBlank(rec.getString("phone_office")))
|
||||||
result.append(" \"office\": " + "\"" + rec.get("phone_office") + "\",\n");
|
result.append(" \"office\": " + "\"" + rec.getString("phone_office") + "\",\n");
|
||||||
if (isNotBlank(rec.get("phone_mobile")))
|
if (isNotBlank(rec.getString("phone_mobile")))
|
||||||
result.append(" \"mobile\": " + "\"" + rec.get("phone_mobile") + "\",\n");
|
result.append(" \"mobile\": " + "\"" + rec.getString("phone_mobile") + "\",\n");
|
||||||
if (isNotBlank(rec.get("fax")))
|
if (isNotBlank(rec.getString("fax")))
|
||||||
result.append(" \"fax\": " + "\"" + rec.get("fax") + "\",\n");
|
result.append(" \"fax\": " + "\"" + rec.getString("fax") + "\",\n");
|
||||||
return (result + "}").replace("\",\n}", "\"\n}");
|
return (result + "}").replace("\",\n}", "\"\n}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toAddress(final Record rec) {
|
private String toAddress(final Record rec) {
|
||||||
final var result = new StringBuilder();
|
final var result = new StringBuilder();
|
||||||
final var name = toName(rec.get("salut"), rec.get("title"), rec.get("first_name"), rec.get("last_name"));
|
final var name = toName(rec.getString("salut"), rec.getString("title"), rec.getString("first_name"), rec.getString("last_name"));
|
||||||
if (isNotBlank(name))
|
if (isNotBlank(name))
|
||||||
result.append(name + "\n");
|
result.append(name + "\n");
|
||||||
if (isNotBlank(rec.get("firma")))
|
if (isNotBlank(rec.getString("firma")))
|
||||||
result.append(rec.get("firma") + "\n");
|
result.append(rec.getString("firma") + "\n");
|
||||||
if (isNotBlank(rec.get("co")))
|
if (isNotBlank(rec.getString("co")))
|
||||||
result.append("c/o " + rec.get("co") + "\n");
|
result.append("c/o " + rec.getString("co") + "\n");
|
||||||
if (isNotBlank(rec.get("street")))
|
if (isNotBlank(rec.getString("street")))
|
||||||
result.append(rec.get("street") + "\n");
|
result.append(rec.getString("street") + "\n");
|
||||||
final var zipcodeAndCity = toZipcodeAndCity(rec);
|
final var zipcodeAndCity = toZipcodeAndCity(rec);
|
||||||
if (isNotBlank(zipcodeAndCity))
|
if (isNotBlank(zipcodeAndCity))
|
||||||
result.append(zipcodeAndCity + "\n");
|
result.append(zipcodeAndCity + "\n");
|
||||||
@ -412,12 +527,12 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
|
|
||||||
private String toZipcodeAndCity(final Record rec) {
|
private String toZipcodeAndCity(final Record rec) {
|
||||||
final var result = new StringBuilder();
|
final var result = new StringBuilder();
|
||||||
if (isNotBlank(rec.get("country")))
|
if (isNotBlank(rec.getString("country")))
|
||||||
result.append(rec.get("country") + " ");
|
result.append(rec.getString("country") + " ");
|
||||||
if (isNotBlank(rec.get("zipcode")))
|
if (isNotBlank(rec.getString("zipcode")))
|
||||||
result.append(rec.get("zipcode") + " ");
|
result.append(rec.getString("zipcode") + " ");
|
||||||
if (isNotBlank(rec.get("city")))
|
if (isNotBlank(rec.getString("city")))
|
||||||
result.append(rec.get("city"));
|
result.append(rec.getString("city"));
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,23 +561,6 @@ public class ImportOfficeTables extends ContextBasedTest {
|
|||||||
return toLabel(salut, title, firstname, lastname, null);
|
return toLabel(salut, title, firstname, lastname, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate toLocalDate(final String dateString) {
|
|
||||||
if (isNotBlank(dateString)) {
|
|
||||||
return LocalDate.parse(dateString);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Integer toInt(final String value) {
|
|
||||||
return isNotBlank(value) ? Integer.parseInt(value.trim()) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocalDate localDate(final String dateStringNullOrBlank) {
|
|
||||||
if (isNotBlank(dateStringNullOrBlank)) {
|
|
||||||
return LocalDate.parse(dateStringNullOrBlank);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Reader resourceReader(@NotNull final String resourcePath) {
|
private Reader resourceReader(@NotNull final String resourcePath) {
|
||||||
return new InputStreamReader(getClass().getClassLoader().getResourceAsStream(resourcePath));
|
return new InputStreamReader(getClass().getClassLoader().getResourceAsStream(resourcePath));
|
||||||
@ -512,7 +610,38 @@ class Record {
|
|||||||
this.row = row;
|
this.row = row;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get(final String columnName) {
|
String getString(final String columnName) {
|
||||||
return row[columns.indexOf(columnName)];
|
return row[columns.indexOf(columnName)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isEmpty(final String columnName) {
|
||||||
|
final String value = getString(columnName);
|
||||||
|
return value == null || value.isBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte getByte(final String columnName) {
|
||||||
|
final String value = getString(columnName);
|
||||||
|
return isNotBlank(value) ? Byte.valueOf(value.trim()) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getInteger(final String columnName) {
|
||||||
|
final String value = getString(columnName);
|
||||||
|
return isNotBlank(value) ? Integer.valueOf(value.trim()) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal getBigDecimal(final String columnName) {
|
||||||
|
final String value = getString(columnName);
|
||||||
|
if (isNotBlank(value)) {
|
||||||
|
return new BigDecimal(value);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate getLocalDate(final String columnName) {
|
||||||
|
final String dateString = getString(columnName);
|
||||||
|
if (isNotBlank(dateString)) {
|
||||||
|
return LocalDate.parse(dateString);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||||
final var newPartner = toCleanup(HsOfficePartnerEntity.builder()
|
final var newPartner = toCleanup(HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(22222)
|
||||||
.person(givenPerson)
|
.person(givenPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
@ -115,11 +116,11 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.admin",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.admin",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.agent",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.agent",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.owner",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.owner",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.tenant",
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.tenant",
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-forthcontact.guest"));
|
"hs_office_partner#22222:ErbenBesslerMelBessler-forthcontact.guest"));
|
||||||
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(grantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("ErbenBesslerMelBessler", "EBess"))
|
.map(s -> s.replace("ErbenBesslerMelBessler", "EBess"))
|
||||||
.map(s -> s.replace("forthcontact", "4th"))
|
.map(s -> s.replace("forthcontact", "4th"))
|
||||||
@ -127,31 +128,31 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on partner#EBess-4th to role partner#EBess-4th.owner by system and assume }",
|
"{ grant perm * on partner#22222:EBess-4th to role partner#22222:EBess-4th.owner by system and assume }",
|
||||||
"{ grant perm * on partner_details#EBess-4th-details to role partner#EBess-4th.owner by system and assume }",
|
"{ grant perm * on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.owner by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.owner to role global#global.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.owner to role global#global.admin by system and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on partner#EBess-4th to role partner#EBess-4th.admin by system and assume }",
|
"{ grant perm edit on partner#22222:EBess-4th to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant perm edit on partner_details#EBess-4th-details to role partner#EBess-4th.admin by system and assume }",
|
"{ grant perm edit on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.admin to role partner#EBess-4th.owner by system and assume }",
|
"{ grant role partner#22222:EBess-4th.admin to role partner#22222:EBess-4th.owner by system and assume }",
|
||||||
"{ grant role person#EBess.tenant to role partner#EBess-4th.admin by system and assume }",
|
"{ grant role person#EBess.tenant to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role contact#4th.tenant to role partner#EBess-4th.admin by system and assume }",
|
"{ grant role contact#4th.tenant to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant perm view on partner_details#EBess-4th-details to role partner#EBess-4th.agent by system and assume }",
|
"{ grant perm view on partner_details#22222:EBess-4th-details to role partner#22222:EBess-4th.agent by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.agent to role partner#EBess-4th.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.agent to role partner#22222:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.agent to role person#EBess.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.agent to role person#EBess.admin by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.agent to role contact#4th.admin by system and assume }",
|
"{ grant role partner#22222:EBess-4th.agent to role contact#4th.admin by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role partner#EBess-4th.tenant to role partner#EBess-4th.agent by system and assume }",
|
"{ grant role partner#22222:EBess-4th.tenant to role partner#22222:EBess-4th.agent by system and assume }",
|
||||||
"{ grant role person#EBess.guest to role partner#EBess-4th.tenant by system and assume }",
|
"{ grant role person#EBess.guest to role partner#22222:EBess-4th.tenant by system and assume }",
|
||||||
"{ grant role contact#4th.guest to role partner#EBess-4th.tenant by system and assume }",
|
"{ grant role contact#4th.guest to role partner#22222:EBess-4th.tenant by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on partner#EBess-4th to role partner#EBess-4th.guest by system and assume }",
|
"{ grant perm view on partner#22222:EBess-4th to role partner#22222:EBess-4th.guest by system and assume }",
|
||||||
"{ grant role partner#EBess-4th.guest to role partner#EBess-4th.tenant by system and assume }",
|
"{ grant role partner#22222:EBess-4th.guest to role partner#22222:EBess-4th.tenant by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -217,10 +218,10 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryPartner() {
|
public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("fifth contact");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "fifth contact");
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office_person#ErbenBesslerMelBessler.admin");
|
"hs_office_partner#22222:ErbenBesslerMelBessler-fifthcontact.admin");
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0);
|
final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0);
|
||||||
@ -253,16 +254,16 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void partnerAgent_canNotUpdateRelatedPartner() {
|
public void partnerAgent_canNotUpdateRelatedPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("ninth");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "ninth");
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office_partner#ErbenBesslerMelBessler-ninthcontact.agent");
|
"hs_office_partner#22222:ErbenBesslerMelBessler-ninthcontact.agent");
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("tenth").get(0);
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_partner#ErbenBesslerMelBessler-ninthcontact.agent");
|
context("superuser-alex@hostsharing.net",
|
||||||
|
"hs_office_partner#22222:ErbenBesslerMelBessler-ninthcontact.agent");
|
||||||
givenPartner.getDetails().setBirthName("new birthname");
|
givenPartner.getDetails().setBirthName("new birthname");
|
||||||
return partnerRepo.save(givenPartner);
|
return partnerRepo.save(givenPartner);
|
||||||
});
|
});
|
||||||
@ -304,7 +305,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() {
|
public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("tenth");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "tenth");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -324,7 +325,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
|
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("eleventh");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "eleventh");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -350,7 +351,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
|
||||||
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler("twelfth");
|
final var givenPartner = givenSomeTemporaryPartnerBessler(22222, "Erben Bessler", "twelfth");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -394,12 +395,14 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final String contact) {
|
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(
|
||||||
|
final Integer debitorNumberPrefix, final String person, final String contact) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenPerson = personRepo.findPersonByOptionalNameLike(person).get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(debitorNumberPrefix)
|
||||||
.person(givenPerson)
|
.person(givenPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
|
@ -8,10 +8,11 @@ import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGA
|
|||||||
|
|
||||||
public class TestHsOfficePartner {
|
public class TestHsOfficePartner {
|
||||||
|
|
||||||
public static final HsOfficePartnerEntity TEST_PARTNER = HsOfficePartnerWithLegalPerson("Test Ltd.");
|
public static final HsOfficePartnerEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
|
||||||
|
|
||||||
static public HsOfficePartnerEntity HsOfficePartnerWithLegalPerson(final String tradeName) {
|
static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
|
||||||
return HsOfficePartnerEntity.builder()
|
return HsOfficePartnerEntity.builder()
|
||||||
|
.debitorNumberPrefix(10001)
|
||||||
.person(HsOfficePersonEntity.builder()
|
.person(HsOfficePersonEntity.builder()
|
||||||
.personType(LEGAL)
|
.personType(LEGAL)
|
||||||
.tradeName(tradeName)
|
.tradeName(tradeName)
|
||||||
|
@ -80,7 +80,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10002,
|
"debitorNumber": 1000212,
|
||||||
"billingContact": { "label": "second contact" }
|
"billingContact": { "label": "second contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": { "holder": "Second e.K." },
|
"bankAccount": { "holder": "Second e.K." },
|
||||||
@ -90,7 +90,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
"billingContact": { "label": "first contact" }
|
"billingContact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": { "holder": "First GmbH" },
|
"bankAccount": { "holder": "First GmbH" },
|
||||||
@ -100,7 +100,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10003,
|
"debitorNumber": 1000313,
|
||||||
"billingContact": { "label": "third contact" }
|
"billingContact": { "label": "third contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": { "holder": "Third OHG" },
|
"bankAccount": { "holder": "Third OHG" },
|
||||||
@ -269,7 +269,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
"billingContact": { "label": "first contact" }
|
"billingContact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": {
|
"bankAccount": {
|
||||||
@ -321,7 +321,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": {
|
"debitor": {
|
||||||
"debitorNumber": 10001,
|
"debitorNumber": 1000111,
|
||||||
"billingContact": { "label": "first contact" }
|
"billingContact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
"bankAccount": {
|
"bankAccount": {
|
||||||
@ -376,7 +376,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(10001: First GmbH)");
|
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: First GmbH)");
|
||||||
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
||||||
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
|
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
|
||||||
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
|
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
|
||||||
@ -417,7 +417,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
|
|||||||
// finally, the sepaMandate is actually updated
|
// finally, the sepaMandate is actually updated
|
||||||
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(10001: First GmbH)");
|
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: First GmbH)");
|
||||||
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
||||||
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
|
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");
|
||||||
|
@ -134,24 +134,24 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm * on sepamandate#temprefB to role sepamandate#temprefB.owner by system and assume }",
|
"{ grant perm * on sepamandate#temprefB to role sepamandate#temprefB.owner by system and assume }",
|
||||||
"{ grant role sepamandate#temprefB.owner to role global#global.admin by system and assume }",
|
"{ grant role sepamandate#temprefB.owner to role global#global.admin by system and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm edit on sepamandate#temprefB to role sepamandate#temprefB.admin by system and assume }",
|
"{ grant perm edit on sepamandate#temprefB to role sepamandate#temprefB.admin by system and assume }",
|
||||||
"{ grant role sepamandate#temprefB.admin to role sepamandate#temprefB.owner by system and assume }",
|
"{ grant role sepamandate#temprefB.admin to role sepamandate#temprefB.owner by system and assume }",
|
||||||
"{ grant role bankaccount#Paul....tenant to role sepamandate#temprefB.admin by system and assume }",
|
"{ grant role bankaccount#Paul....tenant to role sepamandate#temprefB.admin by system and assume }",
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role sepamandate#temprefB.agent to role sepamandate#temprefB.admin by system and assume }",
|
"{ grant role sepamandate#temprefB.agent to role sepamandate#temprefB.admin by system and assume }",
|
||||||
"{ grant role debitor#10001FirstGmbH-....tenant to role sepamandate#temprefB.agent by system and assume }",
|
"{ grant role debitor#1000111:FirstGmbH-....tenant to role sepamandate#temprefB.agent by system and assume }",
|
||||||
"{ grant role sepamandate#temprefB.agent to role bankaccount#Paul....admin by system and assume }",
|
"{ grant role sepamandate#temprefB.agent to role bankaccount#Paul....admin by system and assume }",
|
||||||
"{ grant role sepamandate#temprefB.agent to role debitor#10001FirstGmbH-....admin by system and assume }",
|
"{ grant role sepamandate#temprefB.agent to role debitor#1000111:FirstGmbH-....admin by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant role sepamandate#temprefB.tenant to role sepamandate#temprefB.agent by system and assume }",
|
"{ grant role sepamandate#temprefB.tenant to role sepamandate#temprefB.agent by system and assume }",
|
||||||
"{ grant role debitor#10001FirstGmbH-....guest to role sepamandate#temprefB.tenant by system and assume }",
|
"{ grant role debitor#1000111:FirstGmbH-....guest to role sepamandate#temprefB.tenant by system and assume }",
|
||||||
"{ grant role bankaccount#Paul....guest to role sepamandate#temprefB.tenant by system and assume }",
|
"{ grant role bankaccount#Paul....guest to role sepamandate#temprefB.tenant by system and assume }",
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
"{ grant perm view on sepamandate#temprefB to role sepamandate#temprefB.guest by system and assume }",
|
"{ grant perm view on sepamandate#temprefB to role sepamandate#temprefB.guest by system and assume }",
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
member_asset_id; bp_id; date; action; amount
|
member_asset_id; bp_id; date; action; amount; comment
|
||||||
33443; 7; 2000-12-06; PAYMENT; 1280
|
30000; 7; 2000-12-06; PAYMENT; 1280.00; for subscription A
|
||||||
33451; 10; 2000-12-06; PAYMENT; 128
|
31000; 10; 2000-12-06; PAYMENT; 128.00; for subscription B
|
||||||
33701; 7; 2005-01-10; PAYMENT; 2560
|
32000; 7; 2005-01-10; PAYMENT; 2560.00; for subscription C
|
||||||
33810; 10; 2016-12-31; PAYBACK; 128
|
33001; 7; 2005-01-10; HANDOVER; -512.00; for transfer to 10
|
||||||
|
33002; 10; 2005-01-10; ADOPTION; 512.00; for transfer from 7
|
||||||
|
34001; 10; 2016-12-31; CLEARING; -8.00; for cancellation D
|
||||||
|
34002; 10; 2016-12-31; PAYBACK; -100.00; for cancellation D
|
||||||
|
34003; 10; 2016-12-31; LOSS; -20.00; for cancellation D
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
bp_id;member_id;member_code;member_since;member_until;member_role;author_contract;nondisc_contract;free;exempt_vat;indicator_vat;uid_vat
|
bp_id;member_id;member_code;member_since;member_until;member_role;author_contract;nondisc_contract;free;exempt_vat;indicator_vat;uid_vat
|
||||||
7;10007;mih;2000-12-06;;Aufsichtsrat;2006-10-15;2001-10-15;false;false;NET;DE-VAT-007
|
7;10007;hsh00-mih;2000-12-06;;Aufsichtsrat;2006-10-15;2001-10-15;false;false;NET;DE-VAT-007
|
||||||
10;10010;xyz;2000-12-06;2015-12-31;;;;false;false;GROSS;
|
10;10010;hsh00-xyz;2000-12-06;2015-12-31;;;;false;false;GROSS;
|
||||||
12;11012;xxx;2021-04-01;;;;;true;true;GROSS;
|
12;11012;hsh00-xxx;2021-04-01;;;;;true;true;GROSS;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user