1
0

add hs-office-membership entity+repo + fix rbac

This commit is contained in:
Michael Hoennig
2022-10-17 19:42:14 +02:00
parent 28bdd9220d
commit e6f9484f99
10 changed files with 662 additions and 10 deletions

View File

@@ -0,0 +1,88 @@
package net.hostsharing.hsadminng.hs.office.membership;
import com.vladmihalcea.hibernate.type.basic.PostgreSQLEnumType;
import com.vladmihalcea.hibernate.type.range.PostgreSQLRangeType;
import com.vladmihalcea.hibernate.type.range.Range;
import lombok.*;
import net.hostsharing.hsadminng.Stringify;
import net.hostsharing.hsadminng.Stringifyable;
import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import java.time.LocalDate;
import java.util.UUID;
import static net.hostsharing.hsadminng.Stringify.stringify;
@Entity
@Table(name = "hs_office_membership_rv")
@TypeDef(
name = "pgsql_enum",
typeClass = PostgreSQLEnumType.class
)
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DisplayName("Membership")
@TypeDef(
typeClass = PostgreSQLRangeType.class,
defaultForType = Range.class
)
public class HsOfficeMembershipEntity implements Stringifyable {
private static Stringify<HsOfficeMembershipEntity> stringify = stringify(HsOfficeMembershipEntity.class)
.withProp(HsOfficeMembershipEntity::getMemberNumber)
.withProp(e -> e.getPartner().toShortString())
.withProp(e -> e.getMainDebitor().toShortString())
.withProp(e -> e.getValidity().asString())
.withProp(HsOfficeMembershipEntity::getReasonForTermination)
.withSeparator(", ")
.quotedValues(false);
private @Id UUID uuid;
@ManyToOne
@JoinColumn(name = "partneruuid")
private HsOfficePartnerEntity partner;
@ManyToOne
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "maindebitoruuid")
private HsOfficeDebitorEntity mainDebitor;
@Column(name = "membernumber")
private int memberNumber;
@Column(name = "validity", columnDefinition = "daterange")
private Range<LocalDate> validity;
@Column(name = "reasonfortermination")
@Enumerated(EnumType.STRING)
@Type(type = "pgsql_enum")
private HsOfficeReasonForTermination reasonForTermination;
@Override
public String toString() {
return stringify.apply(this);
}
@Override
public String toShortString() {
return String.valueOf(memberNumber);
}
@PrePersist
void init() {
if (getReasonForTermination() == null) {
setReasonForTermination(HsOfficeReasonForTermination.NONE);
}
}
}

View File

@@ -0,0 +1,29 @@
package net.hostsharing.hsadminng.hs.office.membership;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsOfficeMembershipRepository extends Repository<HsOfficeMembershipEntity, UUID> {
Optional<HsOfficeMembershipEntity> findByUuid(UUID id);
@Query("""
SELECT membership FROM HsOfficeMembershipEntity membership
WHERE :memberNumber is null
OR membership.memberNumber = :memberNumber
ORDER BY membership.memberNumber
""")
List<HsOfficeMembershipEntity> findMembershipByOptionalMemberNumber(Integer memberNumber);
List<HsOfficeMembershipEntity> findMembershipsByPartnerUuid(UUID partnerUuid);
HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity);
long count();
int deleteByUuid(UUID uuid);
}

View File

@@ -0,0 +1,5 @@
package net.hostsharing.hsadminng.hs.office.membership;
public enum HsOfficeReasonForTermination {
NONE, CANCELLATION, TRANSFER, DEATH, LIQUIDATION, EXPULSION;
}

View File

@@ -15,7 +15,7 @@ create table if not exists hs_office_membership
mainDebitorUuid uuid not null references hs_office_debitor(uuid),
memberNumber numeric(5) not null,
validity daterange not null,
reasonForTermination HsOfficeReasonForTermination not null
reasonForTermination HsOfficeReasonForTermination not null default 'NONE'
);
--//

View File

@@ -51,11 +51,13 @@ subgraph hsOfficeMembership
role:hsOfficeDebitor.admin --> role:hsOfficeMembership.agent
%% outgoing
role:hsOfficeMembership.agent --> role:hsOfficePartner.tenant
role:hsOfficeMembership.admin --> role:hsOfficeDebitor.tenant
role:hsOfficeMembership.agent --> role:hsOfficeDebitor.tenant
role:hsOfficeMembership.tenant[membership.tenant]
%% incoming
role:hsOfficeMembership.agent --> role:hsOfficeMembership.tenant
role:hsOfficePartner.agent --> role:hsOfficeMembership.tenant
role:hsOfficeDebitor.agent --> role:hsOfficeMembership.tenant
%% outgoing
role:hsOfficeMembership.tenant --> role:hsOfficePartner.guest
role:hsOfficeMembership.tenant --> role:hsOfficeDebitor.guest
@@ -65,6 +67,8 @@ subgraph hsOfficeMembership
role:hsOfficeMembership.guest --> perm:hsOfficeMembership.view{{membership.view}}
%% incoming
role:hsOfficeMembership.tenant --> role:hsOfficeMembership.guest
role:hsOfficePartner.tenant --> role:hsOfficeMembership.guest
role:hsOfficeDebitor.tenant --> role:hsOfficeMembership.guest
end

View File

@@ -47,26 +47,25 @@ begin
perform createRoleWithGrants(
hsOfficeMembershipAdmin(NEW),
permissions => array['edit'],
incomingSuperRoles => array[hsOfficeMembershipOwner(NEW)],
outgoingSubRoles => array[hsOfficeDebitorTenant(newHsOfficeDebitor)]
incomingSuperRoles => array[hsOfficeMembershipOwner(NEW)]
);
perform createRoleWithGrants(
hsOfficeMembershipAgent(NEW),
incomingSuperRoles => array[hsOfficeMembershipAdmin(NEW), hsOfficePartnerAdmin(newHsOfficePartner), hsOfficeDebitorAdmin(newHsOfficeDebitor)],
outgoingSubRoles => array[hsOfficePartnerTenant(newHsOfficePartner)]
outgoingSubRoles => array[hsOfficePartnerTenant(newHsOfficePartner), hsOfficeDebitorTenant(newHsOfficeDebitor)]
);
perform createRoleWithGrants(
hsOfficeMembershipTenant(NEW),
incomingSuperRoles => array[hsOfficeMembershipAgent(NEW)],
incomingSuperRoles => array[hsOfficeMembershipAgent(NEW), hsOfficePartnerAgent(newHsOfficePartner), hsOfficeDebitorAgent(newHsOfficeDebitor)],
outgoingSubRoles => array[hsOfficePartnerGuest(newHsOfficePartner), hsOfficeDebitorGuest(newHsOfficeDebitor)]
);
perform createRoleWithGrants(
hsOfficeMembershipGuest(NEW),
permissions => array['view'],
incomingSuperRoles => array[hsOfficeMembershipTenant(NEW)]
incomingSuperRoles => array[hsOfficeMembershipTenant(NEW), hsOfficePartnerTenant(newHsOfficePartner), hsOfficeDebitorTenant(newHsOfficeDebitor)]
);
-- === END of code generated from Mermaid flowchart. ===

View File

@@ -18,7 +18,7 @@ declare
newMemberNumber numeric;
begin
idName := cleanIdentifier( forPartnerTradeName || '#' || forMainDebitorNumber);
currentTask := 'creating SEPA-mandate test-data ' || idName;
currentTask := 'creating Membership test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
execute format('set local hsadminng.currentTask to %L', currentTask);
@@ -28,7 +28,7 @@ begin
select d.* from hs_office_debitor d where d.debitorNumber = forMainDebitorNumber into relatedDebitor;
select coalesce(max(memberNumber)+1, 10001) from hs_office_membership into newMemberNumber;
raise notice 'creating test SEPA-mandate: %', idName;
raise notice 'creating test Membership: %', idName;
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
insert