Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Permettre de recréer un learner avec nationalStudentId lorsque l'ancien est supprimé (PIX-15467) #10653

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const TABLE_NAME = 'organization-learners';
const NEW_CONSTRAINT_NAME = 'one_active_sco_organization_learner';
const DELETEDAT_COLUMN = 'deletedAt';
const NATIONAL_STUDENT_ID_COLUMN = 'nationalStudentId';
const ORGANIZATIONID_COLUMN = 'organizationId';

const up = async function (knex) {
await knex.schema.table(TABLE_NAME, (table) => {
table.dropUnique(['organizationId', 'nationalStudentId']);
});

return knex.raw(
`CREATE UNIQUE INDEX :name: ON :table: (:nationalStudentId:, :organizationId: ) WHERE :deletedAt: IS NULL;`,
{
name: NEW_CONSTRAINT_NAME,
table: TABLE_NAME,
nationalStudentId: NATIONAL_STUDENT_ID_COLUMN,
organizationId: ORGANIZATIONID_COLUMN,
deletedAt: DELETEDAT_COLUMN,
},
);
};

const down = async function (knex) {
await knex.raw(`DROP INDEX :name:;`, { name: NEW_CONSTRAINT_NAME });

return knex.schema.table(TABLE_NAME, (table) => {
table.unique(['organizationId', 'nationalStudentId']);
});
};

export { down, up };
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const addOrUpdateOrganizationOfOrganizationLearners = async function (organizati

await knexConn('organization-learners')
.insert(organizationLearnersToSave)
.onConflict(['organizationId', 'nationalStudentId'])
.onConflict(knexConn.raw('("organizationId","nationalStudentId") where "deletedAt" is NULL'))
.merge();
} catch (err) {
throw new OrganizationLearnersCouldNotBeSavedError();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,56 @@ describe('Integration | Repository | Organization Learner Management | Organizat
});
});

context('when there are deleted organizationLearners with same nationalStudentId', function () {
let organizationLearners;
let organizationId;
let firstOrganizationLearner;

beforeEach(async function () {
organizationId = databaseBuilder.factory.buildOrganization().id;

firstOrganizationLearner = new OrganizationLearner({
lastName: 'Pipeau',
preferredLastName: 'Toto',
firstName: 'Corinne',
middleName: 'Dorothée',
thirdName: 'Driss',
sex: 'F',
birthdate: '2000-01-01',
birthCity: 'Perpi',
birthCityCode: '123456',
birthProvinceCode: '66',
birthCountryCode: '100',
MEFCode: 'MEF123456',
status: 'ST',
nationalStudentId: '1234',
division: '4B',
userId: null,
isDisabled: false,
organizationId,
});

databaseBuilder.factory.buildOrganizationLearner({ ...firstOrganizationLearner, deletedAt: new Date() });

await databaseBuilder.commit();

organizationLearners = [firstOrganizationLearner];
});

it('should create all organizationLearners', async function () {
// when
await DomainTransaction.execute((domainTransaction) => {
return addOrUpdateOrganizationOfOrganizationLearners(organizationLearners, organizationId, domainTransaction);
});

// then
const actualOrganizationLearners = await organizationLearnerRepository.findByOrganizationId({
organizationId,
});
expect(actualOrganizationLearners).to.have.lengthOf(1);
});
});

context('when an organizationLearner is saved with a userId already present in organization', function () {
it('should save the organization learner with userId as null', async function () {
const { id: organizationId } = databaseBuilder.factory.buildOrganization();
Expand Down