Compare commits

..

2 Commits

Author SHA1 Message Date
Michael Hoennig
ecc91592b0 amend string representations in ImportOfficeData to new toString/toShortString implementations 2024-02-08 14:05:56 +01:00
Michael Hoennig
3261e92b2c remove partner roles and amend grants accordingly 2024-02-08 13:28:13 +01:00
7 changed files with 158 additions and 132 deletions

View File

@ -397,6 +397,7 @@ select exists(
); );
$$; $$;
-- TODO: the array parameter and thus the array return value is only used in toPermissionUuids, simplify to non-arrays
create or replace function createPermissions(forObjectUuid uuid, permitOps RbacOp[]) create or replace function createPermissions(forObjectUuid uuid, permitOps RbacOp[])
returns uuid[] returns uuid[]
language plpgsql as $$ language plpgsql as $$
@ -668,6 +669,26 @@ begin
end if; end if;
end; $$; end; $$;
create or replace procedure revokePermissionFromRole(permission RbacRoleDescriptor, superRole RbacRoleDescriptor)
language plpgsql as $$
declare
superRoleId uuid;
subRoleId uuid;
begin
superRoleId := findRoleId(superRole);
subRoleId := findRoleId(subRole);
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
if (isGranted(superRoleId, subRoleId)) then
delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId;
else
raise exception 'cannot revoke role % (%) from % (% because it is not granted',
subRole, subRoleId, superRole, superRoleId;
end if;
end; $$;
-- ============================================================================ -- ============================================================================
--changeset rbac-base-QUERY-ACCESSIBLE-OBJECT-UUIDS:1 endDelimiter:--// --changeset rbac-base-QUERY-ACCESSIBLE-OBJECT-UUIDS:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------

View File

@ -74,6 +74,7 @@ begin
return roleDescriptor('%2$s', entity.uuid, 'tenant'); return roleDescriptor('%2$s', entity.uuid, 'tenant');
end; $f$; end; $f$;
-- TODO: remove guest role
create or replace function %1$sGuest(entity %2$s) create or replace function %1$sGuest(entity %2$s)
returns RbacRoleDescriptor returns RbacRoleDescriptor
language plpgsql language plpgsql
@ -82,6 +83,14 @@ begin
return roleDescriptor('%2$s', entity.uuid, 'guest'); return roleDescriptor('%2$s', entity.uuid, 'guest');
end; $f$; end; $f$;
create or replace function %1$sReferrer(entity %2$s)
returns RbacRoleDescriptor
language plpgsql
strict as $f$
begin
return roleDescriptor('%2$s', entity.uuid, 'referrer');
end; $f$;
$sql$, prefix, targetTable); $sql$, prefix, targetTable);
execute sql; execute sql;
end; $$; end; $$;

View File

@ -7,13 +7,6 @@ call generateRelatedRbacObject('hs_office_partner');
--// --//
-- ============================================================================
--changeset hs-office-partner-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacRoleDescriptors('hsOfficePartner', 'hs_office_partner');
--//
-- ============================================================================ -- ============================================================================
--changeset hs-office-partner-rbac-ROLES-CREATION:1 endDelimiter:--// --changeset hs-office-partner-rbac-ROLES-CREATION:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
@ -35,70 +28,40 @@ begin
if TG_OP = 'INSERT' then if TG_OP = 'INSERT' then
-- === ATTENTION: code generated from related Mermaid flowchart: === -- Permissions and Grants for Partner
perform createRoleWithGrants(
hsOfficePartnerOwner(NEW),
permissions => array['*'],
incomingSuperRoles => array[globalAdmin()],
outgoingSubRoles => array[
hsOfficeRelationshipOwner(newPartnerRole)]
);
perform createRoleWithGrants(
hsOfficePartnerAdmin(NEW),
permissions => array['edit'],
incomingSuperRoles => array[
hsOfficePartnerOwner(NEW)],
outgoingSubRoles => array[
hsOfficeRelationshipAdmin(newPartnerRole)]
);
perform createRoleWithGrants(
hsOfficePartnerAgent(NEW),
incomingSuperRoles => array[
hsOfficePartnerAdmin(NEW),
hsOfficeRelationshipAgent(newPartnerRole)]
);
perform createRoleWithGrants(
hsOfficePartnerTenant(NEW),
incomingSuperRoles => array[
hsOfficePartnerAgent(NEW)],
outgoingSubRoles => array[
hsOfficeRelationshipTenant(newPartnerRole)]
);
perform createRoleWithGrants(
hsOfficePartnerGuest(NEW),
permissions => array['view'],
incomingSuperRoles => array[hsOfficePartnerTenant(NEW)]
);
-- === END of code generated from Mermaid flowchart. ===
-- Each partner-details entity belong exactly to one partner entity
-- and it makes little sense just to delegate partner-details roles.
-- Therefore, we did not model partner-details roles,
-- but instead just assign extra permissions to existing partner-roles.
--Attention: Cannot be in partner-details because of insert order (partner is not in database yet)
call grantPermissionsToRole( call grantPermissionsToRole(
getRoleId(hsOfficePartnerOwner(NEW), 'fail'), getRoleId(hsOfficeRelationshipOwner(newPartnerRole), 'fail'),
createPermissions(NEW.uuid, array ['*'])
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipAdmin(newPartnerRole), 'fail'),
createPermissions(NEW.uuid, array ['edit'])
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipTenant(newPartnerRole), 'fail'),
createPermissions(NEW.uuid, array ['view'])
);
-- Permissions and Grants for PartnerDetails
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipOwner(newPartnerRole), 'fail'),
createPermissions(NEW.detailsUuid, array ['*']) createPermissions(NEW.detailsUuid, array ['*'])
); );
call grantPermissionsToRole( call grantPermissionsToRole(
getRoleId(hsOfficePartnerAdmin(NEW), 'fail'), getRoleId(hsOfficeRelationshipAdmin(newPartnerRole), 'fail'),
createPermissions(NEW.detailsUuid, array ['edit']) createPermissions(NEW.detailsUuid, array ['edit'])
); );
call grantPermissionsToRole( call grantPermissionsToRole(
-- Yes, here hsOfficePartnerAGENT is used, not hsOfficePartnerTENANT. -- Yes, here hsOfficePartnerAGENT is used, not hsOfficeRelationshipTENANT.
-- Do NOT grant view permission on partner-details to hsOfficePartnerTENANT! -- Do NOT grant view permission on partner-details to hsOfficeRelationshipTENANT!
-- Otherwise package-admins etc. would be able to read the data. -- Otherwise package-admins etc. would be able to read the data.
getRoleId(hsOfficePartnerAgent(NEW), 'fail'), getRoleId(hsOfficeRelationshipAgent(newPartnerRole), 'fail'),
createPermissions(NEW.detailsUuid, array ['view']) createPermissions(NEW.detailsUuid, array ['view'])
); );
@ -108,14 +71,47 @@ begin
if OLD.partnerRoleUuid <> NEW.partnerRoleUuid then if OLD.partnerRoleUuid <> NEW.partnerRoleUuid then
select * from hs_office_relationship as r where r.uuid = OLD.partnerRoleUuid into oldPartnerRole; select * from hs_office_relationship as r where r.uuid = OLD.partnerRoleUuid into oldPartnerRole;
call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRole), hsOfficePartnerAdmin(OLD)); -- Revoke all Permissions from old partner relationship
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRole), hsOfficePartnerAdmin(NEW)); -- TODO: introduce call revokeAllPermissionsOnDescendantFromAllRolesOfAscendant(OLD, oldPartnerRole);
delete from rbacGrants where descendantUuid==OLD.uuid and ascendantUuid==OLD.partnerRoleUuid;
call revokeRoleFromRole(hsOfficePartnerAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRole)); -- Grants for Partner
call grantRoleToRole(hsOfficePartnerAgent(NEW), hsOfficeRelationshipAdmin(newPartnerRole));
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipOwner(newPartnerRole), 'fail'),
array[findPermissionId(NEW.uuid, '*')]
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipAdmin(newPartnerRole), 'fail'),
array[findPermissionId(NEW.uuid, 'edit')]
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipTenant(newPartnerRole), 'fail'),
array[findPermissionId(NEW.uuid, 'view')]
);
-- Grants for PartnerDetails
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipOwner(newPartnerRole), 'fail'),
array[findPermissionId(NEW.detailsUuid, '*')]
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipAdmin(newPartnerRole), 'fail'),
array[findPermissionId(NEW.detailsUuid, array ['edit'])]
);
call grantPermissionsToRole(
-- Yes, here hsOfficePartnerAGENT is used, not hsOfficePartnerTENANT.
-- Do NOT grant view permission on partner-details to hsOfficeRelationshipTENANT!
-- Otherwise package-admins etc. would be able to read the data.
getRoleId(hsOfficeRelationshipAgent(newPartnerRole), 'fail'),
array[findPermissionId(NEW.detailsUuid, 'view')]
);
call revokeRoleFromRole(hsOfficeRelationshipGuest(oldPartnerRole), hsOfficePartnerTenant(OLD));
call grantRoleToRole(hsOfficeRelationshipGuest(newPartnerRole), hsOfficePartnerTenant(NEW));
end if; end if;
else else

View File

@ -3,22 +3,6 @@
```mermaid ```mermaid
flowchart TB flowchart TB
subgraph bank[ ]
style bank fill:#fff
subgraph refundBankAccount
direction TB
style refundBankAccount fill:#eee
role:refundBankAccount.owner[bankAccount.owner]
--> role:refundBankAccount.admin[bankAccount.admin]
--> role:refundBankAccount.referrer[bankAccount.referrer]
end
end
subgraph partner[ ]
style partner fill:#fff
subgraph partnerRelationship[hsOfficeRelationship:PARTNER] subgraph partnerRelationship[hsOfficeRelationship:PARTNER]
direction TB direction TB
style partnerRelationship fill:#eee style partnerRelationship fill:#eee
@ -28,15 +12,25 @@ subgraph partner[ ]
--> role:partnerRelationship.agent[relationship.agent] --> role:partnerRelationship.agent[relationship.agent]
--> role:partnerRelationship.tenant[relationship.tenant] --> role:partnerRelationship.tenant[relationship.tenant]
partnerPerson[e.g. partnerPerson.admin] --> role:partnerRelationship.agent partnerPersonAdmin>e.g. partnerPerson.admin] --> role:partnerRelationship.agent
otherPerson[e.g. operationalPerson.admin] --> role:partnerRelationship.tenant otherPersonAdmin>e.g. operationalPerson.admin] --> role:partnerRelationship.tenant
end role:partnerRelationship.tenant --> partnerPersonReferrer>e.g. partnerPerson.referrer]
end end
subgraph internal[ ] subgraph internal[ ]
direction TB direction TB
style internal fill:#fff style internal fill:#fff
subgraph refundBankAccount
direction TB
style refundBankAccount fill:#eee
role:refundBankAccount.owner[bankAccount.owner]
--> role:refundBankAccount.admin[bankAccount.admin]
--> role:refundBankAccount.referrer[bankAccount.referrer]
end
subgraph debitorRelationship[hsOfficeRelationship:DEBITOR] subgraph debitorRelationship[hsOfficeRelationship:DEBITOR]
direction TB direction TB
style debitorRelationship fill:#eee style debitorRelationship fill:#eee
@ -56,7 +50,7 @@ subgraph internal[ ]
role:debitorRelationship.admin[debitorRelationship.admin] role:debitorRelationship.admin[debitorRelationship.admin]
%% permissions %% permissions
==> perm:debitor.edit{{debitorRelationship.edit}} ==> perm:debitor.edit{{debitor.edit}}
%% incoming %% incoming
role:partnerRelationship.admin ==> role:debitorRelationship.admin role:partnerRelationship.admin ==> role:debitorRelationship.admin
%% outgoing %% outgoing

View File

@ -30,6 +30,8 @@ declare
hsOfficeDebitorTenant RbacRoleDescriptor; hsOfficeDebitorTenant RbacRoleDescriptor;
oldPartner hs_office_partner; oldPartner hs_office_partner;
newPartner hs_office_partner; newPartner hs_office_partner;
oldPartnerRel hs_office_relationship;
newPartnerRel hs_office_relationship;
oldContact hs_office_contact; oldContact hs_office_contact;
newContact hs_office_contact; newContact hs_office_contact;
newBankAccount hs_office_bankaccount; newBankAccount hs_office_bankaccount;
@ -39,10 +41,11 @@ begin
hsOfficeDebitorTenant := hsOfficeDebitorTenant(NEW); hsOfficeDebitorTenant := hsOfficeDebitorTenant(NEW);
select * from hs_office_partner as p where p.uuid = NEW.partnerUuid into newPartner; select * from hs_office_partner as p where p.uuid = NEW.partnerUuid into newPartner;
select * from hs_office_relationship as r where r.relType = 'PARTNER' and r.relHolderUuid = NEW.partnerUuid into newPartnerRel;
select * from hs_office_contact as c where c.uuid = NEW.billingContactUuid into newContact; select * from hs_office_contact as c where c.uuid = NEW.billingContactUuid into newContact;
select * from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid into newBankAccount; select * from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid into newBankAccount;
if TG_OP = 'INSERT' then
if TG_OP = 'INSERT' then
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeDebitorOwner(NEW), hsOfficeDebitorOwner(NEW),
@ -62,7 +65,7 @@ begin
hsOfficeDebitorAgent(NEW), hsOfficeDebitorAgent(NEW),
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeDebitorAdmin(NEW), hsOfficeDebitorAdmin(NEW),
hsOfficePartnerAdmin(newPartner), hsOfficeRelationshipAdmin(newPartnerRel),
hsOfficeContactAdmin(newContact)], hsOfficeContactAdmin(newContact)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeBankAccountTenant(newBankaccount)] hsOfficeBankAccountTenant(newBankaccount)]
@ -72,10 +75,10 @@ begin
hsOfficeDebitorTenant(NEW), hsOfficeDebitorTenant(NEW),
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeDebitorAgent(NEW), hsOfficeDebitorAgent(NEW),
hsOfficePartnerAgent(newPartner), hsOfficeRelationshipAgent(newPartnerRel),
hsOfficeBankAccountAdmin(newBankaccount)], hsOfficeBankAccountAdmin(newBankaccount)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficePartnerTenant(newPartner), hsOfficeRelationshipTenant(newPartnerRel),
hsOfficeContactGuest(newContact), hsOfficeContactGuest(newContact),
hsOfficeBankAccountGuest(newBankaccount)] hsOfficeBankAccountGuest(newBankaccount)]
); );
@ -91,15 +94,16 @@ begin
if OLD.partnerUuid <> NEW.partnerUuid then if OLD.partnerUuid <> NEW.partnerUuid then
select * from hs_office_partner as p where p.uuid = OLD.partnerUuid into oldPartner; select * from hs_office_partner as p where p.uuid = OLD.partnerUuid into oldPartner;
select * from hs_office_relationship as r where r.uuid = OLD.partnerUuid into oldPartnerRel;
call revokeRoleFromRole(hsOfficeDebitorAgent(OLD), hsOfficePartnerAdmin(oldPartner)); call revokeRoleFromRole(hsOfficeDebitorAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRel));
call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficePartnerAdmin(newPartner)); call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficeRelationshipAdmin(oldPartnerRel));
call revokeRoleFromRole(hsOfficeDebitorTenant(OLD), hsOfficePartnerAgent(oldPartner)); call revokeRoleFromRole(hsOfficeDebitorTenant(OLD), hsOfficeRelationshipAgent(oldPartnerRel));
call grantRoleToRole(hsOfficeDebitorTenant(NEW), hsOfficePartnerAgent(newPartner)); call grantRoleToRole(hsOfficeDebitorTenant(NEW), hsOfficeRelationshipAgent(newPartner));
call revokeRoleFromRole(hsOfficePartnerTenant(oldPartner), hsOfficeDebitorTenant(OLD)); call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRel), hsOfficeDebitorTenant(OLD));
call grantRoleToRole(hsOfficePartnerTenant(newPartner), hsOfficeDebitorTenant(NEW)); call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeDebitorTenant(NEW));
end if; end if;
if OLD.billingContactUuid <> NEW.billingContactUuid then if OLD.billingContactUuid <> NEW.billingContactUuid then

View File

@ -28,10 +28,12 @@ create or replace function hsOfficeMembershipRbacRolesTrigger()
strict as $$ strict as $$
declare declare
newHsOfficePartner hs_office_partner; newHsOfficePartner hs_office_partner;
newHsOfficePartnerRel hs_office_relationship;
newHsOfficeDebitor hs_office_debitor; newHsOfficeDebitor hs_office_debitor;
begin begin
select * from hs_office_partner as p where p.uuid = NEW.partnerUuid into newHsOfficePartner; select * from hs_office_partner as p where p.uuid = NEW.partnerUuid into newHsOfficePartner;
select * from hs_office_relationship as r where r.relType = 'PARTNER' and r.relHolderUuid = NEW.partnerUuid into newHsOfficePartnerRel;
select * from hs_office_debitor as c where c.uuid = NEW.mainDebitorUuid into newHsOfficeDebitor; select * from hs_office_debitor as c where c.uuid = NEW.mainDebitorUuid into newHsOfficeDebitor;
if TG_OP = 'INSERT' then if TG_OP = 'INSERT' then
@ -52,20 +54,20 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipAgent(NEW), hsOfficeMembershipAgent(NEW),
incomingSuperRoles => array[hsOfficeMembershipAdmin(NEW), hsOfficePartnerAdmin(newHsOfficePartner), hsOfficeDebitorAdmin(newHsOfficeDebitor)], incomingSuperRoles => array[hsOfficeMembershipAdmin(NEW), hsOfficeRelationshipAdmin(newHsOfficePartnerRel), hsOfficeDebitorAdmin(newHsOfficeDebitor)],
outgoingSubRoles => array[hsOfficePartnerTenant(newHsOfficePartner), hsOfficeDebitorTenant(newHsOfficeDebitor)] outgoingSubRoles => array[hsOfficeRelationshipTenant(newHsOfficePartnerRel), hsOfficeDebitorTenant(newHsOfficeDebitor)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipTenant(NEW), hsOfficeMembershipTenant(NEW),
incomingSuperRoles => array[hsOfficeMembershipAgent(NEW), hsOfficePartnerAgent(newHsOfficePartner), hsOfficeDebitorAgent(newHsOfficeDebitor)], incomingSuperRoles => array[hsOfficeMembershipAgent(NEW), hsOfficeRelationshipAgent(newHsOfficePartnerRel), hsOfficeDebitorAgent(newHsOfficeDebitor)],
outgoingSubRoles => array[hsOfficePartnerGuest(newHsOfficePartner), hsOfficeDebitorGuest(newHsOfficeDebitor)] outgoingSubRoles => array[hsOfficeRelationshipGuest(newHsOfficePartnerRel), hsOfficeDebitorGuest(newHsOfficeDebitor)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipGuest(NEW), hsOfficeMembershipGuest(NEW),
permissions => array['view'], permissions => array['view'],
incomingSuperRoles => array[hsOfficeMembershipTenant(NEW), hsOfficePartnerTenant(newHsOfficePartner), hsOfficeDebitorTenant(newHsOfficeDebitor)] incomingSuperRoles => array[hsOfficeMembershipTenant(NEW), hsOfficeRelationshipTenant(newHsOfficePartnerRel), hsOfficeDebitorTenant(newHsOfficeDebitor)]
); );
-- === END of code generated from Mermaid flowchart. === -- === END of code generated from Mermaid flowchart. ===

View File

@ -181,26 +181,26 @@ public class ImportOfficeData extends ContextBasedTest {
// no contacts yet => mostly null values // no contacts yet => mostly null values
assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace("""
{ {
17=partner(null null, null), 17=partner(P-10017: null null, null),
20=partner(null null, null), 20=partner(P-10020: null null, null),
22=partner(null null, null), 22=partner(P-11022: null null, null),
99=partner(null null, null) 99=partner(P-19999: null null, null)
} }
"""); """);
assertThat(toFormattedString(contacts)).isEqualTo("{}"); assertThat(toFormattedString(contacts)).isEqualTo("{}");
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
{ {
17=debitor(D-1001700: null null, null: mih), 17=debitor(D-1001700: P-10017, mih),
20=debitor(D-1002000: null null, null: xyz), 20=debitor(D-1002000: P-10020, xyz),
22=debitor(D-1102200: null null, null: xxx), 22=debitor(D-1102200: P-11022, xxx),
99=debitor(D-1999900: null null, null: zzz) 99=debitor(D-1999900: P-19999, zzz)
} }
"""); """);
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
{ {
17=Membership(M-1001700, null null, null, D-1001700, [2000-12-06,), NONE), 17=Membership(M-1001700, P-10017, D-1001700, [2000-12-06,), NONE),
20=Membership(M-1002000, null null, null, D-1002000, [2000-12-06,2016-01-01), UNKNOWN), 20=Membership(M-1002000, P-10020, D-1002000, [2000-12-06,2016-01-01), UNKNOWN),
22=Membership(M-1102200, null null, null, D-1102200, [2021-04-01,), NONE) 22=Membership(M-1102200, P-11022, D-1102200, [2021-04-01,), NONE)
} }
"""); """);
} }
@ -224,10 +224,10 @@ public class ImportOfficeData extends ContextBasedTest {
assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(partners)).isEqualToIgnoringWhitespace("""
{ {
17=partner(NP Mellies, Michael: Herr Michael Mellies ), 17=partner(P-10017: NP Mellies, Michael, Herr Michael Mellies ),
20=partner(LP JM GmbH: Herr Philip Meyer-Contract , JM GmbH), 20=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH),
22=partner(?? Test PS: Petra Schmidt , Test PS), 22=partner(P-11022: ?? Test PS, Petra Schmidt , Test PS),
99=partner(null null, null) 99=partner(P-19999: null null, null)
} }
"""); """);
assertThat(toFormattedString(contacts)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(contacts)).isEqualToIgnoringWhitespace("""
@ -257,17 +257,17 @@ public class ImportOfficeData extends ContextBasedTest {
"""); """);
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
{ {
17=debitor(D-1001700: NP Mellies, Michael: mih), 17=debitor(D-1001700: P-10017, mih),
20=debitor(D-1002000: LP JM GmbH: xyz), 20=debitor(D-1002000: P-10020, xyz),
22=debitor(D-1102200: ?? Test PS: xxx), 22=debitor(D-1102200: P-11022, xxx),
99=debitor(D-1999900: null null, null: zzz) 99=debitor(D-1999900: P-19999, zzz)
} }
"""); """);
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
{ {
17=Membership(M-1001700, NP Mellies, Michael, D-1001700, [2000-12-06,), NONE), 17=Membership(M-1001700, P-10017, D-1001700, [2000-12-06,), NONE),
20=Membership(M-1002000, LP JM GmbH, D-1002000, [2000-12-06,2016-01-01), UNKNOWN), 20=Membership(M-1002000, P-10020, D-1002000, [2000-12-06,2016-01-01), UNKNOWN),
22=Membership(M-1102200, ?? Test PS, D-1102200, [2021-04-01,), NONE) 22=Membership(M-1102200, P-11022, D-1102200, [2021-04-01,), NONE)
} }
"""); """);
assertThat(toFormattedString(relationships)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(relationships)).isEqualToIgnoringWhitespace("""
@ -313,9 +313,9 @@ public class ImportOfficeData extends ContextBasedTest {
assertThat(toFormattedString(bankAccounts)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(bankAccounts)).isEqualToIgnoringWhitespace("""
{ {
234234=bankAccount(holder='Michael Mellies', iban='DE37500105177419788228', bic='INGDDEFFXXX'), 234234=bankAccount(DE37500105177419788228: holder='Michael Mellies', bic='INGDDEFFXXX'),
235600=bankAccount(holder='JM e.K.', iban='DE02300209000106531065', bic='CMCIDEDD'), 235600=bankAccount(DE02300209000106531065: holder='JM e.K.', bic='CMCIDEDD'),
235662=bankAccount(holder='JM GmbH', iban='DE49500105174516484892', bic='INGDDEFFXXX') 235662=bankAccount(DE49500105174516484892: holder='JM GmbH', bic='INGDDEFFXXX')
} }
"""); """);
assertThat(toFormattedString(sepaMandates)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(sepaMandates)).isEqualToIgnoringWhitespace("""