1
0

memberNumber as partnerNumber+memberNumberSuffix (#13)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/13
Reviewed-by: Michael Hierweck <michael.hierweck@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-01-24 15:57:16 +01:00
parent f150ea2091
commit fb974a3b43
47 changed files with 789 additions and 423 deletions

View File

@ -53,12 +53,25 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, HasUu
@Column(name = "valuedate")
private LocalDate valueDate;
/**
* The signed value which directly affects the booking balance.
*
* <p>This means, that a DEPOSIT is always positive, a DISBURSAL is always negative,
* but an ADJUSTMENT can bei either positive or negative.
* See {@link HsOfficeCoopAssetsTransactionType} for</p> more information.
*/
@Column(name = "assetvalue")
private BigDecimal assetValue;
/**
* The booking reference.
*/
@Column(name = "reference")
private String reference; // TODO: what is this for?
private String reference;
/**
* An optional arbitrary comment.
*/
@Column(name = "comment")
private String comment;

View File

@ -17,7 +17,7 @@ public interface HsOfficeCoopAssetsTransactionRepository extends Repository<HsOf
WHERE ( CAST(:membershipUuid AS org.hibernate.type.UUIDCharType) IS NULL OR at.membership.uuid = :membershipUuid)
AND ( CAST(:fromValueDate AS java.time.LocalDate) IS NULL OR (at.valueDate >= :fromValueDate))
AND ( CAST(:toValueDate AS java.time.LocalDate)IS NULL OR (at.valueDate <= :toValueDate))
ORDER BY at.membership.memberNumber, at.valueDate
ORDER BY at.membership.memberNumberSuffix, at.valueDate
""")
List<HsOfficeCoopAssetsTransactionEntity> findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
UUID membershipUuid, LocalDate fromValueDate, LocalDate toValueDate);

View File

@ -1,12 +1,43 @@
package net.hostsharing.hsadminng.hs.office.coopassets;
public enum HsOfficeCoopAssetsTransactionType {
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
/**
* correction of wrong bookings, value can be positive or negative
*/
ADJUSTMENT,
/**
* payment received from member after signing shares, value >0
*/
DEPOSIT,
/**
* payment send to member after cancellation of shares, value <0
*/
DISBURSAL,
/**
* transferring shares to another member, value <0
*/
TRANSFER,
/**
* receiving shares from another member, value >0
*/
ADOPTION,
/**
* settlement with members dept, value <0
*/
CLEARING,
/**
* assignment of balance sheet loss in case of cancellation of shares, value <0
*/
LOSS,
/**
* limitation period was reached after impossible disbursal, value <0
*/
LIMITATION
}

View File

@ -46,15 +46,28 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUu
@Enumerated(EnumType.STRING)
private HsOfficeCoopSharesTransactionType transactionType;
/**
* The signed value which directly affects the booking balance.
*
* <p>This means, that a SUBSCRIPTION is always positive, a CANCELLATION is always negative,
* but an ADJUSTMENT can bei either positive or negative.
* See {@link HsOfficeCoopSharesTransactionType} for</p> more information.
*/
@Column(name = "valuedate")
private LocalDate valueDate;
@Column(name = "sharecount")
private int shareCount;
/**
* The Booking reference.
*/
@Column(name = "reference")
private String reference; // TODO: what is this for?
private String reference;
/**
* An optional arbitrary comment.
*/
@Column(name = "comment")
private String comment;
@ -69,6 +82,6 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUu
@Override
public String toShortString() {
return "%s%+d".formatted(getMemberNumber(), shareCount);
return "M-%s%+d".formatted(getMemberNumber(), shareCount);
}
}

View File

@ -17,7 +17,7 @@ public interface HsOfficeCoopSharesTransactionRepository extends Repository<HsOf
WHERE ( CAST(:membershipUuid AS org.hibernate.type.UUIDCharType) IS NULL OR st.membership.uuid = :membershipUuid)
AND ( CAST(:fromValueDate AS java.time.LocalDate) IS NULL OR (st.valueDate >= :fromValueDate))
AND ( CAST(:toValueDate AS java.time.LocalDate)IS NULL OR (st.valueDate <= :toValueDate))
ORDER BY st.membership.memberNumber, st.valueDate
ORDER BY st.membership.memberNumberSuffix, st.valueDate
""")
List<HsOfficeCoopSharesTransactionEntity> findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
UUID membershipUuid, LocalDate fromValueDate, LocalDate toValueDate);

View File

@ -1,7 +1,18 @@
package net.hostsharing.hsadminng.hs.office.coopshares;
public enum HsOfficeCoopSharesTransactionType {
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
/**
* correction of wrong bookings, with either positive or negative value
*/
ADJUSTMENT,
/**
* shares signed, e.g. with the declaration of accession, value >0
*/
SUBSCRIPTION,
/**
* shares terminated, e.g. when a membership is resigned, value <0
*/
CANCELLATION;
}

View File

@ -26,12 +26,14 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@DisplayName("Debitor")
public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
public static final String DEBITOR_NUMBER_TAG = "D-";
// TODO: I would rather like to generate something matching this example:
// debitor(1234500: Test AG, tes)
// maybe remove withSepararator (always use ', ') and add withBusinessIdProp (with ': ' afterwards)?
private static Stringify<HsOfficeDebitorEntity> stringify =
stringify(HsOfficeDebitorEntity.class, "debitor")
.withProp(HsOfficeDebitorEntity::getDebitorNumber)
.withProp(e -> DEBITOR_NUMBER_TAG + e.getDebitorNumber())
.withProp(HsOfficeDebitorEntity::getPartner)
.withProp(HsOfficeDebitorEntity::getDefaultPrefix)
.withSeparator(": ")
@ -75,18 +77,11 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
@Column(name = "defaultprefix", columnDefinition = "char(3) not null")
private String defaultPrefix;
public String getDebitorNumberString() {
// TODO: refactor
if (partner.getDebitorNumberPrefix() == null ) {
if (debitorNumberSuffix == null) {
return null;
}
return String.format("%02d", debitorNumberSuffix);
private String getDebitorNumberString() {
if (partner == null || partner.getPartnerNumber() == null || debitorNumberSuffix == null ) {
return null;
}
if (debitorNumberSuffix == null) {
return partner.getDebitorNumberPrefix() + "??";
}
return partner.getDebitorNumberPrefix() + String.format("%02d", debitorNumberSuffix);
return partner.getPartnerNumber() + String.format("%02d", debitorNumberSuffix);
}
public Integer getDebitorNumber() {
@ -100,6 +95,6 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
@Override
public String toShortString() {
return getDebitorNumberString();
return DEBITOR_NUMBER_TAG + getDebitorNumberString();
}
}

View File

@ -13,10 +13,10 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
@Query("""
SELECT debitor FROM HsOfficeDebitorEntity debitor
WHERE cast(debitor.partner.debitorNumberPrefix as integer) = :debitorNumberPrefix
WHERE cast(debitor.partner.partnerNumber as integer) = :partnerNumber
AND cast(debitor.debitorNumberSuffix as integer) = :debitorNumberSuffix
""")
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumberPrefix, byte debitorNumberSuffix);
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int partnerNumber, byte debitorNumberSuffix);
default List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
return findDebitorByDebitorNumber( debitorNumber/100, (byte) (debitorNumber%100));

View File

@ -44,8 +44,9 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
Integer memberNumber) {
context.define(currentUser, assumedRoles);
final var entities =
membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(partnerUuid, memberNumber);
final var entities = ( memberNumber != null)
? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber))
: membershipRepo.findMembershipsByOptionalPartnerUuid(partnerUuid);
final var resources = mapper.mapList(entities, HsOfficeMembershipResource.class,
SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER);

View File

@ -30,8 +30,10 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@DisplayName("Membership")
public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
public static final String MEMBER_NUMBER_TAG = "M-";
private static Stringify<HsOfficeMembershipEntity> stringify = stringify(HsOfficeMembershipEntity.class)
.withProp(HsOfficeMembershipEntity::getMemberNumber)
.withProp(e -> MEMBER_NUMBER_TAG + e.getMemberNumber())
.withProp(e -> e.getPartner().toShortString())
.withProp(e -> e.getMainDebitor().toShortString())
.withProp(e -> e.getValidity().asString())
@ -52,8 +54,8 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
@JoinColumn(name = "maindebitoruuid")
private HsOfficeDebitorEntity mainDebitor;
@Column(name = "membernumber")
private int memberNumber; // TODO: migrate to suffix, like debitorNumberSuffix
@Column(name = "membernumbersuffix", length = 2)
private String memberNumberSuffix;
@Column(name = "validity", columnDefinition = "daterange")
@Type(PostgreSQLRangeType.class)
@ -82,14 +84,19 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
return upperInclusiveFromPostgresDateRange(getValidity());
}
public Range<LocalDate> getValidity() {
if (validity == null) {
validity = Range.infinite(LocalDate.class);
}
;
return validity;
}
public Integer getMemberNumber() {
if (partner == null || partner.getPartnerNumber() == null || memberNumberSuffix == null ) {
return null;
}
return getPartner().getPartnerNumber() * 100 + Integer.parseInt(memberNumberSuffix, 10);
}
@Override
public String toString() {
@ -98,7 +105,7 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
@Override
public String toShortString() {
return String.valueOf(memberNumber);
return "M-" + getMemberNumber();
}
@PrePersist

View File

@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -11,16 +12,30 @@ public interface HsOfficeMembershipRepository extends Repository<HsOfficeMembers
Optional<HsOfficeMembershipEntity> findByUuid(UUID id);
HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity);
@Query("""
SELECT membership FROM HsOfficeMembershipEntity membership
WHERE (:memberNumber is null OR membership.memberNumber = :memberNumber)
AND ( CAST(:partnerUuid as org.hibernate.type.UUIDCharType) IS NULL
OR membership.partner.uuid = :partnerUuid )
ORDER BY membership.memberNumber
WHERE ( CAST(:partnerUuid as org.hibernate.type.UUIDCharType) IS NULL
OR membership.partner.uuid = :partnerUuid )
ORDER BY membership.partner.partnerNumber, membership.memberNumberSuffix
""")
List<HsOfficeMembershipEntity> findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(UUID partnerUuid, Integer memberNumber);
HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity);
List<HsOfficeMembershipEntity> findMembershipsByOptionalPartnerUuid(UUID partnerUuid);
@Query("""
SELECT membership FROM HsOfficeMembershipEntity membership
WHERE (:partnerNumber = membership.partner.partnerNumber)
AND (membership.memberNumberSuffix = :suffix)
ORDER BY membership.memberNumberSuffix
""")
HsOfficeMembershipEntity findMembershipByPartnerNumberAndSuffix(
@NotNull Integer partnerNumber,
@NotNull String suffix);
default HsOfficeMembershipEntity findMembershipByMemberNumber(Integer memberNumber) {
final var partnerNumber = memberNumber / 100;
final var suffix = memberNumber % 100;
return findMembershipByPartnerNumberAndSuffix(partnerNumber, String.format("%02d", suffix));
}
long count();

View File

@ -36,8 +36,8 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
@GeneratedValue
private UUID uuid;
@Column(name = "debitornumberprefix", columnDefinition = "numeric(5) not null")
private Integer debitorNumberPrefix;
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
private Integer partnerNumber;
@ManyToOne
@JoinColumn(name = "personuuid", nullable = false)

View File

@ -23,6 +23,7 @@ public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEnt
OR person.familyName like concat(cast(:name as text), '%')
""")
List<HsOfficePartnerEntity> findPartnerByOptionalNameLike(String name);
HsOfficePartnerEntity findPartnerByPartnerNumber(Integer partnerNumber);
HsOfficePartnerEntity save(final HsOfficePartnerEntity entity);