diff --git a/api/src/services/application-exporter.service.ts b/api/src/services/application-exporter.service.ts index fd3bccef87..213c3e39bc 100644 --- a/api/src/services/application-exporter.service.ts +++ b/api/src/services/application-exporter.service.ts @@ -8,6 +8,7 @@ import { join } from 'path'; import { view } from './application.service'; import { Application } from '../dtos/applications/application.dto'; import { ApplicationCsvQueryParams } from '../dtos/applications/application-csv-query-params.dto'; +import { MultiselectQuestion } from '../dtos/multiselect-questions/multiselect-question.dto'; import { ApplicationMultiselectQuestion } from '../dtos/applications/application-multiselect-question.dto'; import { IdDTO } from '../dtos/shared/id.dto'; import { User } from '../dtos/users/user.dto'; @@ -465,18 +466,18 @@ export class ApplicationExporterService { ); if (forLottery) { - const preferences = multiSelectQuestions.filter( - (question) => - question.applicationSection === - MultiselectQuestionsApplicationSectionEnum.preferences, + const sortedPreferences = await this.sortPreferencesByOrdinal( + multiSelectQuestions, + queryParams.id, ); - for (const preference of preferences) { + + for (const preference of sortedPreferences) { await this.generateSpreadsheetData( workbook, mappedApps, columns, queryParams, - forLottery, + true, { id: preference.id, name: preference.text, @@ -719,6 +720,44 @@ export class ApplicationExporterService { return res; } + /** + * + * @param questions a collection of questions which can include more than preferences, the rest will be filtered out + * @param listingId the id of the listing + * @returns listing preferences sorted in ordinal order + */ + async sortPreferencesByOrdinal( + questions: MultiselectQuestion[], + listingId: string, + ) { + const preferences = questions.filter( + (question) => + question.applicationSection === + MultiselectQuestionsApplicationSectionEnum.preferences, + ); + + // pull in the preference questions by ordinal + const listingPreferencesByOrdinal = + await this.prisma.listingMultiselectQuestions.findMany({ + where: { + listingId: listingId, + multiselectQuestionId: { + in: [...preferences.map((preference) => preference.id)], + }, + }, + orderBy: { + ordinal: 'asc', + }, + }); + + // get a sorted list of preferences via listing preference ordinal + return listingPreferencesByOrdinal.map((item) => + preferences.find( + (preference) => preference.id === item.multiselectQuestionId, + ), + ); + } + // shared functions /** * diff --git a/api/test/unit/services/application-exporter.service.spec.ts b/api/test/unit/services/application-exporter.service.spec.ts index 4d76a14f26..e500ea3fa8 100644 --- a/api/test/unit/services/application-exporter.service.spec.ts +++ b/api/test/unit/services/application-exporter.service.spec.ts @@ -7,6 +7,7 @@ import { Request as ExpressRequest, Response } from 'express'; import { PrismaService } from '../../../src/services/prisma.service'; import { ApplicationCsvQueryParams } from '../../../src/dtos/applications/application-csv-query-params.dto'; import { User } from '../../../src/dtos/users/user.dto'; +import MultiselectQuestion from '../../../src/dtos/multiselect-questions/multiselect-question.dto'; import { ApplicationExporterService } from '../../../src/services/application-exporter.service'; import { MultiselectQuestionService } from '../../../src/services/multiselect-question.service'; import { mockApplicationSet } from './application.service.spec'; @@ -381,4 +382,56 @@ describe('Testing application export service', () => { expect(readable).toContain('EST'); }); + + it('should sort listing preferences by ordinal', async () => { + jest.useFakeTimers(); + jest.setSystemTime(new Date('2024-01-01')); + + const unsortedPreferences = [ + { + ...mockMultiselectQuestion( + 0, + new Date(), + MultiselectQuestionsApplicationSectionEnum.preferences, + ), + }, + { + ...mockMultiselectQuestion( + 1, + new Date(), + MultiselectQuestionsApplicationSectionEnum.preferences, + ), + }, + { + ...mockMultiselectQuestion( + 2, + new Date(), + MultiselectQuestionsApplicationSectionEnum.programs, + ), + options: [{ id: 1, text: 'text' }], + }, + ] as MultiselectQuestion[]; + + const listingId = randomUUID(); + + prisma.listingMultiselectQuestions.findMany = jest.fn().mockReturnValue([ + { + listingId, + multiselectQuestionId: unsortedPreferences[1].id, + ordinal: 1, + }, + { + listingId, + multiselectQuestionId: unsortedPreferences[0].id, + ordinal: 2, + }, + ]); + + const sortedPreferences = await service.sortPreferencesByOrdinal( + unsortedPreferences, + listingId, + ); + expect(sortedPreferences[0].text).toEqual('text 1'); + expect(sortedPreferences[1].text).toEqual('text 0'); + }); });