Skip to content

Commit

Permalink
feat: allow registration admin to signup to a closed registration
Browse files Browse the repository at this point in the history
  • Loading branch information
jorilindell committed May 21, 2024
1 parent 5c245cb commit d47aabb
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 78 deletions.
117 changes: 65 additions & 52 deletions src/domain/registration/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,19 +570,21 @@ describe('isRegistrationPossible', () => {
vi.setSystemTime('2022-11-07');

expect(
isRegistrationPossible(
fakeRegistration({
isRegistrationPossible({
organizationAncestors: [],
registration: fakeRegistration({
enrolmentStartTime: new Date('2022-11-08').toISOString(),
enrolmentEndTime: '',
})
)
}),
})
).toBe(false);
});

it('should return false if all seats are reserved', () => {
expect(
isRegistrationPossible(
fakeRegistration({
isRegistrationPossible({
organizationAncestors: [],
registration: fakeRegistration({
enrolmentStartTime: '',
enrolmentEndTime: '',
currentAttendeeCount: 10,
Expand All @@ -591,43 +593,46 @@ describe('isRegistrationPossible', () => {
waitingListCapacity: 10,
remainingAttendeeCapacity: 0,
remainingWaitingListCapacity: 0,
})
)
}),
})
).toBe(false);
});

it('should return true if all seats in event are not reserved', () => {
expect(
isRegistrationPossible(
fakeRegistration({
isRegistrationPossible({
organizationAncestors: [],
registration: fakeRegistration({
enrolmentStartTime: '',
enrolmentEndTime: '',
currentAttendeeCount: 5,
maximumAttendeeCapacity: 10,
remainingAttendeeCapacity: 5,
})
)
}),
})
).toBe(true);
});

it('should return false if all seats in event are reserved', () => {
expect(
isRegistrationPossible(
fakeRegistration({
isRegistrationPossible({
organizationAncestors: [],
registration: fakeRegistration({
enrolmentStartTime: '',
enrolmentEndTime: '',
currentAttendeeCount: 5,
maximumAttendeeCapacity: 10,
remainingAttendeeCapacity: 0,
})
)
}),
})
).toBe(false);
});

it('should return true if all seats in waiting list are not reserved', () => {
expect(
isRegistrationPossible(
fakeRegistration({
isRegistrationPossible({
organizationAncestors: [],
registration: fakeRegistration({
enrolmentStartTime: '',
enrolmentEndTime: '',
currentAttendeeCount: 10,
Expand All @@ -636,15 +641,16 @@ describe('isRegistrationPossible', () => {
waitingListCapacity: 10,
remainingAttendeeCapacity: 0,
remainingWaitingListCapacity: 5,
})
)
}),
})
).toBe(true);
});

it('should return false if all seats in waiting list are reserved', () => {
expect(
isRegistrationPossible(
fakeRegistration({
isRegistrationPossible({
organizationAncestors: [],
registration: fakeRegistration({
enrolmentStartTime: '',
enrolmentEndTime: '',
currentAttendeeCount: 10,
Expand All @@ -653,8 +659,8 @@ describe('isRegistrationPossible', () => {
waitingListCapacity: 10,
remainingAttendeeCapacity: 0,
remainingWaitingListCapacity: 0,
})
)
}),
})
).toBe(false);
});
});
Expand Down Expand Up @@ -728,102 +734,109 @@ describe('getRegistrationWarning', () => {

it('should return empty string if it is possible to enrol to the event', () => {
expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
currentAttendeeCount: 0,
remainingAttendeeCapacity: 10,
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe('');
});

it('should return correct warning if enrolment is not open', () => {
expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
enrolmentStartTime: new Date('2022-11-04').toISOString(),
enrolmentEndTime: new Date('2022-11-06').toISOString(),
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe('Ilmoittautuminen tähän tapahtumaan avautuu 4.11.2022 klo 00.00.');

expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
enrolmentStartTime: '',
enrolmentEndTime: new Date('2022-11-06').toISOString(),
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe(
'Ilmoittautuminen tähän tapahtumaan on tällä hetkellä suljettu. Kokeile myöhemmin uudelleen.'
);
});

it('should return correct warning if there is no available seats', () => {
expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
currentAttendeeCount: 10,
currentWaitingListCount: 0,
remainingAttendeeCapacity: 0,
remainingWaitingListCapacity: 0,
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe(
'Tapahtuman kaikki paikat ovat tällä hetkellä varatut. Kokeile myöhemmin uudelleen.'
);
});

it('should return correct warning if there are free seats in waiting list', () => {
expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
currentAttendeeCount: 10,
currentWaitingListCount: 0,
remainingAttendeeCapacity: 0,
remainingWaitingListCapacity: 10,
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe(
'Ilmoittautuminen tähän tapahtumaan on vielä mahdollista, mutta jonopaikkoja on jäljellä vain 10 kpl.'
);
});

it('should return empty string if maximum attendee capacity is not set', () => {
expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
currentAttendeeCount: 10,
maximumAttendeeCapacity: null,
remainingAttendeeCapacity: null,
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe('');
});

it('should return correct warning if event is full and waiting list capacity is not set', () => {
expect(
getRegistrationWarning(
fakeRegistration({
getRegistrationWarning({
organizationAncestors: [],
registration: fakeRegistration({
...singleRegistrationOverrides,
currentAttendeeCount: 10,
remainingAttendeeCapacity: 0,
waitingListCapacity: null,
}),
i18n.t.bind(i18n)
)
t: i18n.t.bind(i18n),
})
).toBe(
'Ilmoittautuminen tähän tapahtumaan on vielä mahdollista, mutta vain jonopaikkoja on jäljellä.'
);
Expand Down
67 changes: 51 additions & 16 deletions src/domain/registration/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import {
} from '../../constants';
import {
CreateRegistrationMutationInput,
OrganizationFieldsFragment,
RegistrationFieldsFragment,
RegistrationQueryVariables,
UpdateRegistrationMutationInput,
UserFieldsFragment,
} from '../../generated/graphql';
import { Language, MultiLanguageObject, PathBuilderProps } from '../../types';
import { featureFlagUtils } from '../../utils/featureFlags';
Expand All @@ -40,6 +42,7 @@ import {
getSeatsReservationData,
isSeatsReservationExpired,
} from '../seatsReservation/utils';
import { checkCanUserSignupAfterSignupIsEnded } from '../signupGroup/permissions';
import { REGISTRATION_FIELDS } from './constants';
import {
RegistrationFields,
Expand Down Expand Up @@ -355,21 +358,27 @@ export const registrationPathBuilder = ({
export const isRegistrationOpen = (
registration: RegistrationFieldsFragment
): boolean => {
const enrolmentStartTime = registration.enrolmentStartTime;
const enrolmentEndTime = registration.enrolmentEndTime;

// Registration is not open if enrolment start time is defined and in the future
if (enrolmentStartTime && isFuture(new Date(enrolmentStartTime))) {
if (isSignupNotOpened(registration)) {
return false;
}
// Registration is not open if enrolment end time is defined and in the past
if (enrolmentEndTime && isPast(new Date(enrolmentEndTime))) {
if (isSignupEnded(registration)) {
return false;
}

return true;
};

export const isSignupNotOpened = (
registration: RegistrationFieldsFragment
): boolean => {
const enrolmentStartTime = registration.enrolmentStartTime;

// Registration is not open if enrolment start time is defined and in the future
return Boolean(enrolmentStartTime && isFuture(new Date(enrolmentStartTime)));
};

export const isSignupEnded = (
registration: RegistrationFieldsFragment
): boolean => {
Expand Down Expand Up @@ -450,17 +459,32 @@ export const hasSignups = (
);
};

export const isRegistrationPossible = (
registration: RegistrationFieldsFragment
): boolean => {
const registrationOpen = isRegistrationOpen(registration);
export const isRegistrationPossible = ({
organizationAncestors,
registration,
user,
}: {
organizationAncestors: OrganizationFieldsFragment[];
registration: RegistrationFieldsFragment;
user?: UserFieldsFragment;
}): boolean => {
const signupNotOpened = isSignupNotOpened(registration);
const signupEnded = isSignupEnded(registration);
const attendeeCapacityUsed = isAttendeeCapacityUsed(registration);
const freeAttendeeCapacity = getFreeAttendeeCapacity(registration);
const waitingListCapacityUsed = isWaitingListCapacityUsed(registration);
const freeWaitingListCapacity = getFreeWaitingListCapacity(registration);

// Enrolment is not opened or is already closed
if (!registrationOpen) {
// Enrolment is not opened or is already closed and user cannot add signups to closed registration
if (
signupNotOpened ||
(signupEnded &&
!checkCanUserSignupAfterSignupIsEnded({
organizationAncestors,
registration,
user,
}))
) {
return false;
}
// Attendee capacity and waiting list capacity is used
Expand All @@ -476,12 +500,23 @@ export const isRegistrationPossible = (
return freeWaitingListCapacity !== 0;
};

export const getRegistrationWarning = (
registration: RegistrationFieldsFragment,
t: TFunction
): string => {
export const getRegistrationWarning = ({
organizationAncestors,
registration,
t,
user,
}: {
organizationAncestors: OrganizationFieldsFragment[];
registration: RegistrationFieldsFragment;
t: TFunction;
user?: UserFieldsFragment;
}): string => {
const registrationOpen = isRegistrationOpen(registration);
const registrationPossible = isRegistrationPossible(registration);
const registrationPossible = isRegistrationPossible({
organizationAncestors,
registration,
user,
});
const attendeeCapacityUsed = isAttendeeCapacityUsed(registration);
const waitingListCapacityUsed = isWaitingListCapacityUsed(registration);
const freeWaitlistCapacity = getFreeWaitingListCapacity(registration);
Expand Down
Loading

0 comments on commit d47aabb

Please sign in to comment.