Compare commits

..

No commits in common. "ecc91592b0482fef98f63408f6dc5d005071d281" and "4c6b7beb2d903f23bd110b5642b32400b9050290" have entirely different histories.

7 changed files with 132 additions and 158 deletions

View File

@ -397,7 +397,6 @@ 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 $$
@ -669,26 +668,6 @@ 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,7 +74,6 @@ 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
@ -83,14 +82,6 @@ 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,6 +7,13 @@ 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:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
@ -28,40 +35,70 @@ begin
if TG_OP = 'INSERT' then if TG_OP = 'INSERT' then
-- Permissions and Grants for Partner -- === ATTENTION: code generated from related Mermaid flowchart: ===
call grantPermissionsToRole( perform createRoleWithGrants(
getRoleId(hsOfficeRelationshipOwner(newPartnerRole), 'fail'), hsOfficePartnerOwner(NEW),
createPermissions(NEW.uuid, array ['*']) permissions => array['*'],
incomingSuperRoles => array[globalAdmin()],
outgoingSubRoles => array[
hsOfficeRelationshipOwner(newPartnerRole)]
); );
call grantPermissionsToRole( perform createRoleWithGrants(
getRoleId(hsOfficeRelationshipAdmin(newPartnerRole), 'fail'), hsOfficePartnerAdmin(NEW),
createPermissions(NEW.uuid, array ['edit']) permissions => array['edit'],
incomingSuperRoles => array[
hsOfficePartnerOwner(NEW)],
outgoingSubRoles => array[
hsOfficeRelationshipAdmin(newPartnerRole)]
); );
call grantPermissionsToRole( perform createRoleWithGrants(
getRoleId(hsOfficeRelationshipTenant(newPartnerRole), 'fail'), hsOfficePartnerAgent(NEW),
createPermissions(NEW.uuid, array ['view']) incomingSuperRoles => array[
hsOfficePartnerAdmin(NEW),
hsOfficeRelationshipAgent(newPartnerRole)]
); );
-- Permissions and Grants for PartnerDetails 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(hsOfficeRelationshipOwner(newPartnerRole), 'fail'), getRoleId(hsOfficePartnerOwner(NEW), 'fail'),
createPermissions(NEW.detailsUuid, array ['*']) createPermissions(NEW.detailsUuid, array ['*'])
); );
call grantPermissionsToRole( call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipAdmin(newPartnerRole), 'fail'), getRoleId(hsOfficePartnerAdmin(NEW), 'fail'),
createPermissions(NEW.detailsUuid, array ['edit']) createPermissions(NEW.detailsUuid, array ['edit'])
); );
call grantPermissionsToRole( call grantPermissionsToRole(
-- Yes, here hsOfficePartnerAGENT is used, not hsOfficeRelationshipTENANT. -- Yes, here hsOfficePartnerAGENT is used, not hsOfficePartnerTENANT.
-- Do NOT grant view permission on partner-details to hsOfficeRelationshipTENANT! -- Do NOT grant view permission on partner-details to hsOfficePartnerTENANT!
-- Otherwise package-admins etc. would be able to read the data. -- Otherwise package-admins etc. would be able to read the data.
getRoleId(hsOfficeRelationshipAgent(newPartnerRole), 'fail'), getRoleId(hsOfficePartnerAgent(NEW), 'fail'),
createPermissions(NEW.detailsUuid, array ['view']) createPermissions(NEW.detailsUuid, array ['view'])
); );
@ -71,47 +108,14 @@ 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;
-- Revoke all Permissions from old partner relationship call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRole), hsOfficePartnerAdmin(OLD));
-- TODO: introduce call revokeAllPermissionsOnDescendantFromAllRolesOfAscendant(OLD, oldPartnerRole); call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRole), hsOfficePartnerAdmin(NEW));
delete from rbacGrants where descendantUuid==OLD.uuid and ascendantUuid==OLD.partnerRoleUuid;
-- Grants for Partner call revokeRoleFromRole(hsOfficePartnerAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRole));
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,6 +3,22 @@
```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
@ -12,25 +28,15 @@ subgraph partnerRelationship[hsOfficeRelationship:PARTNER]
--> role:partnerRelationship.agent[relationship.agent] --> role:partnerRelationship.agent[relationship.agent]
--> role:partnerRelationship.tenant[relationship.tenant] --> role:partnerRelationship.tenant[relationship.tenant]
partnerPersonAdmin>e.g. partnerPerson.admin] --> role:partnerRelationship.agent partnerPerson[e.g. partnerPerson.admin] --> role:partnerRelationship.agent
otherPersonAdmin>e.g. operationalPerson.admin] --> role:partnerRelationship.tenant otherPerson[e.g. operationalPerson.admin] --> role:partnerRelationship.tenant
role:partnerRelationship.tenant --> partnerPersonReferrer>e.g. partnerPerson.referrer] end
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
@ -50,7 +56,7 @@ subgraph internal[ ]
role:debitorRelationship.admin[debitorRelationship.admin] role:debitorRelationship.admin[debitorRelationship.admin]
%% permissions %% permissions
==> perm:debitor.edit{{debitor.edit}} ==> perm:debitor.edit{{debitorRelationship.edit}}
%% incoming %% incoming
role:partnerRelationship.admin ==> role:debitorRelationship.admin role:partnerRelationship.admin ==> role:debitorRelationship.admin
%% outgoing %% outgoing

View File

@ -30,8 +30,6 @@ 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;
@ -41,12 +39,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),
permissions => array['*'], permissions => array['*'],
@ -65,7 +62,7 @@ begin
hsOfficeDebitorAgent(NEW), hsOfficeDebitorAgent(NEW),
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeDebitorAdmin(NEW), hsOfficeDebitorAdmin(NEW),
hsOfficeRelationshipAdmin(newPartnerRel), hsOfficePartnerAdmin(newPartner),
hsOfficeContactAdmin(newContact)], hsOfficeContactAdmin(newContact)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeBankAccountTenant(newBankaccount)] hsOfficeBankAccountTenant(newBankaccount)]
@ -75,10 +72,10 @@ begin
hsOfficeDebitorTenant(NEW), hsOfficeDebitorTenant(NEW),
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeDebitorAgent(NEW), hsOfficeDebitorAgent(NEW),
hsOfficeRelationshipAgent(newPartnerRel), hsOfficePartnerAgent(newPartner),
hsOfficeBankAccountAdmin(newBankaccount)], hsOfficeBankAccountAdmin(newBankaccount)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeRelationshipTenant(newPartnerRel), hsOfficePartnerTenant(newPartner),
hsOfficeContactGuest(newContact), hsOfficeContactGuest(newContact),
hsOfficeBankAccountGuest(newBankaccount)] hsOfficeBankAccountGuest(newBankaccount)]
); );
@ -94,16 +91,15 @@ 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), hsOfficeRelationshipAdmin(oldPartnerRel)); call revokeRoleFromRole(hsOfficeDebitorAgent(OLD), hsOfficePartnerAdmin(oldPartner));
call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficeRelationshipAdmin(oldPartnerRel)); call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficePartnerAdmin(newPartner));
call revokeRoleFromRole(hsOfficeDebitorTenant(OLD), hsOfficeRelationshipAgent(oldPartnerRel)); call revokeRoleFromRole(hsOfficeDebitorTenant(OLD), hsOfficePartnerAgent(oldPartner));
call grantRoleToRole(hsOfficeDebitorTenant(NEW), hsOfficeRelationshipAgent(newPartner)); call grantRoleToRole(hsOfficeDebitorTenant(NEW), hsOfficePartnerAgent(newPartner));
call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRel), hsOfficeDebitorTenant(OLD)); call revokeRoleFromRole(hsOfficePartnerTenant(oldPartner), hsOfficeDebitorTenant(OLD));
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeDebitorTenant(NEW)); call grantRoleToRole(hsOfficePartnerTenant(newPartner), hsOfficeDebitorTenant(NEW));
end if; end if;
if OLD.billingContactUuid <> NEW.billingContactUuid then if OLD.billingContactUuid <> NEW.billingContactUuid then

View File

@ -28,12 +28,10 @@ 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
@ -54,20 +52,20 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipAgent(NEW), hsOfficeMembershipAgent(NEW),
incomingSuperRoles => array[hsOfficeMembershipAdmin(NEW), hsOfficeRelationshipAdmin(newHsOfficePartnerRel), hsOfficeDebitorAdmin(newHsOfficeDebitor)], incomingSuperRoles => array[hsOfficeMembershipAdmin(NEW), hsOfficePartnerAdmin(newHsOfficePartner), hsOfficeDebitorAdmin(newHsOfficeDebitor)],
outgoingSubRoles => array[hsOfficeRelationshipTenant(newHsOfficePartnerRel), hsOfficeDebitorTenant(newHsOfficeDebitor)] outgoingSubRoles => array[hsOfficePartnerTenant(newHsOfficePartner), hsOfficeDebitorTenant(newHsOfficeDebitor)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipTenant(NEW), hsOfficeMembershipTenant(NEW),
incomingSuperRoles => array[hsOfficeMembershipAgent(NEW), hsOfficeRelationshipAgent(newHsOfficePartnerRel), hsOfficeDebitorAgent(newHsOfficeDebitor)], incomingSuperRoles => array[hsOfficeMembershipAgent(NEW), hsOfficePartnerAgent(newHsOfficePartner), hsOfficeDebitorAgent(newHsOfficeDebitor)],
outgoingSubRoles => array[hsOfficeRelationshipGuest(newHsOfficePartnerRel), hsOfficeDebitorGuest(newHsOfficeDebitor)] outgoingSubRoles => array[hsOfficePartnerGuest(newHsOfficePartner), hsOfficeDebitorGuest(newHsOfficeDebitor)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipGuest(NEW), hsOfficeMembershipGuest(NEW),
permissions => array['view'], permissions => array['view'],
incomingSuperRoles => array[hsOfficeMembershipTenant(NEW), hsOfficeRelationshipTenant(newHsOfficePartnerRel), hsOfficeDebitorTenant(newHsOfficeDebitor)] incomingSuperRoles => array[hsOfficeMembershipTenant(NEW), hsOfficePartnerTenant(newHsOfficePartner), 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(P-10017: null null, null), 17=partner(null null, null),
20=partner(P-10020: null null, null), 20=partner(null null, null),
22=partner(P-11022: null null, null), 22=partner(null null, null),
99=partner(P-19999: null null, null) 99=partner(null null, null)
} }
"""); """);
assertThat(toFormattedString(contacts)).isEqualTo("{}"); assertThat(toFormattedString(contacts)).isEqualTo("{}");
assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(debitors)).isEqualToIgnoringWhitespace("""
{ {
17=debitor(D-1001700: P-10017, mih), 17=debitor(D-1001700: null null, null: mih),
20=debitor(D-1002000: P-10020, xyz), 20=debitor(D-1002000: null null, null: xyz),
22=debitor(D-1102200: P-11022, xxx), 22=debitor(D-1102200: null null, null: xxx),
99=debitor(D-1999900: P-19999, zzz) 99=debitor(D-1999900: null null, null: zzz)
} }
"""); """);
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
{ {
17=Membership(M-1001700, P-10017, D-1001700, [2000-12-06,), NONE), 17=Membership(M-1001700, null null, null, D-1001700, [2000-12-06,), NONE),
20=Membership(M-1002000, P-10020, D-1002000, [2000-12-06,2016-01-01), UNKNOWN), 20=Membership(M-1002000, null null, null, D-1002000, [2000-12-06,2016-01-01), UNKNOWN),
22=Membership(M-1102200, P-11022, D-1102200, [2021-04-01,), NONE) 22=Membership(M-1102200, null null, null, 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(P-10017: NP Mellies, Michael, Herr Michael Mellies ), 17=partner(NP Mellies, Michael: Herr Michael Mellies ),
20=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH), 20=partner(LP JM GmbH: Herr Philip Meyer-Contract , JM GmbH),
22=partner(P-11022: ?? Test PS, Petra Schmidt , Test PS), 22=partner(?? Test PS: Petra Schmidt , Test PS),
99=partner(P-19999: null null, null) 99=partner(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: P-10017, mih), 17=debitor(D-1001700: NP Mellies, Michael: mih),
20=debitor(D-1002000: P-10020, xyz), 20=debitor(D-1002000: LP JM GmbH: xyz),
22=debitor(D-1102200: P-11022, xxx), 22=debitor(D-1102200: ?? Test PS: xxx),
99=debitor(D-1999900: P-19999, zzz) 99=debitor(D-1999900: null null, null: zzz)
} }
"""); """);
assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(memberships)).isEqualToIgnoringWhitespace("""
{ {
17=Membership(M-1001700, P-10017, D-1001700, [2000-12-06,), NONE), 17=Membership(M-1001700, NP Mellies, Michael, D-1001700, [2000-12-06,), NONE),
20=Membership(M-1002000, P-10020, D-1002000, [2000-12-06,2016-01-01), UNKNOWN), 20=Membership(M-1002000, LP JM GmbH, D-1002000, [2000-12-06,2016-01-01), UNKNOWN),
22=Membership(M-1102200, P-11022, D-1102200, [2021-04-01,), NONE) 22=Membership(M-1102200, ?? Test PS, 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(DE37500105177419788228: holder='Michael Mellies', bic='INGDDEFFXXX'), 234234=bankAccount(holder='Michael Mellies', iban='DE37500105177419788228', bic='INGDDEFFXXX'),
235600=bankAccount(DE02300209000106531065: holder='JM e.K.', bic='CMCIDEDD'), 235600=bankAccount(holder='JM e.K.', iban='DE02300209000106531065', bic='CMCIDEDD'),
235662=bankAccount(DE49500105174516484892: holder='JM GmbH', bic='INGDDEFFXXX') 235662=bankAccount(holder='JM GmbH', iban='DE49500105174516484892', bic='INGDDEFFXXX')
} }
"""); """);
assertThat(toFormattedString(sepaMandates)).isEqualToIgnoringWhitespace(""" assertThat(toFormattedString(sepaMandates)).isEqualToIgnoringWhitespace("""