diff --git a/backend/src/services/organizationService.ts b/backend/src/services/organizationService.ts index 0db9800dda..e25227a79d 100644 --- a/backend/src/services/organizationService.ts +++ b/backend/src/services/organizationService.ts @@ -19,7 +19,7 @@ import { mergeObjects, normalizeHostname, } from '@crowd/common' -import { signalMemberUpdate, unmergeRoles } from '@crowd/common_services' +import { roleExistsInArray, signalMemberUpdate, unmergeRoles } from '@crowd/common_services' import { addMemberRole, moveMembersBetweenOrganizations, @@ -416,13 +416,10 @@ export default class OrganizationService extends LoggerBase { // check if anything to delete in primary const rolesToDelete = memberOrganizations.filter( (r) => - r.source !== 'ui' && - !primaryUnmergedRoles.some( - (pr) => - pr.memberId === r.memberId && - pr.title === r.title && - pr.dateStart === r.dateStart && - pr.dateEnd === r.dateEnd, + !roleExistsInArray( + r, + primaryUnmergedRoles, + MemberRoleUnmergeStrategy.SAME_ORGANIZATION, ), ) diff --git a/services/libs/common_services/src/services/member-organization.ts b/services/libs/common_services/src/services/member-organization.ts index 7e53b4302b..07ba071984 100644 --- a/services/libs/common_services/src/services/member-organization.ts +++ b/services/libs/common_services/src/services/member-organization.ts @@ -4,6 +4,7 @@ import { MemberOrgDate, MemberOrgStintChange, MemberRoleUnmergeStrategy, + OrganizationSource, } from '@crowd/types' function roleKey( @@ -16,7 +17,12 @@ function roleKey( return role.memberId } -function roleExistsInArray( +function isSameDate(a: Date | string | null, b: Date | string | null): boolean { + if (!a || !b) return !a && !b + return new Date(a).getTime() === new Date(b).getTime() +} + +export function roleExistsInArray( role: IMemberOrganization, roles: IMemberOrganization[], strategy: MemberRoleUnmergeStrategy, @@ -26,8 +32,8 @@ function roleExistsInArray( (r) => roleKey(r, strategy) === key && r.title === role.title && - r.dateStart === role.dateStart && - r.dateEnd === role.dateEnd, + isSameDate(r.dateStart, role.dateStart) && + isSameDate(r.dateEnd, role.dateEnd), ) } @@ -59,15 +65,19 @@ export function unmergeRoles( secondaryBackupRoles: IMemberOrganization[], strategy: MemberRoleUnmergeStrategy, ): IMemberOrganization[] { - const unmergedRoles: IMemberOrganization[] = mergedRoles.filter( - (role) => - role.source === 'ui' || - !secondaryBackupRoles.some((r) => roleKey(r, strategy) === roleKey(role, strategy)), + const cameFromSecondary = (role: IMemberOrganization) => + roleExistsInArray(role, secondaryBackupRoles, strategy) && + !roleExistsInArray(role, primaryBackupRoles, strategy) + + const unmergedRoles: IMemberOrganization[] = mergedRoles.filter((role) => + role.source === OrganizationSource.UI + ? !cameFromSecondary(role) + : !secondaryBackupRoles.some((r) => roleKey(r, strategy) === roleKey(role, strategy)), ) const editableRoles = mergedRoles.filter( (role) => - role.source !== 'ui' && + role.source !== OrganizationSource.UI && secondaryBackupRoles.some((r) => roleKey(r, strategy) === roleKey(role, strategy)), ) diff --git a/services/libs/common_services/src/services/member/unmerge.ts b/services/libs/common_services/src/services/member/unmerge.ts index 43f4baa3b5..81c3c9c9a4 100644 --- a/services/libs/common_services/src/services/member/unmerge.ts +++ b/services/libs/common_services/src/services/member/unmerge.ts @@ -59,10 +59,11 @@ import { MergeActionState, MergeActionStep, MergeActionType, + OrganizationSource, } from '@crowd/types' import { BotDetectionService } from '../bot.service' -import { unmergeRoles } from '../member-organization' +import { roleExistsInArray, unmergeRoles } from '../member-organization' const logger = getServiceLogger() @@ -591,16 +592,13 @@ export async function unmergeMember( const memberOrganizationsMap = await fetchManyMemberOrgsWithOrgData(tx, [memberId]) const memberOrganizations = memberOrganizationsMap.get(memberId) ?? [] + const isRoleIn = (role: IMemberRoleWithOrganization, roles: IMemberRoleWithOrganization[]) => + roleExistsInArray(role, roles, MemberRoleUnmergeStrategy.SAME_MEMBER) + rolesToDelete = memberOrganizations.filter( (r) => - r.source !== 'ui' && - !primary.memberOrganizations.some( - (pr) => - pr.organizationId === r.organizationId && - pr.title === r.title && - pr.dateStart === r.dateStart && - pr.dateEnd === r.dateEnd, - ), + !isRoleIn(r, primary.memberOrganizations) && + (r.source !== OrganizationSource.UI || isRoleIn(r, secondary.memberOrganizations)), ) for (const role of rolesToDelete) {