1
0

introduce-partner-business-role (#16)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/16
Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-02-01 14:48:15 +01:00
parent 188cb9733e
commit 2c0101b46d
72 changed files with 1666 additions and 930 deletions

View File

@ -96,6 +96,8 @@ components:
format: int8
minimum: 10000
maximum: 99999
partnerRole:
$ref: '#/components/schemas/HsOfficePartnerRoleInsert'
personUuid:
type: string
format: uuid
@ -110,6 +112,24 @@ components:
- contactUuid
- details
HsOfficePartnerRoleInsert:
type: object
nullable: false
properties:
relAnchorUuid:
type: string
format: uuid
relHolderUuid:
type: string
format: uuid
contactUuid:
type: string
format: uuid
required:
- relAnchorUuid
- relHolderUuid
- relContactUuid
HsOfficePartnerDetailsInsert:
type: object
nullable: false

View File

@ -7,6 +7,7 @@ components:
type: string
enum:
- UNKNOWN
- PARTNER
- EX_PARTNER
- REPRESENTATIVE,
- VIP_CONTACT
@ -61,3 +62,4 @@ components:
- relAnchorUuid
- relHolderUuid
- relType
- relContactUuid

View File

@ -53,6 +53,19 @@ create table tx_journal
create index on tx_journal (targetTable, targetUuid);
--//
-- ============================================================================
--changeset audit-TX-JOURNAL-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
A view combining tx_journal with tx_context.
*/
create view tx_journal_v as
select txc.*, txj.targettable, txj.targetop, txj.targetuuid, txj.targetdelta
from tx_journal txj
left join tx_context txc using (contextid)
order by txc.txtimestamp;
--//
-- ============================================================================
--changeset audit-TX-JOURNAL-TRIGGER:1 endDelimiter:--//
-- ----------------------------------------------------------------------------

View File

@ -120,6 +120,7 @@ $$;
create table RbacObject
(
uuid uuid primary key default uuid_generate_v4(),
serialId serial, -- TODO: we might want to remove this once test data deletion works properly
objectTable varchar(64) not null,
unique (objectTable, uuid)
);

View File

@ -61,7 +61,7 @@ do language plpgsql $$
call createHsOfficeContactTestData('first contact');
call createHsOfficeContactTestData('second contact');
call createHsOfficeContactTestData('third contact');
call createHsOfficeContactTestData('forth contact');
call createHsOfficeContactTestData('fourth contact');
call createHsOfficeContactTestData('fifth contact');
call createHsOfficeContactTestData('sixth contact');
call createHsOfficeContactTestData('seventh contact');

View File

@ -46,7 +46,7 @@ create or replace procedure createTestPersonTestData(
begin
for t in startCount..endCount
loop
call createHsOfficePersonTestData('LEGAL', intToVarChar(t, 4));
call createHsOfficePersonTestData('LP', intToVarChar(t, 4));
commit;
end loop;
end; $$;
@ -59,11 +59,15 @@ end; $$;
do language plpgsql $$
begin
call createHsOfficePersonTestData('LP', 'Hostsharing eG');
call createHsOfficePersonTestData('LP', 'First GmbH');
call createHsOfficePersonTestData('NP', null, 'Firby', 'Susan');
call createHsOfficePersonTestData('NP', null, 'Smith', 'Peter');
call createHsOfficePersonTestData('LP', 'Second e.K.', 'Sandra', 'Miller');
call createHsOfficePersonTestData('NP', null, 'Tucker', 'Jack');
call createHsOfficePersonTestData('NP', null, 'Fouler', 'Ellie');
call createHsOfficePersonTestData('LP', 'Second e.K.', 'Smith', 'Peter');
call createHsOfficePersonTestData('IF', 'Third OHG');
call createHsOfficePersonTestData('IF', 'Fourth e.G.');
call createHsOfficePersonTestData('IF', 'Fourth eG');
call createHsOfficePersonTestData('UF', 'Erben Bessler', 'Mel', 'Bessler');
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Anita');
call createHsOfficePersonTestData('NP', null, 'Winkler', 'Paul');

View File

@ -6,6 +6,7 @@
CREATE TYPE HsOfficeRelationshipType AS ENUM (
'UNKNOWN',
'PARTNER',
'EX_PARTNER',
'REPRESENTATIVE',
'VIP_CONTACT',

View File

@ -9,9 +9,9 @@
Creates a single relationship test record.
*/
create or replace procedure createHsOfficeRelationshipTestData(
anchorPersonTradeName varchar,
holderPersonFamilyName varchar,
holderPersonName varchar,
relationshipType HsOfficeRelationshipType,
anchorPersonTradeName varchar,
contactLabel varchar,
mark varchar default null)
language plpgsql as $$
@ -23,14 +23,27 @@ declare
contact hs_office_contact;
begin
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonFamilyName);
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonName);
currentTask := 'creating relationship test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
execute format('set local hsadminng.currentTask to %L', currentTask);
select p.* from hs_office_person p where p.tradeName = anchorPersonTradeName into anchorPerson;
select p.* from hs_office_person p where p.familyName = holderPersonFamilyName into holderPerson;
if anchorPerson is null then
raise exception 'anchorPerson "%" not found', anchorPersonTradeName;
end if;
select p.* from hs_office_person p
where p.tradeName = holderPersonName or p.familyName = holderPersonName
into holderPerson;
if holderPerson is null then
raise exception 'holderPerson "%" not found', holderPersonName;
end if;
select c.* from hs_office_contact c where c.label = contactLabel into contact;
if contact is null then
raise exception 'contact "%" not found', contactLabel;
end if;
raise notice 'creating test relationship: %', idName;
raise notice '- using anchor person (%): %', anchorPerson.uuid, anchorPerson;
@ -72,13 +85,20 @@ end; $$;
do language plpgsql $$
begin
call createHsOfficeRelationshipTestData('First GmbH', 'Smith', 'REPRESENTATIVE', 'first contact');
call createHsOfficeRelationshipTestData('First GmbH', 'PARTNER', 'Hostsharing eG', 'first contact');
call createHsOfficeRelationshipTestData('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
call createHsOfficeRelationshipTestData('Second e.K.', 'Smith', 'REPRESENTATIVE', 'second contact');
call createHsOfficeRelationshipTestData('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
call createHsOfficeRelationshipTestData('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'REPRESENTATIVE', 'third contact');
call createHsOfficeRelationshipTestData('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
call createHsOfficeRelationshipTestData('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
call createHsOfficeRelationshipTestData('Third OHG', 'Smith', 'SUBSCRIBER', 'third contact', 'members-announce');
call createHsOfficeRelationshipTestData('Fourth eG', 'PARTNER', 'Hostsharing eG', 'fourth contact');
call createHsOfficeRelationshipTestData('Fouler', 'REPRESENTATIVE', 'Third OHG', 'third contact');
call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
call createHsOfficeRelationshipTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
end;
$$;
--//

View File

@ -32,14 +32,47 @@ call create_journal('hs_office_partner_details');
create table hs_office_partner
(
uuid uuid unique references RbacObject (uuid) initially deferred,
partnerNumber numeric(5),
personUuid uuid not null references hs_office_person(uuid),
contactUuid uuid not null references hs_office_contact(uuid),
detailsUuid uuid not null references hs_office_partner_details(uuid) on delete cascade
partnerNumber numeric(5) unique not null,
partnerRoleUuid uuid not null references hs_office_relationship(uuid), -- TODO: delete in after delete trigger
personUuid uuid not null references hs_office_person(uuid), -- TODO: remove, replaced by partnerRoleUuid
contactUuid uuid not null references hs_office_contact(uuid), -- TODO: remove, replaced by partnerRoleUuid
detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger
);
--//
-- ============================================================================
--changeset hs-office-partner-DELETE-DETAILS-TRIGGER:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Trigger function to delete related details of a partner to delete.
*/
create or replace function deleteHsOfficeDetailsOnPartnerDelete()
returns trigger
language PLPGSQL
as $$
declare
counter integer;
begin
DELETE FROM hs_office_partner_details d WHERE d.uuid = OLD.detailsUuid;
GET DIAGNOSTICS counter = ROW_COUNT;
if counter = 0 then
raise exception 'partner details % could not be deleted', OLD.detailsUuid;
end if;
RETURN OLD;
end; $$;
/**
Triggers deletion of related details of a partner to delete.
*/
create trigger hs_office_partner_delete_details_trigger
after delete
on hs_office_partner
for each row
execute procedure deleteHsOfficeDetailsOnPartnerDelete();
-- ============================================================================
--changeset hs-office-partner-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ----------------------------------------------------------------------------

View File

@ -27,12 +27,17 @@ create or replace function hsOfficePartnerRbacRolesTrigger()
language plpgsql
strict as $$
declare
oldPartnerRole hs_office_relationship;
newPartnerRole hs_office_relationship;
oldPerson hs_office_person;
newPerson hs_office_person;
oldContact hs_office_contact;
newContact hs_office_contact;
begin
select * from hs_office_relationship as r where r.uuid = NEW.partnerroleuuid into newPartnerRole;
select * from hs_office_person as p where p.uuid = NEW.personUuid into newPerson;
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
@ -52,6 +57,7 @@ begin
incomingSuperRoles => array[
hsOfficePartnerOwner(NEW)],
outgoingSubRoles => array[
hsOfficeRelationshipTenant(newPartnerRole),
hsOfficePersonTenant(newPerson),
hsOfficeContactTenant(newContact)]
);
@ -60,6 +66,7 @@ begin
hsOfficePartnerAgent(NEW),
incomingSuperRoles => array[
hsOfficePartnerAdmin(NEW),
hsOfficeRelationshipAdmin(newPartnerRole),
hsOfficePersonAdmin(newPerson),
hsOfficeContactAdmin(newContact)]
);
@ -69,6 +76,7 @@ begin
incomingSuperRoles => array[
hsOfficePartnerAgent(NEW)],
outgoingSubRoles => array[
hsOfficeRelationshipTenant(newPartnerRole),
hsOfficePersonGuest(newPerson),
hsOfficeContactGuest(newContact)]
);
@ -109,6 +117,19 @@ begin
elsif TG_OP = 'UPDATE' then
if OLD.partnerRoleUuid <> NEW.partnerRoleUuid then
select * from hs_office_relationship as r where r.uuid = OLD.partnerRoleUuid into oldPartnerRole;
call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRole), hsOfficePartnerAdmin(OLD));
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRole), hsOfficePartnerAdmin(NEW));
call revokeRoleFromRole(hsOfficePartnerAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRole));
call grantRoleToRole(hsOfficePartnerAgent(NEW), hsOfficeRelationshipAdmin(newPartnerRole));
call revokeRoleFromRole(hsOfficeRelationshipGuest(oldPartnerRole), hsOfficePartnerTenant(OLD));
call grantRoleToRole(hsOfficeRelationshipGuest(newPartnerRole), hsOfficePartnerTenant(NEW));
end if;
if OLD.personUuid <> NEW.personUuid then
select * from hs_office_person as p where p.uuid = OLD.personUuid into oldPerson;
@ -179,6 +200,7 @@ call generateRbacIdentityView('hs_office_partner', $idName$
call generateRbacRestrictedView('hs_office_partner',
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
$updates$
partnerRoleUuid = new.partnerRoleUuid,
personUuid = new.personUuid,
contactUuid = new.contactUuid
$updates$);
@ -189,7 +211,7 @@ call generateRbacRestrictedView('hs_office_partner',
--changeset hs-office-partner-rbac-NEW-PARTNER:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates a global permission for new-partner and assigns it to the hostsharing admins role.
Creates a global permission for new-partner and assigns it to the Hostsharing admins role.
*/
do language plpgsql $$
declare

View File

@ -9,30 +9,49 @@
Creates a single partner test record.
*/
create or replace procedure createHsOfficePartnerTestData(
mandantTradeName varchar,
partnerNumber numeric(5),
personTradeOrFamilyName varchar,
partnerPersonName varchar,
contactLabel varchar )
language plpgsql as $$
declare
currentTask varchar;
idName varchar;
mandantPerson hs_office_person;
partnerRole hs_office_relationship;
relatedPerson hs_office_person;
relatedContact hs_office_contact;
relatedDetailsUuid uuid;
begin
idName := cleanIdentifier( personTradeOrFamilyName|| '-' || contactLabel);
idName := cleanIdentifier( partnerPersonName|| '-' || contactLabel);
currentTask := 'creating partner test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
execute format('set local hsadminng.currentTask to %L', currentTask);
select p.* from hs_office_person p
where p.tradeName = personTradeOrFamilyName or p.familyName = personTradeOrFamilyName
where p.tradeName = mandantTradeName
into mandantPerson;
if mandantPerson is null then
raise exception 'mandant "%" not found', mandantTradeName;
end if;
select p.* from hs_office_person p
where p.tradeName = partnerPersonName or p.familyName = partnerPersonName
into relatedPerson;
select c.* from hs_office_contact c
where c.label = contactLabel
into relatedContact;
select r.* from hs_office_relationship r
where r.reltype = 'PARTNER'
and r.relanchoruuid = mandantPerson.uuid and r.relholderuuid = relatedPerson.uuid
into partnerRole;
if partnerRole is null then
raise exception 'partnerRole "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
end if;
raise notice 'creating test partner: %', idName;
raise notice '- using partnerRole (%): %', partnerRole.uuid, partnerRole;
raise notice '- using person (%): %', relatedPerson.uuid, relatedPerson;
raise notice '- using contact (%): %', relatedContact.uuid, relatedContact;
@ -44,13 +63,13 @@ begin
else
insert
into hs_office_partner_details (uuid, registrationOffice, registrationNumber)
values (uuid_generate_v4(), 'Hamburg', '12345')
values (uuid_generate_v4(), 'Hamburg', 'RegNo123456789')
returning uuid into relatedDetailsUuid;
end if;
insert
into hs_office_partner (uuid, partnerNumber, personuuid, contactuuid, detailsUuid)
values (uuid_generate_v4(), partnerNumber, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
into hs_office_partner (uuid, partnerNumber, partnerRoleUuid, personuuid, contactuuid, detailsUuid)
values (uuid_generate_v4(), partnerNumber, partnerRole.uuid, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
end; $$;
--//
@ -62,11 +81,11 @@ end; $$;
do language plpgsql $$
begin
call createHsOfficePartnerTestData(10001, 'First GmbH', 'first contact');
call createHsOfficePartnerTestData(10002, 'Second e.K.', 'second contact');
call createHsOfficePartnerTestData(10003, 'Third OHG', 'third contact');
call createHsOfficePartnerTestData(10004, 'Fourth e.G.', 'forth contact');
call createHsOfficePartnerTestData(10010, 'Smith', 'fifth contact');
call createHsOfficePartnerTestData('Hostsharing eG', 10001, 'First GmbH', 'first contact');
call createHsOfficePartnerTestData('Hostsharing eG', 10002, 'Second e.K.', 'second contact');
call createHsOfficePartnerTestData('Hostsharing eG', 10003, 'Third OHG', 'third contact');
call createHsOfficePartnerTestData('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact');
call createHsOfficePartnerTestData('Hostsharing eG', 10010, 'Smith', 'fifth contact');
end;
$$;
--//

View File

@ -41,7 +41,7 @@ do language plpgsql $$
call createHsOfficeBankAccountTestData('Peter Smith', 'DE02500105170137075030', 'INGDDEFF');
call createHsOfficeBankAccountTestData('Second e.K.', 'DE02100500000054540402', 'BELADEBE');
call createHsOfficeBankAccountTestData('Third OHG', 'DE02300209000106531065', 'CMCIDEDD');
call createHsOfficeBankAccountTestData('Fourth e.G.', 'DE02200505501015871393', 'HASPDEHH');
call createHsOfficeBankAccountTestData('Fourth eG', 'DE02200505501015871393', 'HASPDEHH');
call createHsOfficeBankAccountTestData('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');
call createHsOfficeBankAccountTestData('Anita Bessler', 'DE02300606010002474689', 'DAAEDEDD');
call createHsOfficeBankAccountTestData('Paul Winkler', 'DE02600501010002034304', 'SOLADEST600');

View File

@ -66,21 +66,21 @@ databaseChangeLog:
- include:
file: db/changelog/218-hs-office-person-test-data.sql
- include:
file: db/changelog/220-hs-office-partner.sql
file: db/changelog/220-hs-office-relationship.sql
- include:
file: db/changelog/223-hs-office-partner-rbac.sql
file: db/changelog/223-hs-office-relationship-rbac.sql
- include:
file: db/changelog/224-hs-office-partner-details-rbac.sql
file: db/changelog/228-hs-office-relationship-test-data.sql
- include:
file: db/changelog/226-hs-office-partner-migration.sql
file: db/changelog/230-hs-office-partner.sql
- include:
file: db/changelog/228-hs-office-partner-test-data.sql
file: db/changelog/233-hs-office-partner-rbac.sql
- include:
file: db/changelog/230-hs-office-relationship.sql
file: db/changelog/234-hs-office-partner-details-rbac.sql
- include:
file: db/changelog/233-hs-office-relationship-rbac.sql
file: db/changelog/236-hs-office-partner-migration.sql
- include:
file: db/changelog/238-hs-office-relationship-test-data.sql
file: db/changelog/238-hs-office-partner-test-data.sql
- include:
file: db/changelog/240-hs-office-bankaccount.sql
- include: