import-cancelled-memberships-if-booking-exist (#36)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #36 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
parent
4314b647f6
commit
48f4cf8ed6
@ -19,13 +19,7 @@ import org.hibernate.annotations.JoinFormula;
|
|||||||
import org.hibernate.annotations.NotFound;
|
import org.hibernate.annotations.NotFound;
|
||||||
import org.hibernate.annotations.NotFoundAction;
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.*;
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
import jakarta.persistence.Version;
|
import jakarta.persistence.Version;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -2,7 +2,11 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
|
|
||||||
import io.hypersistence.utils.hibernate.type.range.PostgreSQLRangeType;
|
import io.hypersistence.utils.hibernate.type.range.PostgreSQLRangeType;
|
||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import lombok.*;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
@ -13,17 +17,32 @@ 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;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.PrePersist;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.persistence.Version;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.*;
|
import static io.hypersistence.utils.hibernate.type.range.Range.emptyRange;
|
||||||
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
|
||||||
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||||
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||||
@ -50,7 +69,7 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
|||||||
.withProp(e -> MEMBER_NUMBER_TAG + e.getMemberNumber())
|
.withProp(e -> MEMBER_NUMBER_TAG + e.getMemberNumber())
|
||||||
.withProp(e -> e.getPartner().toShortString())
|
.withProp(e -> e.getPartner().toShortString())
|
||||||
.withProp(e -> e.getValidity().asString())
|
.withProp(e -> e.getValidity().asString())
|
||||||
.withProp(HsOfficeMembershipEntity::getReasonForTermination)
|
.withProp(HsOfficeMembershipEntity::getStatus)
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@ -75,9 +94,9 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
|||||||
@Column(name = "membershipfeebillable", nullable = false)
|
@Column(name = "membershipfeebillable", nullable = false)
|
||||||
private Boolean membershipFeeBillable; // not primitive to force setting the value
|
private Boolean membershipFeeBillable; // not primitive to force setting the value
|
||||||
|
|
||||||
@Column(name = "reasonfortermination")
|
@Column(name = "status")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private HsOfficeReasonForTermination reasonForTermination;
|
private HsOfficeMembershipStatus status;
|
||||||
|
|
||||||
public void setValidFrom(final LocalDate validFrom) {
|
public void setValidFrom(final LocalDate validFrom) {
|
||||||
setValidity(toPostgresDateRange(validFrom, getValidTo()));
|
setValidity(toPostgresDateRange(validFrom, getValidTo()));
|
||||||
@ -97,7 +116,7 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
|||||||
|
|
||||||
public Range<LocalDate> getValidity() {
|
public Range<LocalDate> getValidity() {
|
||||||
if (validity == null) {
|
if (validity == null) {
|
||||||
validity = Range.infinite(LocalDate.class);
|
validity = emptyRange(LocalDate.class);
|
||||||
}
|
}
|
||||||
return validity;
|
return validity;
|
||||||
}
|
}
|
||||||
@ -121,8 +140,8 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
|||||||
|
|
||||||
@PrePersist
|
@PrePersist
|
||||||
void init() {
|
void init() {
|
||||||
if (getReasonForTermination() == null) {
|
if (getStatus() == null) {
|
||||||
setReasonForTermination(HsOfficeReasonForTermination.NONE);
|
setStatus(HsOfficeMembershipStatus.INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +154,7 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
|||||||
JOIN hs_office_partner AS p ON p.uuid = m.partnerUuid
|
JOIN hs_office_partner AS p ON p.uuid = m.partnerUuid
|
||||||
"""))
|
"""))
|
||||||
.withRestrictedViewOrderBy(SQL.projection("validity"))
|
.withRestrictedViewOrderBy(SQL.projection("validity"))
|
||||||
.withUpdatableColumns("validity", "membershipFeeBillable", "reasonForTermination")
|
.withUpdatableColumns("validity", "membershipFeeBillable", "status")
|
||||||
|
|
||||||
.importEntityAlias("partnerRel", HsOfficeRelationEntity.class,
|
.importEntityAlias("partnerRel", HsOfficeRelationEntity.class,
|
||||||
dependsOnColumn("partnerUuid"),
|
dependsOnColumn("partnerUuid"),
|
||||||
|
@ -23,9 +23,9 @@ public class HsOfficeMembershipEntityPatcher implements EntityPatcher<HsOfficeMe
|
|||||||
public void apply(final HsOfficeMembershipPatchResource resource) {
|
public void apply(final HsOfficeMembershipPatchResource resource) {
|
||||||
OptionalFromJson.of(resource.getValidTo()).ifPresent(
|
OptionalFromJson.of(resource.getValidTo()).ifPresent(
|
||||||
entity::setValidTo);
|
entity::setValidTo);
|
||||||
Optional.ofNullable(resource.getReasonForTermination())
|
Optional.ofNullable(resource.getStatus())
|
||||||
.map(v -> mapper.map(v, HsOfficeReasonForTermination.class))
|
.map(v -> mapper.map(v, HsOfficeMembershipStatus.class))
|
||||||
.ifPresent(entity::setReasonForTermination);
|
.ifPresent(entity::setStatus);
|
||||||
OptionalFromJson.of(resource.getMembershipFeeBillable()).ifPresent(
|
OptionalFromJson.of(resource.getMembershipFeeBillable()).ifPresent(
|
||||||
entity::setMembershipFeeBillable);
|
entity::setMembershipFeeBillable);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.membership;
|
||||||
|
|
||||||
|
public enum HsOfficeMembershipStatus {
|
||||||
|
INVALID, ACTIVE, CANCELLED, TRANSFERRED, DECEASED, LIQUIDATED, EXPULSED, UNKNOWN;
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.membership;
|
|
||||||
|
|
||||||
public enum HsOfficeReasonForTermination {
|
|
||||||
NONE, CANCELLATION, TRANSFER, DEATH, LIQUIDATION, EXPULSION, UNKNOWN;
|
|
||||||
}
|
|
@ -3,15 +3,17 @@ components:
|
|||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
|
|
||||||
HsOfficeReasonForTermination:
|
HsOfficeMembershipStatus:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- NONE
|
- INVALID
|
||||||
- CANCELLATION
|
- ACTIVE
|
||||||
- TRANSFER
|
- CANCELLED
|
||||||
- DEATH
|
- TRANSFERRED
|
||||||
- LIQUIDATION
|
- DECEASED
|
||||||
- EXPULSION
|
- LIQUIDATED
|
||||||
|
- EXPULSED
|
||||||
|
- UNKNOWN
|
||||||
|
|
||||||
HsOfficeMembership:
|
HsOfficeMembership:
|
||||||
type: object
|
type: object
|
||||||
@ -38,8 +40,8 @@ components:
|
|||||||
validTo:
|
validTo:
|
||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
reasonForTermination:
|
status:
|
||||||
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
$ref: '#/components/schemas/HsOfficeMembershipStatus'
|
||||||
membershipFeeBillable:
|
membershipFeeBillable:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
@ -50,9 +52,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
nullable: true
|
nullable: true
|
||||||
reasonForTermination:
|
status:
|
||||||
nullable: true
|
$ref: '#/components/schemas/HsOfficeMembershipStatus'
|
||||||
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
|
||||||
membershipFeeBillable:
|
membershipFeeBillable:
|
||||||
nullable: true
|
nullable: true
|
||||||
type: boolean
|
type: boolean
|
||||||
@ -79,8 +80,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
nullable: true
|
nullable: true
|
||||||
reasonForTermination:
|
status:
|
||||||
$ref: '#/components/schemas/HsOfficeReasonForTermination'
|
$ref: '#/components/schemas/HsOfficeMembershipStatus'
|
||||||
membershipFeeBillable:
|
membershipFeeBillable:
|
||||||
nullable: false
|
nullable: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
openapi: 3.0.1
|
openapi: 3.0.3
|
||||||
info:
|
info:
|
||||||
title: Hostsharing hsadmin-ng API
|
title: Hostsharing hsadmin-ng API
|
||||||
version: v0
|
version: v0
|
||||||
|
@ -4,9 +4,18 @@
|
|||||||
--changeset hs-office-membership-MAIN-TABLE:1 endDelimiter:--//
|
--changeset hs-office-membership-MAIN-TABLE:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE HsOfficeReasonForTermination AS ENUM ('NONE', 'CANCELLATION', 'TRANSFER', 'DEATH', 'LIQUIDATION', 'EXPULSION', 'UNKNOWN');
|
CREATE TYPE HsOfficeMembershipStatus AS ENUM (
|
||||||
|
'INVALID',
|
||||||
|
'ACTIVE',
|
||||||
|
'CANCELLED',
|
||||||
|
'TRANSFERRED',
|
||||||
|
'DECEASED',
|
||||||
|
'LIQUIDATED',
|
||||||
|
'EXPULSED',
|
||||||
|
'UNKNOWN'
|
||||||
|
);
|
||||||
|
|
||||||
CREATE CAST (character varying as HsOfficeReasonForTermination) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as HsOfficeMembershipStatus) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
create table if not exists hs_office_membership
|
create table if not exists hs_office_membership
|
||||||
(
|
(
|
||||||
@ -15,7 +24,7 @@ create table if not exists hs_office_membership
|
|||||||
partnerUuid uuid not null references hs_office_partner(uuid),
|
partnerUuid uuid not null references hs_office_partner(uuid),
|
||||||
memberNumberSuffix char(2) not null check (memberNumberSuffix::text ~ '^[0-9][0-9]$'),
|
memberNumberSuffix char(2) not null check (memberNumberSuffix::text ~ '^[0-9][0-9]$'),
|
||||||
validity daterange not null,
|
validity daterange not null,
|
||||||
reasonForTermination HsOfficeReasonForTermination not null default 'NONE',
|
status HsOfficeMembershipStatus not null default 'ACTIVE',
|
||||||
membershipFeeBillable boolean not null default true,
|
membershipFeeBillable boolean not null default true,
|
||||||
|
|
||||||
UNIQUE(partnerUuid, memberNumberSuffix)
|
UNIQUE(partnerUuid, memberNumberSuffix)
|
||||||
|
@ -172,7 +172,7 @@ call generateRbacRestrictedView('hs_office_membership',
|
|||||||
$updates$
|
$updates$
|
||||||
validity = new.validity,
|
validity = new.validity,
|
||||||
membershipFeeBillable = new.membershipFeeBillable,
|
membershipFeeBillable = new.membershipFeeBillable,
|
||||||
reasonForTermination = new.reasonForTermination
|
status = new.status
|
||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ begin
|
|||||||
raise notice 'creating test Membership: M-% %', forPartnerNumber, newMemberNumberSuffix;
|
raise notice 'creating test Membership: M-% %', forPartnerNumber, newMemberNumberSuffix;
|
||||||
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
||||||
insert
|
insert
|
||||||
into hs_office_membership (uuid, partneruuid, memberNumberSuffix, validity, reasonfortermination)
|
into hs_office_membership (uuid, partneruuid, memberNumberSuffix, validity, status)
|
||||||
values (uuid_generate_v4(), relatedPartner.uuid, newMemberNumberSuffix, daterange('20221001' , null, '[]'), 'NONE');
|
values (uuid_generate_v4(), relatedPartner.uuid, newMemberNumberSuffix, daterange('20221001' , null, '[]'), 'ACTIVE');
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ import jakarta.persistence.PersistenceContext;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeReasonForTermination.CANCELLATION;
|
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus.ACTIVE;
|
||||||
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeReasonForTermination.NONE;
|
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus.CANCELLED;
|
||||||
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -84,7 +84,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "01",
|
"memberNumberSuffix": "01",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"partner": { "partnerNumber": 10002 },
|
"partner": { "partnerNumber": 10002 },
|
||||||
@ -92,7 +92,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "02",
|
"memberNumberSuffix": "02",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"partner": { "partnerNumber": 10003 },
|
"partner": { "partnerNumber": 10003 },
|
||||||
@ -100,7 +100,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "03",
|
"memberNumberSuffix": "03",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
@ -131,7 +131,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "01",
|
"memberNumberSuffix": "01",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
@ -159,7 +159,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "02",
|
"memberNumberSuffix": "02",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
@ -239,7 +239,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "01",
|
"memberNumberSuffix": "01",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
"memberNumberSuffix": "03",
|
"memberNumberSuffix": "03",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"reasonForTermination": "NONE"
|
"status": "ACTIVE"
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"validTo": "2023-12-31",
|
"validTo": "2023-12-31",
|
||||||
"reasonForTermination": "CANCELLATION"
|
"status": "CANCELLED"
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -320,7 +320,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
.body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix()))
|
.body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix()))
|
||||||
.body("validFrom", is("2022-11-01"))
|
.body("validFrom", is("2022-11-01"))
|
||||||
.body("validTo", is("2023-12-31"))
|
.body("validTo", is("2023-12-31"))
|
||||||
.body("reasonForTermination", is("CANCELLATION"));
|
.body("status", is("CANCELLED"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
// finally, the Membership is actually updated
|
// finally, the Membership is actually updated
|
||||||
@ -329,7 +329,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
assertThat(mandate.getPartner().toShortString()).isEqualTo("P-10001");
|
assertThat(mandate.getPartner().toShortString()).isEqualTo("P-10001");
|
||||||
assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix());
|
assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix());
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
|
||||||
assertThat(mandate.getReasonForTermination()).isEqualTo(CANCELLATION);
|
assertThat(mandate.getStatus()).isEqualTo(CANCELLED);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -351,7 +351,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"validTo": "2024-01-01",
|
"validTo": "2024-01-01",
|
||||||
"reasonForTermination": "CANCELLATION"
|
"status": "CANCELLED"
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -364,7 +364,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
|
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-02)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-02)");
|
||||||
assertThat(mandate.getReasonForTermination()).isEqualTo(CANCELLATION);
|
assertThat(mandate.getStatus()).isEqualTo(CANCELLED);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -441,7 +441,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
.partner(givenPartner)
|
.partner(givenPartner)
|
||||||
.memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX)
|
.memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX)
|
||||||
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
||||||
.reasonForTermination(NONE)
|
.status(ACTIVE)
|
||||||
.membershipFeeBillable(true)
|
.membershipFeeBillable(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeReasonForTerminationResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipStatusResource;
|
||||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||||
import net.hostsharing.test.PatchUnitTestBase;
|
import net.hostsharing.test.PatchUnitTestBase;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -79,11 +79,11 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
PATCHED_VALID_TO,
|
PATCHED_VALID_TO,
|
||||||
HsOfficeMembershipEntity::setValidTo),
|
HsOfficeMembershipEntity::setValidTo),
|
||||||
new SimpleProperty<>(
|
new SimpleProperty<>(
|
||||||
"reasonForTermination",
|
"status",
|
||||||
HsOfficeMembershipPatchResource::setReasonForTermination,
|
HsOfficeMembershipPatchResource::setStatus,
|
||||||
HsOfficeReasonForTerminationResource.CANCELLATION,
|
HsOfficeMembershipStatusResource.CANCELLED,
|
||||||
HsOfficeMembershipEntity::setReasonForTermination,
|
HsOfficeMembershipEntity::setStatus,
|
||||||
HsOfficeReasonForTermination.CANCELLATION)
|
HsOfficeMembershipStatus.CANCELLED)
|
||||||
.notNullable(),
|
.notNullable(),
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"membershipFeeBillable",
|
"membershipFeeBillable",
|
||||||
|
@ -62,27 +62,27 @@ class HsOfficeMembershipEntityUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getValidtyIfNull() {
|
void getEmptyValidtyIfNull() {
|
||||||
givenMembership.setValidity(null);
|
givenMembership.setValidity(null);
|
||||||
final var result = givenMembership.getValidity();
|
final var result = givenMembership.getValidity();
|
||||||
assertThat(result).isEqualTo(Range.infinite(LocalDate.class));
|
assertThat(result.isEmpty()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void initializesReasonForTerminationInPrePersistIfNull() throws Exception {
|
void initializesStatusInPrePersistIfNull() throws Exception {
|
||||||
final var givenUninitializedMembership = new HsOfficeMembershipEntity();
|
final var givenUninitializedMembership = new HsOfficeMembershipEntity();
|
||||||
assertThat(givenUninitializedMembership.getReasonForTermination()).as("precondition failed").isNull();
|
assertThat(givenUninitializedMembership.getStatus()).as("precondition failed").isNull();
|
||||||
|
|
||||||
invokePrePersist(givenUninitializedMembership);
|
invokePrePersist(givenUninitializedMembership);
|
||||||
assertThat(givenUninitializedMembership.getReasonForTermination()).isEqualTo(HsOfficeReasonForTermination.NONE);
|
assertThat(givenUninitializedMembership.getStatus()).isEqualTo(HsOfficeMembershipStatus.INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void doesNotOverwriteReasonForTerminationInPrePersistIfNotNull() throws Exception {
|
void doesNotOverwriteStatusInPrePersistIfNotNull() throws Exception {
|
||||||
givenMembership.setReasonForTermination(HsOfficeReasonForTermination.CANCELLATION);
|
givenMembership.setStatus(HsOfficeMembershipStatus.CANCELLED);
|
||||||
|
|
||||||
invokePrePersist(givenMembership);
|
invokePrePersist(givenMembership);
|
||||||
assertThat(givenMembership.getReasonForTermination()).isEqualTo(HsOfficeReasonForTermination.CANCELLATION);
|
assertThat(givenMembership.getStatus()).isEqualTo(HsOfficeMembershipStatus.CANCELLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -161,9 +161,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(
|
exactlyTheseMembershipsAreReturned(
|
||||||
result,
|
result,
|
||||||
"Membership(M-1000101, P-10001, [2022-10-01,), NONE)",
|
"Membership(M-1000101, P-10001, [2022-10-01,), ACTIVE)",
|
||||||
"Membership(M-1000202, P-10002, [2022-10-01,), NONE)",
|
"Membership(M-1000202, P-10002, [2022-10-01,), ACTIVE)",
|
||||||
"Membership(M-1000303, P-10003, [2022-10-01,), NONE)");
|
"Membership(M-1000303, P-10003, [2022-10-01,), ACTIVE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -177,7 +177,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseMembershipsAreReturned(result,
|
exactlyTheseMembershipsAreReturned(result,
|
||||||
"Membership(M-1000101, P-10001, [2022-10-01,), NONE)");
|
"Membership(M-1000101, P-10001, [2022-10-01,), ACTIVE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -192,7 +192,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
assertThat(result)
|
assertThat(result)
|
||||||
.isNotNull()
|
.isNotNull()
|
||||||
.extracting(Object::toString)
|
.extracting(Object::toString)
|
||||||
.isEqualTo("Membership(M-1000202, P-10002, [2022-10-01,), NONE)");
|
.isEqualTo("Membership(M-1000202, P-10002, [2022-10-01,), ACTIVE)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
givenMembership.setValidity(Range.closedOpen(
|
givenMembership.setValidity(Range.closedOpen(
|
||||||
givenMembership.getValidity().lower(), newValidityEnd));
|
givenMembership.getValidity().lower(), newValidityEnd));
|
||||||
givenMembership.setReasonForTermination(HsOfficeReasonForTermination.CANCELLATION);
|
givenMembership.setStatus(HsOfficeMembershipStatus.CANCELLED);
|
||||||
return toCleanup(membershipRepo.save(givenMembership));
|
return toCleanup(membershipRepo.save(givenMembership));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.office.coopshares.HsOfficeCoopSharesTransact
|
|||||||
import net.hostsharing.hsadminng.hs.office.coopshares.HsOfficeCoopSharesTransactionType;
|
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.HsOfficeMembershipStatus;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
@ -54,6 +54,7 @@ import java.util.stream.Collectors;
|
|||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
@ -185,6 +186,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
17=partner(P-10017: null null, null),
|
17=partner(P-10017: null null, null),
|
||||||
20=partner(P-10020: null null, null),
|
20=partner(P-10020: null null, null),
|
||||||
22=partner(P-11022: null null, null),
|
22=partner(P-11022: null null, null),
|
||||||
|
90=partner(P-19090: null null, null),
|
||||||
99=partner(P-19999: null null, null)
|
99=partner(P-19999: null null, null)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -194,14 +196,15 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
17=debitor(D-1001700: rel(anchor='null null, null', type='DEBITOR'), mih),
|
17=debitor(D-1001700: rel(anchor='null null, null', type='DEBITOR'), mih),
|
||||||
20=debitor(D-1002000: rel(anchor='null null, null', type='DEBITOR'), xyz),
|
20=debitor(D-1002000: rel(anchor='null null, null', type='DEBITOR'), xyz),
|
||||||
22=debitor(D-1102200: rel(anchor='null null, null', type='DEBITOR'), xxx),
|
22=debitor(D-1102200: rel(anchor='null null, null', type='DEBITOR'), xxx),
|
||||||
|
90=debitor(D-1909000: rel(anchor='null null, null', type='DEBITOR'), yyy),
|
||||||
99=debitor(D-1999900: rel(anchor='null null, null', type='DEBITOR'), zzz)
|
99=debitor(D-1999900: rel(anchor='null null, null', type='DEBITOR'), zzz)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
17=Membership(M-1001700, P-10017, [2000-12-06,), NONE),
|
17=Membership(M-1001700, P-10017, [2000-12-06,), ACTIVE),
|
||||||
20=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
20=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
||||||
22=Membership(M-1102200, P-11022, [2021-04-01,), NONE)
|
22=Membership(M-1102200, P-11022, [2021-04-01,), ACTIVE)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -228,6 +231,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
17=partner(P-10017: NP Mellies, Michael, Herr Michael Mellies ),
|
17=partner(P-10017: NP Mellies, Michael, Herr Michael Mellies ),
|
||||||
20=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH),
|
20=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH),
|
||||||
22=partner(P-11022: ?? Test PS, Petra Schmidt , Test PS),
|
22=partner(P-11022: ?? Test PS, Petra Schmidt , Test PS),
|
||||||
|
90=partner(P-19090: NP Camus, Cecilia, Frau Cecilia Camus ),
|
||||||
99=partner(P-19999: null null, null)
|
99=partner(P-19999: null null, null)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -240,7 +244,8 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
1203=contact(label='Herr Philip Meyer-Contract , JM GmbH', emailAddresses='pm-partner@example.org'),
|
1203=contact(label='Herr Philip Meyer-Contract , JM GmbH', emailAddresses='pm-partner@example.org'),
|
||||||
1204=contact(label='Frau Tammy Meyer-VIP , JM GmbH', emailAddresses='tm-vip@example.org'),
|
1204=contact(label='Frau Tammy Meyer-VIP , JM GmbH', emailAddresses='tm-vip@example.org'),
|
||||||
1301=contact(label='Petra Schmidt , Test PS', emailAddresses='ps@example.com'),
|
1301=contact(label='Petra Schmidt , Test PS', emailAddresses='ps@example.com'),
|
||||||
1401=contact(label='Frau Frauke Fanninga ', emailAddresses='ff@example.org')
|
1401=contact(label='Frau Frauke Fanninga ', emailAddresses='ff@example.org'),
|
||||||
|
1501=contact(label='Frau Cecilia Camus ', emailAddresses='cc@example.org')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(persons)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(persons)).isEqualToIgnoringWhitespace("""
|
||||||
@ -253,7 +258,8 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
1203=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Contract', givenName='Philip'),
|
1203=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Contract', givenName='Philip'),
|
||||||
1204=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-VIP', givenName='Tammy'),
|
1204=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-VIP', givenName='Tammy'),
|
||||||
1301=person(personType='??', tradeName='Test PS', familyName='Schmidt', givenName='Petra'),
|
1301=person(personType='??', tradeName='Test PS', familyName='Schmidt', givenName='Petra'),
|
||||||
1401=person(personType='NP', tradeName='', familyName='Fanninga', givenName='Frauke')
|
1401=person(personType='NP', tradeName='', familyName='Fanninga', givenName='Frauke'),
|
||||||
|
1501=person(personType='NP', tradeName='', familyName='Camus', givenName='Cecilia')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
|
||||||
@ -261,14 +267,15 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
17=debitor(D-1001700: rel(anchor='NP Mellies, Michael', type='DEBITOR', holder='NP Mellies, Michael'), mih),
|
17=debitor(D-1001700: rel(anchor='NP Mellies, Michael', type='DEBITOR', holder='NP Mellies, Michael'), mih),
|
||||||
20=debitor(D-1002000: rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH'), xyz),
|
20=debitor(D-1002000: rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH'), xyz),
|
||||||
22=debitor(D-1102200: rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS'), xxx),
|
22=debitor(D-1102200: rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS'), xxx),
|
||||||
|
90=debitor(D-1909000: rel(anchor='NP Camus, Cecilia', type='DEBITOR', holder='NP Camus, Cecilia'), yyy),
|
||||||
99=debitor(D-1999900: rel(anchor='null null, null', type='DEBITOR'), zzz)
|
99=debitor(D-1999900: rel(anchor='null null, null', type='DEBITOR'), zzz)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
17=Membership(M-1001700, P-10017, [2000-12-06,), NONE),
|
17=Membership(M-1001700, P-10017, [2000-12-06,), ACTIVE),
|
||||||
20=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
20=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
||||||
22=Membership(M-1102200, P-11022, [2021-04-01,), NONE)
|
22=Membership(M-1102200, P-11022, [2021-04-01,), ACTIVE)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
||||||
@ -279,21 +286,25 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
2000003=rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
2000003=rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
||||||
2000004=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000004=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000005=rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000005=rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000006=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='null null, null'),
|
2000006=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
||||||
2000007=rel(anchor='null null, null', type='DEBITOR'),
|
2000007=rel(anchor='NP Camus, Cecilia', type='DEBITOR', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
||||||
2000008=rel(anchor='NP Mellies, Michael', type='OPERATIONS', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000008=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='null null, null'),
|
||||||
2000009=rel(anchor='NP Mellies, Michael', type='REPRESENTATIVE', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000009=rel(anchor='null null, null', type='DEBITOR'),
|
||||||
2000010=rel(anchor='LP JM GmbH', type='EX_PARTNER', holder='LP JM e.K.', contact='JM e.K.'),
|
2000010=rel(anchor='NP Mellies, Michael', type='OPERATIONS', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000011=rel(anchor='LP JM GmbH', type='OPERATIONS', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000011=rel(anchor='NP Mellies, Michael', type='REPRESENTATIVE', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000012=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000012=rel(anchor='LP JM GmbH', type='EX_PARTNER', holder='LP JM e.K.', contact='JM e.K.'),
|
||||||
2000013=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000013=rel(anchor='LP JM GmbH', type='OPERATIONS', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000014=rel(anchor='LP JM GmbH', type='REPRESENTATIVE', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000014=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000015=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='members-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000015=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000016=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='customers-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000016=rel(anchor='LP JM GmbH', type='REPRESENTATIVE', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000017=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
2000017=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='members-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000018=rel(anchor='?? Test PS', type='OPERATIONS', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000018=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='customers-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000019=rel(anchor='?? Test PS', type='REPRESENTATIVE', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000019=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
||||||
2000020=rel(anchor='NP Mellies, Michael', type='SUBSCRIBER', mark='operations-announce', holder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga ')
|
2000020=rel(anchor='?? Test PS', type='OPERATIONS', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
|
2000021=rel(anchor='?? Test PS', type='REPRESENTATIVE', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
|
2000022=rel(anchor='NP Mellies, Michael', type='SUBSCRIBER', mark='operations-announce', holder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga '),
|
||||||
|
2000023=rel(anchor='NP Camus, Cecilia', type='OPERATIONS', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
||||||
|
2000024=rel(anchor='NP Camus, Cecilia', type='REPRESENTATIVE', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus ')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -383,7 +394,23 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
33002=CoopAssetsTransaction(M-1002000: 2005-01-10, ADOPTION, 512.00, for transfer from 7),
|
33002=CoopAssetsTransaction(M-1002000: 2005-01-10, ADOPTION, 512.00, for transfer from 7),
|
||||||
34001=CoopAssetsTransaction(M-1002000: 2016-12-31, CLEARING, -8.00, for cancellation D),
|
34001=CoopAssetsTransaction(M-1002000: 2016-12-31, CLEARING, -8.00, for cancellation D),
|
||||||
34002=CoopAssetsTransaction(M-1002000: 2016-12-31, DISBURSAL, -100.00, for cancellation D),
|
34002=CoopAssetsTransaction(M-1002000: 2016-12-31, DISBURSAL, -100.00, for cancellation D),
|
||||||
34003=CoopAssetsTransaction(M-1002000: 2016-12-31, LOSS, -20.00, for cancellation D)
|
34003=CoopAssetsTransaction(M-1002000: 2016-12-31, LOSS, -20.00, for cancellation D),
|
||||||
|
35001=CoopAssetsTransaction(M-1909000: 2024-01-15, DEPOSIT, 128.00, for subscription E),
|
||||||
|
35002=CoopAssetsTransaction(M-1909000: 2024-01-20, ADJUSTMENT, -128.00, chargeback for subscription E)
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1099)
|
||||||
|
void verifyMemberships() {
|
||||||
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
|
||||||
|
{
|
||||||
|
17=Membership(M-1001700, P-10017, [2000-12-06,), ACTIVE),
|
||||||
|
20=Membership(M-1002000, P-10020, [2000-12-06,2016-01-01), UNKNOWN),
|
||||||
|
22=Membership(M-1102200, P-11022, [2021-04-01,), ACTIVE),
|
||||||
|
90=Membership(M-1909000, P-19090, empty, INVALID)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -742,10 +769,10 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
rec.getLocalDate("member_since"),
|
rec.getLocalDate("member_since"),
|
||||||
rec.getLocalDate("member_until")))
|
rec.getLocalDate("member_until")))
|
||||||
.membershipFeeBillable(rec.isEmpty("member_role"))
|
.membershipFeeBillable(rec.isEmpty("member_role"))
|
||||||
.reasonForTermination(
|
.status(
|
||||||
isBlank(rec.getString("member_until"))
|
isBlank(rec.getString("member_until"))
|
||||||
? HsOfficeReasonForTermination.NONE
|
? HsOfficeMembershipStatus.ACTIVE
|
||||||
: HsOfficeReasonForTermination.UNKNOWN)
|
: HsOfficeMembershipStatus.UNKNOWN)
|
||||||
.build();
|
.build();
|
||||||
memberships.put(rec.getInteger("bp_id"), membership);
|
memberships.put(rec.getInteger("bp_id"), membership);
|
||||||
}
|
}
|
||||||
@ -760,7 +787,9 @@ public class ImportOfficeData 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 member = memberships.get(rec.getInteger("bp_id"));
|
final var bpId = rec.getInteger("bp_id");
|
||||||
|
final var member = ofNullable(memberships.get(bpId))
|
||||||
|
.orElseGet(() -> createOnDemandMembership(bpId));
|
||||||
|
|
||||||
final var shareTransaction = HsOfficeCoopSharesTransactionEntity.builder()
|
final var shareTransaction = HsOfficeCoopSharesTransactionEntity.builder()
|
||||||
.membership(member)
|
.membership(member)
|
||||||
@ -788,11 +817,14 @@ public class ImportOfficeData 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 member = memberships.get(rec.getInteger("bp_id"));
|
final var bpId = rec.getInteger("bp_id");
|
||||||
|
final var member = ofNullable(memberships.get(bpId))
|
||||||
|
.orElseGet(() -> createOnDemandMembership(bpId));
|
||||||
|
|
||||||
final var assetTypeMapping = new HashMap<String, HsOfficeCoopAssetsTransactionType>() {
|
final var assetTypeMapping = new HashMap<String, HsOfficeCoopAssetsTransactionType>() {
|
||||||
|
|
||||||
{
|
{
|
||||||
|
put("ADJUSTMENT", HsOfficeCoopAssetsTransactionType.ADJUSTMENT);
|
||||||
put("HANDOVER", HsOfficeCoopAssetsTransactionType.TRANSFER);
|
put("HANDOVER", HsOfficeCoopAssetsTransactionType.TRANSFER);
|
||||||
put("ADOPTION", HsOfficeCoopAssetsTransactionType.ADOPTION);
|
put("ADOPTION", HsOfficeCoopAssetsTransactionType.ADOPTION);
|
||||||
put("LOSS", HsOfficeCoopAssetsTransactionType.LOSS);
|
put("LOSS", HsOfficeCoopAssetsTransactionType.LOSS);
|
||||||
@ -823,6 +855,17 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static HsOfficeMembershipEntity createOnDemandMembership(final Integer bpId) {
|
||||||
|
final var onDemandMembership = HsOfficeMembershipEntity.builder()
|
||||||
|
.memberNumberSuffix("00")
|
||||||
|
.membershipFeeBillable(false)
|
||||||
|
.partner(partners.get(bpId))
|
||||||
|
.status(HsOfficeMembershipStatus.INVALID)
|
||||||
|
.build();
|
||||||
|
memberships.put(bpId, onDemandMembership);
|
||||||
|
return onDemandMembership;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -86,7 +86,7 @@ class HsOfficePersonEntityUnitTest {
|
|||||||
|
|
||||||
final var actualDisplay = givenPersonEntity.toShortString();
|
final var actualDisplay = givenPersonEntity.toShortString();
|
||||||
|
|
||||||
assertThat(actualDisplay).isEqualTo("NP Frau some family name, some given name");
|
assertThat(actualDisplay).isEqualTo("NP some family name, some given name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
member_asset_id; bp_id; date; action; amount; comment
|
member_asset_id; bp_id; date; action; amount; comment
|
||||||
30000; 17; 2000-12-06; PAYMENT; 1280.00; for subscription A
|
30000; 17; 2000-12-06; PAYMENT; 1280.00; for subscription A
|
||||||
31000; 20; 2000-12-06; PAYMENT; 128.00; for subscription B
|
31000; 20; 2000-12-06; PAYMENT; 128.00; for subscription B
|
||||||
32000; 17; 2005-01-10; PAYMENT; 2560.00; for subscription C
|
32000; 17; 2005-01-10; PAYMENT; 2560.00; for subscription C
|
||||||
33001; 17; 2005-01-10; HANDOVER; -512.00; for transfer to 10
|
33001; 17; 2005-01-10; HANDOVER; -512.00; for transfer to 10
|
||||||
33002; 20; 2005-01-10; ADOPTION; 512.00; for transfer from 7
|
33002; 20; 2005-01-10; ADOPTION; 512.00; for transfer from 7
|
||||||
34001; 20; 2016-12-31; CLEARING; -8.00; for cancellation D
|
34001; 20; 2016-12-31; CLEARING; -8.00; for cancellation D
|
||||||
34002; 20; 2016-12-31; PAYBACK; -100.00; for cancellation D
|
34002; 20; 2016-12-31; PAYBACK; -100.00; for cancellation D
|
||||||
34003; 20; 2016-12-31; LOSS; -20.00; for cancellation D
|
34003; 20; 2016-12-31; LOSS; -20.00; for cancellation D
|
||||||
|
35001; 90; 2024-01-15; PAYMENT; 128.00; for subscription E
|
||||||
|
35002; 90; 2024-01-20; ADJUSTMENT;-128.00; chargeback for subscription E
|
||||||
|
|
@ -2,4 +2,5 @@ bp_id;member_id;member_code;member_since;member_until;member_role;author_contrac
|
|||||||
17;10017;hsh00-mih;2000-12-06;;Aufsichtsrat;2006-10-15;2001-10-15;false;false;NET;DE-VAT-007
|
17;10017;hsh00-mih;2000-12-06;;Aufsichtsrat;2006-10-15;2001-10-15;false;false;NET;DE-VAT-007
|
||||||
20;10020;hsh00-xyz;2000-12-06;2015-12-31;;;;false;false;GROSS;
|
20;10020;hsh00-xyz;2000-12-06;2015-12-31;;;;false;false;GROSS;
|
||||||
22;11022;hsh00-xxx;2021-04-01;;;;;true;true;GROSS;
|
22;11022;hsh00-xxx;2021-04-01;;;;;true;true;GROSS;
|
||||||
|
90;19090;hsh00-yyy;;;;;;true;true;GROSS;
|
||||||
99;19999;hsh00-zzz;;;;;;false;false;GROSS;
|
99;19999;hsh00-zzz;;;;;;false;false;GROSS;
|
||||||
|
|
@ -15,3 +15,6 @@ contact_id; bp_id; salut; first_name; last_name; title; firma; co; street; zip
|
|||||||
|
|
||||||
# eine natürliche Person, die nur Subscriber ist
|
# eine natürliche Person, die nur Subscriber ist
|
||||||
1401; 17; Frau; Frauke; Fanninga; ; ; ; Am Walde 1; 29456; Hitzacker; DE; ; ; ;; ff@example.org; subscriber:operations-announce
|
1401; 17; Frau; Frauke; Fanninga; ; ; ; Am Walde 1; 29456; Hitzacker; DE; ; ; ;; ff@example.org; subscriber:operations-announce
|
||||||
|
|
||||||
|
# eine natürliche Person als Partner
|
||||||
|
1501; 90; Frau; Cecilia; Camus; ; ; ; Rue d'Avignion 60; 45000; Orléans; FR; ; ; ;; cc@example.org; partner,contractual,billing,operation
|
||||||
|
|
Loading…
Reference in New Issue
Block a user