Skip to content

Commit

Permalink
[FEATURE] affiche la date de naissance et la classe pour les prescrit…
Browse files Browse the repository at this point in the history
…s venant d'un import à format (Pix-13984)

 #10187
  • Loading branch information
pix-service-auto-merge authored Sep 26, 2024
2 parents 1215a6f + 84712a2 commit 7216201
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { knex } from '../../../../db/knex-database-connection.js';
import { BookshelfUser } from '../../../../src/shared/infrastructure/orm-models/User.js';
import * as organizationFeaturesApi from '../../../organizational-entities/application/api/organization-features-api.js';
import { Organization } from '../../../organizational-entities/domain/models/Organization.js';
import { OrganizationLearnerForAdmin } from '../../../prescription/learner-management/domain/read-models/OrganizationLearnerForAdmin.js';
import { ORGANIZATION_FEATURE } from '../../../shared/domain/constants.js';
import * as organizationLearnerImportFormatRepository from '../../../prescription/learner-management/infrastructure/repositories/organization-learner-import-format-repository.js';
import { DomainTransaction } from '../../../shared/domain/DomainTransaction.js';
import {
AlreadyExistingEntityError,
Expand Down Expand Up @@ -137,19 +138,20 @@ const getUserDetailsForAdmin = async function (userId) {
'view-active-organization-learners.*',
'organizations.name AS organizationName',
'organizations.isManagingStudents AS organizationIsManagingStudents',
knex.raw('CASE WHEN features.key IS NULL THEN False ELSE True END AS "hasImportFeature"'),
])
.join('organizations', 'organizations.id', 'view-active-organization-learners.organizationId')
.leftJoin('organization-features', 'organization-features.organizationId', 'organizations.id')
.leftJoin('features', function () {
this.on('features.id', 'organization-features.featureId').andOnVal(
'features.key',
ORGANIZATION_FEATURE.LEARNER_IMPORT.key,
);
})
.where({ userId })
.orderBy('id');

for (const learner of organizationLearnersDTO) {
const features = await organizationFeaturesApi.getAllFeaturesFromOrganization(learner.organizationId);
learner.hasImportFeature = features.hasLearnersImportFeature;
if (learner.hasImportFeature) {
const importFormat = await organizationLearnerImportFormatRepository.get(learner.organizationId);
learner.additionalColumns = importFormat.extraColumns;
}
}

const pixAdminRolesDTO = await knex('pix-admin-roles').where({ userId });

return _fromKnexDTOToUserDetailsForAdmin({
Expand Down Expand Up @@ -510,6 +512,8 @@ function _fromKnexDTOToUserDetailsForAdmin({
isDisabled: organizationLearnerDTO.isDisabled,
organizationIsManagingStudents:
organizationLearnerDTO.organizationIsManagingStudents || organizationLearnerDTO.hasImportFeature,
additionalInformations: organizationLearnerDTO.attributes,
additionalColumns: organizationLearnerDTO.additionalColumns,
}),
);
const userLogin = new UserLogin({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import JoiDate from '@joi/date';
import BaseJoi from 'joi';
const Joi = BaseJoi.extend(JoiDate);
import { validateEntity } from '../../../../shared/domain/validators/entity-validator.js';
import { IMPORT_KEY_FIELD } from '../constants.js';

const validationSchema = Joi.object({
id: Joi.number().integer().required(),
firstName: Joi.string().required(),
lastName: Joi.string().required(),
birthdate: Joi.date().required().allow(null),
birthdate: Joi.string().required().allow(null),
division: Joi.string().required().allow(null),
group: Joi.string().required().allow(null),
organizationId: Joi.number().integer().required(),
Expand All @@ -16,6 +17,11 @@ const validationSchema = Joi.object({
updatedAt: Joi.date().required(),
isDisabled: Joi.boolean().required(),
canBeDissociated: Joi.boolean().required(),
additionalInformations: Joi.object().allow(null),
additionalColumns: Joi.array().items({
name: Joi.string().required(),
key: Joi.string().required(),
}),
});

class OrganizationLearnerForAdmin {
Expand All @@ -32,6 +38,8 @@ class OrganizationLearnerForAdmin {
updatedAt,
isDisabled,
organizationIsManagingStudents,
additionalInformations = {},
additionalColumns = [],
}) {
this.id = id;
this.firstName = firstName;
Expand All @@ -45,8 +53,19 @@ class OrganizationLearnerForAdmin {
this.updatedAt = updatedAt;
this.isDisabled = isDisabled;
this.canBeDissociated = organizationIsManagingStudents;

validateEntity(validationSchema, this);
this.updateDivisionAndBirthdate({ additionalInformations, additionalColumns });
}

updateDivisionAndBirthdate({ additionalInformations, additionalColumns }) {
const dateOfBirthColumn = additionalColumns.find((column) => column.name === IMPORT_KEY_FIELD.COMMON_BIRTHDATE);
if (dateOfBirthColumn) {
this.birthdate = additionalInformations[dateOfBirthColumn.key];
}
const divisionColumn = additionalColumns.find((column) => column.name === IMPORT_KEY_FIELD.COMMON_DIVISION);
if (divisionColumn) {
this.division = additionalInformations[divisionColumn.key];
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as OidcIdentityProviders from '../../../../../src/identity-access-manag
import { User } from '../../../../../src/identity-access-management/domain/models/User.js';
import * as userRepository from '../../../../../src/identity-access-management/infrastructure/repositories/user.repository.js';
import { Organization } from '../../../../../src/organizational-entities/domain/models/Organization.js';
import { IMPORT_KEY_FIELD } from '../../../../../src/prescription/learner-management/domain/constants.js';
import { OrganizationLearnerForAdmin } from '../../../../../src/prescription/learner-management/domain/read-models/OrganizationLearnerForAdmin.js';
import { ORGANIZATION_FEATURE } from '../../../../../src/shared/domain/constants.js';
import {
Expand Down Expand Up @@ -1139,21 +1140,54 @@ describe('Integration | Identity Access Management | Infrastructure | Repository
const randomUser = databaseBuilder.factory.buildUser();
const userInDB = databaseBuilder.factory.buildUser(userToInsert);
const firstOrganizationInDB = databaseBuilder.factory.buildOrganization();
const firstOrganizationLearnerInDB = databaseBuilder.factory.buildOrganizationLearner({
id: 1,
userId: userInDB.id,
organizationId: firstOrganizationInDB.id,
});
const firstOrganizationLearnerInDB =
databaseBuilder.factory.prescription.organizationLearners.buildOrganizationLearner({
id: 1,
userId: userInDB.id,
organizationId: firstOrganizationInDB.id,
});
const secondOrganizationInDB = databaseBuilder.factory.buildOrganization();
const secondOrganizationLearnerInDB = databaseBuilder.factory.buildOrganizationLearner({
id: 2,
userId: userInDB.id,
organizationId: secondOrganizationInDB.id,
});
const secondOrganizationLearnerInDB =
databaseBuilder.factory.prescription.organizationLearners.buildOrganizationLearner({
id: 2,
userId: userInDB.id,
organizationId: secondOrganizationInDB.id,
attributes: { Classe: 'CP', 'Date de naissance': '2012-01-13' },
});
const importFeature = databaseBuilder.factory.buildFeature(ORGANIZATION_FEATURE.LEARNER_IMPORT);
const otherFeature = databaseBuilder.factory.buildFeature(ORGANIZATION_FEATURE.PLACES_MANAGEMENT);
const importFormat = databaseBuilder.factory.buildOrganizationLearnerImportFormat({
name: 'test',
fileType: 'csv',
config: {
displayableColumns: [
{
key: 4,
position: 2,
name: IMPORT_KEY_FIELD.COMMON_BIRTHDATE,
},
{
key: 3,
position: 1,
name: IMPORT_KEY_FIELD.COMMON_DIVISION,
},
],
headers: [
{ key: 1, name: 'Nom apprenant', property: 'lastName', required: true },
{ key: 2, name: 'Prénom apprenant', property: 'firstName', required: true },
{ key: 3, name: 'Classe', required: true },
{ key: 4, name: 'Date de naissance', required: true },
],
},
});
databaseBuilder.factory.buildOrganizationFeature({
featureId: importFeature.id,
organizationId: secondOrganizationInDB.id,
params: { organizationLearnerImportFormatId: importFormat.id },
});
databaseBuilder.factory.buildOrganizationFeature({
featureId: otherFeature.id,
organizationId: secondOrganizationInDB.id,
});

databaseBuilder.factory.buildOrganizationLearner({
Expand Down Expand Up @@ -1181,9 +1215,13 @@ describe('Integration | Identity Access Management | Infrastructure | Repository
...secondOrganizationLearnerInDB,
organizationName: secondOrganizationInDB.name,
canBeDissociated: true,
birthdate: '2012-01-13',
division: 'CP',
},
].map((organizationLearner) => pick(organizationLearner, expectedUserDetailsForAdminAttributes));
expect(organizationLearners).to.deep.equal(expectedOrganizationLearners);
organizationLearners.forEach((organizationLearner, index) => {
expect(organizationLearner).to.deep.contains(expectedOrganizationLearners[index]);
});
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IMPORT_KEY_FIELD } from '../../../../../../src/prescription/learner-management/domain/constants.js';
import { OrganizationLearnerForAdmin } from '../../../../../../src/prescription/learner-management/domain/read-models/OrganizationLearnerForAdmin.js';
import { ObjectValidationError } from '../../../../../../src/shared/domain/errors.js';
import { expect } from '../../../../../test-helper.js';
Expand All @@ -11,7 +12,7 @@ describe('Unit | Domain | Read-models | OrganizationLearnerForAdmin', function (
id: 1,
firstName: 'John',
lastName: 'Doe',
birthdate: new Date('2000-10-15'),
birthdate: '2000-10-15',
division: '3A',
group: 'L1',
organizationId: 1,
Expand All @@ -28,6 +29,25 @@ describe('Unit | Domain | Read-models | OrganizationLearnerForAdmin', function (
expect(() => new OrganizationLearnerForAdmin(validArguments)).not.to.throw(ObjectValidationError);
});

it('should overide birthdate and division if additionalColumns and additionalInfos are given', function () {
const learner = new OrganizationLearnerForAdmin({
...validArguments,
additionalColumns: [
{
name: IMPORT_KEY_FIELD.COMMON_BIRTHDATE,
key: 'dateofbirth',
},
{ name: IMPORT_KEY_FIELD.COMMON_DIVISION, key: 'groupe' },
],
additionalInformations: {
groupe: 'CP',
dateofbirth: '2020-02-01',
},
});
expect(learner.division).to.equal('CP');
expect(learner.birthdate).to.deep.equal('2020-02-01');
});

it('should throw an ObjectValidationError when id is not valid', function () {
// when
expect(() => new OrganizationLearnerForAdmin({ ...validArguments, id: 'not_valid' })).to.throw(
Expand Down Expand Up @@ -60,17 +80,15 @@ describe('Unit | Domain | Read-models | OrganizationLearnerForAdmin', function (

it('should throw an ObjectValidationError when birthdate is not valid', function () {
// when
expect(() => new OrganizationLearnerForAdmin({ ...validArguments, birthdate: 'not_valid' })).to.throw(
ObjectValidationError,
);

expect(() => new OrganizationLearnerForAdmin({ ...validArguments, birthdate: undefined })).to.throw(
ObjectValidationError,
);
});

it('should not throw an ObjectValidationError when birthdate is null', function () {
// when
expect(() => new OrganizationLearnerForAdmin({ ...validArguments, birthdate: 'null' })).to.throw(
expect(() => new OrganizationLearnerForAdmin({ ...validArguments, birthdate: null })).not.to.throw(
ObjectValidationError,
);
});
Expand Down

0 comments on commit 7216201

Please sign in to comment.