From f1398d9f22abab3b15755b6c0ec13ecb8e20dff7 Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Mon, 25 Nov 2024 16:25:51 -0800 Subject: [PATCH 1/7] initial commit --- ...t.aest.controller.exportReport.e2e-spec.ts | 221 ++++++++++++++++++ .../report/models/report.dto.ts | 1 + ...DisbursementsWithoutValidSupplierReport.ts | 24 ++ ...rsements-without-valid-supplier-report.sql | 77 ++++++ ...rsements-without-valid-supplier-report.sql | 4 + .../test-utils/src/factories/cas-supplier.ts | 8 +- .../exportfinancialreports.json | 2 +- .../web/src/constants/report-constants.ts | 4 + 8 files changed, 337 insertions(+), 4 deletions(-) create mode 100644 sources/packages/backend/apps/db-migrations/src/migrations/1732567769085-CreateDisbursementsWithoutValidSupplierReport.ts create mode 100644 sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql create mode 100644 sources/packages/backend/apps/db-migrations/src/sql/Reports/Rollback-create-disbursements-without-valid-supplier-report.sql diff --git a/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts b/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts index 93be58bf8b..1b462b8972 100644 --- a/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts +++ b/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts @@ -3,11 +3,13 @@ import { E2EDataSources, createE2EDataSources, createFakeDisbursementFeedbackError, + createFakeDisbursementValue, createFakeEducationProgramOffering, createFakeInstitutionLocation, createFakeUser, getProviderInstanceForModule, saveFakeApplicationDisbursements, + saveFakeCASSupplier, saveFakeDesignationAgreementLocation, saveFakeStudent, } from "@sims/test-utils"; @@ -28,9 +30,11 @@ import { Assessment, COEStatus, DisbursementScheduleStatus, + DisbursementValueType, EducationProgram, EducationProgramOffering, FullTimeAssessment, + IdentityProviders, InstitutionLocation, OfferingIntensity, ProgramIntensity, @@ -39,6 +43,7 @@ import { import { addDays, getISODateOnlyString } from "@sims/utilities"; import { DataSource } from "typeorm"; import { createFakeEducationProgram } from "@sims/test-utils/factories/education-program"; +import { createFakeSINValidation } from "@sims/test-utils/factories/sin-validation"; describe("ReportAestController(e2e)-exportReport", () => { let app: INestApplication; @@ -1197,6 +1202,222 @@ describe("ReportAestController(e2e)-exportReport", () => { }); }); + it("Should generate the Disbursements Without Valid Supplier report when a report generation request is made with the appropriate date range.", async () => { + // Arrange + const application1 = await saveFakeApplicationDisbursements( + appDataSource, + { + firstDisbursementValues: [ + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "BCAG", + 500, + { + effectiveAmount: 500, + }, + ), + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "SBSD", + 300, + { + effectiveAmount: 298, + }, + ), + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "BGPD", + 200, + { + effectiveAmount: 198, + }, + ), + ], + secondDisbursementValues: [ + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "BCAG", + 500, + { + effectiveAmount: 499, + }, + ), + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "SBSD", + 300, + { + effectiveAmount: 299, + }, + ), + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "BGPD", + 200, + { + effectiveAmount: 199, + }, + ), + ], + }, + { + createSecondDisbursement: true, + applicationStatus: ApplicationStatus.Completed, + offeringIntensity: OfferingIntensity.partTime, + firstDisbursementInitialValues: { + coeStatus: COEStatus.completed, + disbursementScheduleStatus: DisbursementScheduleStatus.Sent, + dateSent: new Date("2020-01-01"), + }, + secondDisbursementInitialValues: { + coeStatus: COEStatus.completed, + disbursementScheduleStatus: DisbursementScheduleStatus.Sent, + dateSent: new Date("2020-02-01"), + }, + }, + ); + const student1 = application1.student; + student1.user.identityProviderType = IdentityProviders.BCSC; + await db.user.save(student1.user); + const sinValidation1 = createFakeSINValidation({ + student: student1, + }); + student1.sinValidation = sinValidation1; + await db.student.save(student1); + await db.sinValidation.save(sinValidation1); + await saveFakeCASSupplier( + db, + { + student: student1, + }, + { + isValid: false, + }, + ); + + const application2 = await saveFakeApplicationDisbursements( + appDataSource, + { + firstDisbursementValues: [ + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "BCAG", + 500, + { + effectiveAmount: 100, + }, + ), + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "SBSD", + 300, + { + effectiveAmount: 150, + }, + ), + createFakeDisbursementValue( + DisbursementValueType.BCGrant, + "BGPD", + 200, + { + effectiveAmount: 275, + }, + ), + ], + }, + { + applicationStatus: ApplicationStatus.Completed, + offeringIntensity: OfferingIntensity.fullTime, + firstDisbursementInitialValues: { + coeStatus: COEStatus.completed, + disbursementScheduleStatus: DisbursementScheduleStatus.Sent, + dateSent: new Date("2020-01-15"), + }, + }, + ); + const student2 = application2.student; + student2.user.identityProviderType = IdentityProviders.BCeIDBasic; + await db.user.save(student2.user); + const sinValidation2 = createFakeSINValidation({ + student: student2, + }); + student2.sinValidation = sinValidation2; + await db.student.save(student2); + await db.sinValidation.save(sinValidation2); + await saveFakeCASSupplier( + db, + { + student: student2, + }, + { + isValid: false, + }, + ); + + const payload = { + reportName: "Disbursements_Without_Valid_Supplier_Report", + params: { + startDate: "2020-01-01", + endDate: "2020-02-01", + }, + }; + const dryRunSubmissionMock = jest.fn().mockResolvedValue({ + valid: true, + formName: FormNames.ExportFinancialReports, + data: { data: payload }, + }); + formService.dryRunSubmission = dryRunSubmissionMock; + const endpoint = "/aest/report"; + const ministryUserToken = await getAESTToken( + AESTGroups.BusinessAdministrators, + ); + + // Act/Assert + await request(app.getHttpServer()) + .post(endpoint) + .send(payload) + .auth(ministryUserToken, BEARER_AUTH_TYPE) + .expect(HttpStatus.CREATED) + .then((response) => { + const fileContent = response.request.res["text"]; + const parsedResult = parse(fileContent, { + header: true, + }); + expect(parsedResult.data).toStrictEqual([ + { + "Address Line 1": student1.contactInfo.address.addressLine1, + BCAG: "999.00", + BGPD: "397.00", + City: student1.contactInfo.address.city, + Country: student1.contactInfo.address.country, + "Disability Status": student1.disabilityStatus, + "Given Name": student1.user.firstName, + "Last Name": student1.user.lastName, + "Postal Code": student1.contactInfo.address.postalCode, + "Profile Type": student1.user.identityProviderType, + Province: student1.contactInfo.address.provinceState, + SBSD: "597.00", + SIN: student1.sinValidation.sin, + }, + { + "Address Line 1": student2.contactInfo.address.addressLine1, + BCAG: "100.00", + BGPD: "275.00", + City: student2.contactInfo.address.city, + Country: student2.contactInfo.address.country, + "Disability Status": student2.disabilityStatus, + "Given Name": student2.user.firstName, + "Last Name": student2.user.lastName, + "Postal Code": student2.contactInfo.address.postalCode, + "Profile Type": student2.user.identityProviderType, + Province: student2.contactInfo.address.provinceState, + SBSD: "150.00", + SIN: student2.sinValidation.sin, + }, + ]); + }); + }); + /** * Converts education program offering object into a key-value pair object matching the result data. * @param fakeOffering an education program offering record. diff --git a/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts b/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts index 5d95728814..f9553433cd 100644 --- a/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts +++ b/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts @@ -23,6 +23,7 @@ enum MinistryReportNames { InstitutionDesignation = "Institution_Designation_Report", StudentUnmetNeed = "Ministry_Student_Unmet_Need_Report", ProgramAndOfferingStatus = "Program_And_Offering_Status_Report", + DisbursementsWithoutValidSupplier = "Disbursements_Without_Valid_Supplier_Report", } /** diff --git a/sources/packages/backend/apps/db-migrations/src/migrations/1732567769085-CreateDisbursementsWithoutValidSupplierReport.ts b/sources/packages/backend/apps/db-migrations/src/migrations/1732567769085-CreateDisbursementsWithoutValidSupplierReport.ts new file mode 100644 index 0000000000..e322781377 --- /dev/null +++ b/sources/packages/backend/apps/db-migrations/src/migrations/1732567769085-CreateDisbursementsWithoutValidSupplierReport.ts @@ -0,0 +1,24 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; +import { getSQLFileData } from "../utilities/sqlLoader"; + +export class CreateDisbursementsWithoutValidSupplierReport1732567769085 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + getSQLFileData( + "Create-disbursements-without-valid-supplier-report.sql", + "Reports", + ), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + getSQLFileData( + "Rollback-create-disbursements-without-valid-supplier-report.sql", + "Reports", + ), + ); + } +} diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql new file mode 100644 index 0000000000..36495bcc2a --- /dev/null +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql @@ -0,0 +1,77 @@ +INSERT INTO + sims.report_configs (report_name, report_sql) +VALUES + ( + 'Disbursements_Without_Valid_Supplier_Report', + 'WITH greatest_cas_suppliers AS ( + SELECT + student_id, + MAX(id) AS max_id + FROM + sims.cas_suppliers + GROUP BY + student_id + ), + disbursement_sums AS ( + SELECT + students.id AS student_id, + SUM(CASE WHEN dv.value_code = ''BCAG'' THEN dv.effective_amount ELSE 0 END) AS bcag_effective_amount, + SUM(CASE WHEN dv.value_code = ''SBSD'' THEN dv.effective_amount ELSE 0 END) AS sbsd_effective_amount, + SUM(CASE WHEN dv.value_code = ''BGPD'' THEN dv.effective_amount ELSE 0 END) AS bgpd_effective_amount + FROM + sims.students AS students + JOIN + sims.applications AS applications + ON applications.student_id = students.id + JOIN + sims.student_assessments AS student_assessments + ON applications.current_assessment_id = student_assessments.id + JOIN + sims.disbursement_schedules AS disbursement_schedules + ON student_assessments.id = disbursement_schedules.student_assessment_id + AND disbursement_schedules.disbursement_schedule_status = ''Sent'' + AND disbursement_schedules.date_sent between :startDate + AND :endDate + JOIN + sims.cas_suppliers AS cas_suppliers + ON students.id = cas_suppliers.student_id + JOIN + greatest_cas_suppliers + ON greatest_cas_suppliers.student_id = cas_suppliers.student_id + AND greatest_cas_suppliers.max_id = cas_suppliers.id + LEFT JOIN + sims.disbursement_values AS dv + ON dv.disbursement_schedule_id = disbursement_schedules.id + WHERE + cas_suppliers.is_valid = false + GROUP BY + students.id + ) + SELECT + users.first_name AS "Given Name", + users.last_name AS "Last Name", + sin_validations.sin AS "SIN", + users.identity_provider_type AS "Profile Type", + students.contact_info -> ''address'' ->> ''addressLine1'' AS "Address Line 1", + students.contact_info -> ''address'' ->> ''city'' AS "City", + students.contact_info -> ''address'' ->> ''provinceState'' AS "Province", + students.contact_info -> ''address'' ->> ''country'' AS "Country", + students.contact_info -> ''address'' ->> ''postalCode'' AS "Postal Code", + students.disability_status AS "Disability Status", + disbursement_sums.bcag_effective_amount AS "BCAG", + disbursement_sums.sbsd_effective_amount AS "SBSD", + disbursement_sums.bgpd_effective_amount AS "BGPD" + FROM + disbursement_sums + JOIN + sims.students AS students + ON students.id = disbursement_sums.student_id + JOIN + sims.users AS users + ON students.user_id = users.id + JOIN + sims.sin_validations AS sin_validations + ON students.sin_validation_id = sin_validations.id + ORDER BY + students.id;' + ); \ No newline at end of file diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Rollback-create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Rollback-create-disbursements-without-valid-supplier-report.sql new file mode 100644 index 0000000000..e674a56c46 --- /dev/null +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Rollback-create-disbursements-without-valid-supplier-report.sql @@ -0,0 +1,4 @@ +DELETE FROM + sims.report_configs +WHERE + report_name = 'Disbursements_Without_Valid_Supplier_Report'; \ No newline at end of file diff --git a/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts b/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts index f43f2abd38..81b71a7c55 100644 --- a/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts +++ b/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts @@ -27,7 +27,8 @@ export async function saveFakeCASSupplier( student?: Student; }, options?: { - supplierStatus: SupplierStatus; + supplierStatus?: SupplierStatus; + isValid?: boolean; }, ): Promise { const auditUser = await db.user.save(createFakeUser()); @@ -56,7 +57,8 @@ export function createFakeCASSupplier( auditUser: User; }, options?: { - supplierStatus: SupplierStatus; + supplierStatus?: SupplierStatus; + isValid?: boolean; }, ): CASSupplier { const casSupplier = new CASSupplier(); @@ -66,7 +68,7 @@ export function createFakeCASSupplier( // Verified manually has a minimum of values populated. if (options?.supplierStatus === SupplierStatus.VerifiedManually) { casSupplier.supplierAddress = {} as SupplierAddress; - casSupplier.isValid = true; + casSupplier.isValid = options?.isValid ?? true; } else { casSupplier.supplierAddress = { supplierSiteCode: faker.datatype.number(999).toString(), diff --git a/sources/packages/forms/src/form-definitions/exportfinancialreports.json b/sources/packages/forms/src/form-definitions/exportfinancialreports.json index 943b0bb697..d59e4b7b80 100644 --- a/sources/packages/forms/src/form-definitions/exportfinancialreports.json +++ b/sources/packages/forms/src/form-definitions/exportfinancialreports.json @@ -292,7 +292,7 @@ } ], "key": "columns", - "customConditional": "show = \n data.reportName === 'Disbursement_Forecast_Report' \n || data.reportName === 'Disbursement_Report' \n || data.reportName === 'Data_Inventory_Report'\n || data.reportName === 'Institution_Designation_Report'\n || data.reportName === 'ECert_Errors_Report'\n || data.reportName === 'Program_And_Offering_Status_Report'\n || data.reportName === 'Ministry_Student_Unmet_Need_Report'", + "customConditional": "show = \n data.reportName === 'Disbursement_Forecast_Report' \n || data.reportName === 'Disbursement_Report' \n || data.reportName === 'Data_Inventory_Report'\n || data.reportName === 'Institution_Designation_Report'\n || data.reportName === 'ECert_Errors_Report'\n || data.reportName === 'Program_And_Offering_Status_Report'\n || data.reportName === 'Ministry_Student_Unmet_Need_Report'\n || data.reportName === 'Disbursements_Without_Valid_Supplier_Report'", "type": "columns", "input": false, "tableView": false, diff --git a/sources/packages/web/src/constants/report-constants.ts b/sources/packages/web/src/constants/report-constants.ts index 9d62e017ce..9122c83d27 100644 --- a/sources/packages/web/src/constants/report-constants.ts +++ b/sources/packages/web/src/constants/report-constants.ts @@ -29,4 +29,8 @@ export const MINISTRY_REPORTS: OptionItemAPIOutDTO[] = [ description: "Student Unmet Need", id: "Ministry_Student_Unmet_Need_Report", }, + { + description: "Disbursements Without Valid Supplier", + id: "Disbursements_Without_Valid_Supplier_Report", + }, ]; From a771073b9fa43545e90d28e56b9c8dc148eef33e Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Mon, 25 Nov 2024 16:53:34 -0800 Subject: [PATCH 2/7] sonar issue --- ...rsements-without-valid-supplier-report.sql | 140 +++++++++--------- 1 file changed, 69 insertions(+), 71 deletions(-) diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql index 36495bcc2a..6a122899e1 100644 --- a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql @@ -3,75 +3,73 @@ INSERT INTO VALUES ( 'Disbursements_Without_Valid_Supplier_Report', - 'WITH greatest_cas_suppliers AS ( - SELECT - student_id, - MAX(id) AS max_id - FROM - sims.cas_suppliers - GROUP BY - student_id - ), - disbursement_sums AS ( - SELECT - students.id AS student_id, - SUM(CASE WHEN dv.value_code = ''BCAG'' THEN dv.effective_amount ELSE 0 END) AS bcag_effective_amount, - SUM(CASE WHEN dv.value_code = ''SBSD'' THEN dv.effective_amount ELSE 0 END) AS sbsd_effective_amount, - SUM(CASE WHEN dv.value_code = ''BGPD'' THEN dv.effective_amount ELSE 0 END) AS bgpd_effective_amount - FROM - sims.students AS students - JOIN - sims.applications AS applications - ON applications.student_id = students.id - JOIN - sims.student_assessments AS student_assessments - ON applications.current_assessment_id = student_assessments.id - JOIN - sims.disbursement_schedules AS disbursement_schedules - ON student_assessments.id = disbursement_schedules.student_assessment_id - AND disbursement_schedules.disbursement_schedule_status = ''Sent'' - AND disbursement_schedules.date_sent between :startDate - AND :endDate - JOIN - sims.cas_suppliers AS cas_suppliers - ON students.id = cas_suppliers.student_id - JOIN - greatest_cas_suppliers - ON greatest_cas_suppliers.student_id = cas_suppliers.student_id - AND greatest_cas_suppliers.max_id = cas_suppliers.id - LEFT JOIN - sims.disbursement_values AS dv - ON dv.disbursement_schedule_id = disbursement_schedules.id - WHERE - cas_suppliers.is_valid = false - GROUP BY - students.id - ) - SELECT - users.first_name AS "Given Name", - users.last_name AS "Last Name", - sin_validations.sin AS "SIN", - users.identity_provider_type AS "Profile Type", - students.contact_info -> ''address'' ->> ''addressLine1'' AS "Address Line 1", - students.contact_info -> ''address'' ->> ''city'' AS "City", - students.contact_info -> ''address'' ->> ''provinceState'' AS "Province", - students.contact_info -> ''address'' ->> ''country'' AS "Country", - students.contact_info -> ''address'' ->> ''postalCode'' AS "Postal Code", - students.disability_status AS "Disability Status", - disbursement_sums.bcag_effective_amount AS "BCAG", - disbursement_sums.sbsd_effective_amount AS "SBSD", - disbursement_sums.bgpd_effective_amount AS "BGPD" - FROM - disbursement_sums - JOIN - sims.students AS students - ON students.id = disbursement_sums.student_id - JOIN - sims.users AS users - ON students.user_id = users.id - JOIN - sims.sin_validations AS sin_validations - ON students.sin_validation_id = sin_validations.id - ORDER BY - students.id;' + SELECT + student_id, + MAX(id) AS max_id + FROM + sims.cas_suppliers + GROUP BY + student_id + ), + disbursement_sums AS ( + SELECT + students.id AS student_id, + SUM( + CASE + WHEN dv.value_code = '' BCAG '' THEN dv.effective_amount + ELSE 0 + END + ) AS bcag_effective_amount, + SUM( + CASE + WHEN dv.value_code = '' SBSD '' THEN dv.effective_amount + ELSE 0 + END + ) AS sbsd_effective_amount, + SUM( + CASE + WHEN dv.value_code = '' BGPD '' THEN dv.effective_amount + ELSE 0 + END + ) AS bgpd_effective_amount + FROM + sims.students AS students + JOIN sims.applications AS applications ON applications.student_id = students.id + JOIN sims.student_assessments AS student_assessments ON applications.current_assessment_id = student_assessments.id + JOIN sims.disbursement_schedules AS disbursement_schedules ON student_assessments.id = disbursement_schedules.student_assessment_id + AND disbursement_schedules.disbursement_schedule_status = '' Sent '' + AND disbursement_schedules.date_sent between :startDate + AND :endDate + JOIN sims.cas_suppliers AS cas_suppliers ON students.id = cas_suppliers.student_id + JOIN greatest_cas_suppliers ON greatest_cas_suppliers.student_id = cas_suppliers.student_id + AND greatest_cas_suppliers.max_id = cas_suppliers.id + LEFT JOIN sims.disbursement_values AS dv ON dv.disbursement_schedule_id = disbursement_schedules.id + WHERE + cas_suppliers.is_valid = false + GROUP BY + students.id + ) +SELECT + users.first_name AS "Given Name", + users.last_name AS "Last Name", + sin_validations.sin AS "SIN", + users.identity_provider_type AS "Profile Type", + students.contact_info -> '' address '' ->> '' addressLine1 '' AS "Address Line 1", + students.contact_info -> '' address '' ->> '' city '' AS "City", + students.contact_info -> '' address '' ->> '' provinceState '' AS "Province", + students.contact_info -> '' address '' ->> '' country '' AS "Country", + students.contact_info -> '' address '' ->> '' postalCode '' AS "Postal Code", + students.disability_status AS "Disability Status", + disbursement_sums.bcag_effective_amount AS "BCAG", + disbursement_sums.sbsd_effective_amount AS "SBSD", + disbursement_sums.bgpd_effective_amount AS "BGPD" +FROM + disbursement_sums + JOIN sims.students AS students ON students.id = disbursement_sums.student_id + JOIN sims.users AS users ON students.user_id = users.id + JOIN sims.sin_validations AS sin_validations ON students.sin_validation_id = sin_validations.id +ORDER BY + students.id; + +' ); \ No newline at end of file From 5a1f35824e0536f5903c8800ed2af811b20d54ae Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Mon, 25 Nov 2024 16:55:03 -0800 Subject: [PATCH 3/7] sonar issue --- ...rsements-without-valid-supplier-report.sql | 140 +++++++++--------- 1 file changed, 71 insertions(+), 69 deletions(-) diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql index 6a122899e1..36495bcc2a 100644 --- a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql @@ -3,73 +3,75 @@ INSERT INTO VALUES ( 'Disbursements_Without_Valid_Supplier_Report', - SELECT - student_id, - MAX(id) AS max_id - FROM - sims.cas_suppliers - GROUP BY - student_id - ), - disbursement_sums AS ( - SELECT - students.id AS student_id, - SUM( - CASE - WHEN dv.value_code = '' BCAG '' THEN dv.effective_amount - ELSE 0 - END - ) AS bcag_effective_amount, - SUM( - CASE - WHEN dv.value_code = '' SBSD '' THEN dv.effective_amount - ELSE 0 - END - ) AS sbsd_effective_amount, - SUM( - CASE - WHEN dv.value_code = '' BGPD '' THEN dv.effective_amount - ELSE 0 - END - ) AS bgpd_effective_amount - FROM - sims.students AS students - JOIN sims.applications AS applications ON applications.student_id = students.id - JOIN sims.student_assessments AS student_assessments ON applications.current_assessment_id = student_assessments.id - JOIN sims.disbursement_schedules AS disbursement_schedules ON student_assessments.id = disbursement_schedules.student_assessment_id - AND disbursement_schedules.disbursement_schedule_status = '' Sent '' - AND disbursement_schedules.date_sent between :startDate - AND :endDate - JOIN sims.cas_suppliers AS cas_suppliers ON students.id = cas_suppliers.student_id - JOIN greatest_cas_suppliers ON greatest_cas_suppliers.student_id = cas_suppliers.student_id - AND greatest_cas_suppliers.max_id = cas_suppliers.id - LEFT JOIN sims.disbursement_values AS dv ON dv.disbursement_schedule_id = disbursement_schedules.id - WHERE - cas_suppliers.is_valid = false - GROUP BY - students.id - ) -SELECT - users.first_name AS "Given Name", - users.last_name AS "Last Name", - sin_validations.sin AS "SIN", - users.identity_provider_type AS "Profile Type", - students.contact_info -> '' address '' ->> '' addressLine1 '' AS "Address Line 1", - students.contact_info -> '' address '' ->> '' city '' AS "City", - students.contact_info -> '' address '' ->> '' provinceState '' AS "Province", - students.contact_info -> '' address '' ->> '' country '' AS "Country", - students.contact_info -> '' address '' ->> '' postalCode '' AS "Postal Code", - students.disability_status AS "Disability Status", - disbursement_sums.bcag_effective_amount AS "BCAG", - disbursement_sums.sbsd_effective_amount AS "SBSD", - disbursement_sums.bgpd_effective_amount AS "BGPD" -FROM - disbursement_sums - JOIN sims.students AS students ON students.id = disbursement_sums.student_id - JOIN sims.users AS users ON students.user_id = users.id - JOIN sims.sin_validations AS sin_validations ON students.sin_validation_id = sin_validations.id -ORDER BY - students.id; - -' + 'WITH greatest_cas_suppliers AS ( + SELECT + student_id, + MAX(id) AS max_id + FROM + sims.cas_suppliers + GROUP BY + student_id + ), + disbursement_sums AS ( + SELECT + students.id AS student_id, + SUM(CASE WHEN dv.value_code = ''BCAG'' THEN dv.effective_amount ELSE 0 END) AS bcag_effective_amount, + SUM(CASE WHEN dv.value_code = ''SBSD'' THEN dv.effective_amount ELSE 0 END) AS sbsd_effective_amount, + SUM(CASE WHEN dv.value_code = ''BGPD'' THEN dv.effective_amount ELSE 0 END) AS bgpd_effective_amount + FROM + sims.students AS students + JOIN + sims.applications AS applications + ON applications.student_id = students.id + JOIN + sims.student_assessments AS student_assessments + ON applications.current_assessment_id = student_assessments.id + JOIN + sims.disbursement_schedules AS disbursement_schedules + ON student_assessments.id = disbursement_schedules.student_assessment_id + AND disbursement_schedules.disbursement_schedule_status = ''Sent'' + AND disbursement_schedules.date_sent between :startDate + AND :endDate + JOIN + sims.cas_suppliers AS cas_suppliers + ON students.id = cas_suppliers.student_id + JOIN + greatest_cas_suppliers + ON greatest_cas_suppliers.student_id = cas_suppliers.student_id + AND greatest_cas_suppliers.max_id = cas_suppliers.id + LEFT JOIN + sims.disbursement_values AS dv + ON dv.disbursement_schedule_id = disbursement_schedules.id + WHERE + cas_suppliers.is_valid = false + GROUP BY + students.id + ) + SELECT + users.first_name AS "Given Name", + users.last_name AS "Last Name", + sin_validations.sin AS "SIN", + users.identity_provider_type AS "Profile Type", + students.contact_info -> ''address'' ->> ''addressLine1'' AS "Address Line 1", + students.contact_info -> ''address'' ->> ''city'' AS "City", + students.contact_info -> ''address'' ->> ''provinceState'' AS "Province", + students.contact_info -> ''address'' ->> ''country'' AS "Country", + students.contact_info -> ''address'' ->> ''postalCode'' AS "Postal Code", + students.disability_status AS "Disability Status", + disbursement_sums.bcag_effective_amount AS "BCAG", + disbursement_sums.sbsd_effective_amount AS "SBSD", + disbursement_sums.bgpd_effective_amount AS "BGPD" + FROM + disbursement_sums + JOIN + sims.students AS students + ON students.id = disbursement_sums.student_id + JOIN + sims.users AS users + ON students.user_id = users.id + JOIN + sims.sin_validations AS sin_validations + ON students.sin_validation_id = sin_validations.id + ORDER BY + students.id;' ); \ No newline at end of file From f46abbfbfd1d7218ad4047d9326cab43fdf642fb Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Tue, 26 Nov 2024 10:29:08 -0800 Subject: [PATCH 4/7] changed query to use sims.students.cas_supplier_id --- ...t.aest.controller.exportReport.e2e-spec.ts | 8 ++++++-- ...rsements-without-valid-supplier-report.sql | 20 +++---------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts b/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts index 1b462b8972..933aaaf1f7 100644 --- a/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts +++ b/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts @@ -1285,7 +1285,7 @@ describe("ReportAestController(e2e)-exportReport", () => { student1.sinValidation = sinValidation1; await db.student.save(student1); await db.sinValidation.save(sinValidation1); - await saveFakeCASSupplier( + const casSupplier1 = await saveFakeCASSupplier( db, { student: student1, @@ -1294,6 +1294,8 @@ describe("ReportAestController(e2e)-exportReport", () => { isValid: false, }, ); + student1.casSupplier = casSupplier1; + await db.student.save(student1); const application2 = await saveFakeApplicationDisbursements( appDataSource, @@ -1344,7 +1346,7 @@ describe("ReportAestController(e2e)-exportReport", () => { student2.sinValidation = sinValidation2; await db.student.save(student2); await db.sinValidation.save(sinValidation2); - await saveFakeCASSupplier( + const casSupplier2 = await saveFakeCASSupplier( db, { student: student2, @@ -1353,6 +1355,8 @@ describe("ReportAestController(e2e)-exportReport", () => { isValid: false, }, ); + student2.casSupplier = casSupplier2; + await db.student.save(student2); const payload = { reportName: "Disbursements_Without_Valid_Supplier_Report", diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql index 36495bcc2a..a9a18091bb 100644 --- a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql @@ -3,16 +3,7 @@ INSERT INTO VALUES ( 'Disbursements_Without_Valid_Supplier_Report', - 'WITH greatest_cas_suppliers AS ( - SELECT - student_id, - MAX(id) AS max_id - FROM - sims.cas_suppliers - GROUP BY - student_id - ), - disbursement_sums AS ( + 'WITH disbursement_sums AS ( SELECT students.id AS student_id, SUM(CASE WHEN dv.value_code = ''BCAG'' THEN dv.effective_amount ELSE 0 END) AS bcag_effective_amount, @@ -34,16 +25,11 @@ VALUES AND :endDate JOIN sims.cas_suppliers AS cas_suppliers - ON students.id = cas_suppliers.student_id - JOIN - greatest_cas_suppliers - ON greatest_cas_suppliers.student_id = cas_suppliers.student_id - AND greatest_cas_suppliers.max_id = cas_suppliers.id + ON students.cas_supplier_id = cas_suppliers.id + AND cas_suppliers.is_valid = false LEFT JOIN sims.disbursement_values AS dv ON dv.disbursement_schedule_id = disbursement_schedules.id - WHERE - cas_suppliers.is_valid = false GROUP BY students.id ) From ea0f0103cc38440a89b178881e0f5f7071e93594 Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Tue, 26 Nov 2024 14:43:48 -0800 Subject: [PATCH 5/7] review issues --- ...aest.controller.getCASSupplier.e2e-spec.ts | 2 +- ...t.aest.controller.exportReport.e2e-spec.ts | 8 +- ...rsements-without-valid-supplier-report.sql | 105 ++++++++---------- ...-to-sfas-integration.scheduler.e2e-spec.ts | 4 +- .../test-utils/src/factories/cas-supplier.ts | 19 ++-- .../web/src/constants/report-constants.ts | 8 +- 6 files changed, 72 insertions(+), 74 deletions(-) diff --git a/sources/packages/backend/apps/api/src/route-controllers/cas-supplier/_tests_/cas-supplier.aest.controller.getCASSupplier.e2e-spec.ts b/sources/packages/backend/apps/api/src/route-controllers/cas-supplier/_tests_/cas-supplier.aest.controller.getCASSupplier.e2e-spec.ts index ac40c2f91e..fe846fc86c 100644 --- a/sources/packages/backend/apps/api/src/route-controllers/cas-supplier/_tests_/cas-supplier.aest.controller.getCASSupplier.e2e-spec.ts +++ b/sources/packages/backend/apps/api/src/route-controllers/cas-supplier/_tests_/cas-supplier.aest.controller.getCASSupplier.e2e-spec.ts @@ -30,7 +30,7 @@ describe("CASSupplierAESTController(e2e)-getCASSuppliers", () => { const savedCASSupplier2 = await saveFakeCASSupplier( db, { student }, - { supplierStatus: SupplierStatus.VerifiedManually }, + { initialValues: { supplierStatus: SupplierStatus.VerifiedManually } }, ); const endpoint = `/aest/cas-supplier/student/${student.id}`; diff --git a/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts b/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts index 933aaaf1f7..763200e55c 100644 --- a/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts +++ b/sources/packages/backend/apps/api/src/route-controllers/report/_tests_/e2e/report.aest.controller.exportReport.e2e-spec.ts @@ -1291,7 +1291,9 @@ describe("ReportAestController(e2e)-exportReport", () => { student: student1, }, { - isValid: false, + initialValues: { + isValid: false, + }, }, ); student1.casSupplier = casSupplier1; @@ -1352,7 +1354,9 @@ describe("ReportAestController(e2e)-exportReport", () => { student: student2, }, { - isValid: false, + initialValues: { + isValid: false, + }, }, ); student2.casSupplier = casSupplier2; diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql index a9a18091bb..393eaf45ae 100644 --- a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql @@ -3,61 +3,52 @@ INSERT INTO VALUES ( 'Disbursements_Without_Valid_Supplier_Report', - 'WITH disbursement_sums AS ( - SELECT - students.id AS student_id, - SUM(CASE WHEN dv.value_code = ''BCAG'' THEN dv.effective_amount ELSE 0 END) AS bcag_effective_amount, - SUM(CASE WHEN dv.value_code = ''SBSD'' THEN dv.effective_amount ELSE 0 END) AS sbsd_effective_amount, - SUM(CASE WHEN dv.value_code = ''BGPD'' THEN dv.effective_amount ELSE 0 END) AS bgpd_effective_amount - FROM - sims.students AS students - JOIN - sims.applications AS applications - ON applications.student_id = students.id - JOIN - sims.student_assessments AS student_assessments - ON applications.current_assessment_id = student_assessments.id - JOIN - sims.disbursement_schedules AS disbursement_schedules - ON student_assessments.id = disbursement_schedules.student_assessment_id - AND disbursement_schedules.disbursement_schedule_status = ''Sent'' - AND disbursement_schedules.date_sent between :startDate - AND :endDate - JOIN - sims.cas_suppliers AS cas_suppliers - ON students.cas_supplier_id = cas_suppliers.id - AND cas_suppliers.is_valid = false - LEFT JOIN - sims.disbursement_values AS dv - ON dv.disbursement_schedule_id = disbursement_schedules.id - GROUP BY - students.id - ) - SELECT - users.first_name AS "Given Name", - users.last_name AS "Last Name", - sin_validations.sin AS "SIN", - users.identity_provider_type AS "Profile Type", - students.contact_info -> ''address'' ->> ''addressLine1'' AS "Address Line 1", - students.contact_info -> ''address'' ->> ''city'' AS "City", - students.contact_info -> ''address'' ->> ''provinceState'' AS "Province", - students.contact_info -> ''address'' ->> ''country'' AS "Country", - students.contact_info -> ''address'' ->> ''postalCode'' AS "Postal Code", - students.disability_status AS "Disability Status", - disbursement_sums.bcag_effective_amount AS "BCAG", - disbursement_sums.sbsd_effective_amount AS "SBSD", - disbursement_sums.bgpd_effective_amount AS "BGPD" - FROM - disbursement_sums - JOIN - sims.students AS students - ON students.id = disbursement_sums.student_id - JOIN - sims.users AS users - ON students.user_id = users.id - JOIN - sims.sin_validations AS sin_validations - ON students.sin_validation_id = sin_validations.id - ORDER BY - students.id;' + 'SELECT + users.first_name AS "Given Name", + users.last_name AS "Last Name", + sin_validations.sin AS "SIN", + users.identity_provider_type AS "Profile Type", + students.contact_info -> ''address'' ->> ''addressLine1'' AS "Address Line 1", + students.contact_info -> ''address'' ->> ''city'' AS "City", + students.contact_info -> ''address'' ->> ''provinceState'' AS "Province", + students.contact_info -> ''address'' ->> ''country'' AS "Country", + students.contact_info -> ''address'' ->> ''postalCode'' AS "Postal Code", + students.disability_status AS "Disability Status", + SUM( + CASE + WHEN disbursement_values.value_code = ''BCAG'' THEN disbursement_values.effective_amount + ELSE 0 + END + ) AS "BCAG", + SUM( + CASE + WHEN disbursement_values.value_code = ''SBSD'' THEN disbursement_values.effective_amount + ELSE 0 + END + ) AS "SBSD", + SUM( + CASE + WHEN disbursement_values.value_code = ''BGPD'' THEN disbursement_values.effective_amount + ELSE 0 + END + ) AS "BGPD" + FROM + sims.students students + INNER JOIN sims.users users ON students.user_id = users.id + INNER JOIN sims.sin_validations sin_validations ON students.id = sin_validations.student_id + INNER JOIN sims.cas_suppliers cas_suppliers ON cas_suppliers.student_id = students.id + INNER JOIN sims.applications applications ON applications.student_id = students.id + INNER JOIN sims.student_assessments student_assessments ON student_assessments.application_id = applications.id + LEFT JOIN sims.disbursement_schedules disbursement_schedules ON disbursement_schedules.student_assessment_id = student_assessments.id + INNER JOIN sims.disbursement_values disbursement_values ON disbursement_values.disbursement_schedule_id = disbursement_schedules.id + WHERE + disbursement_schedules.disbursement_schedule_status = ''Sent'' + AND disbursement_schedules.date_sent BETWEEN :startDate + AND :endDate + AND cas_suppliers.is_valid = false + GROUP BY + users.id, + sin_validations.sin, + students.contact_info, + students.disability_status;' ); \ No newline at end of file diff --git a/sources/packages/backend/apps/queue-consumers/src/processors/schedulers/sfas-integration/_tests_/sims-to-sfas-integration.scheduler.e2e-spec.ts b/sources/packages/backend/apps/queue-consumers/src/processors/schedulers/sfas-integration/_tests_/sims-to-sfas-integration.scheduler.e2e-spec.ts index bd21f67689..f4d20f6893 100644 --- a/sources/packages/backend/apps/queue-consumers/src/processors/schedulers/sfas-integration/_tests_/sims-to-sfas-integration.scheduler.e2e-spec.ts +++ b/sources/packages/backend/apps/queue-consumers/src/processors/schedulers/sfas-integration/_tests_/sims-to-sfas-integration.scheduler.e2e-spec.ts @@ -710,7 +710,9 @@ describe(describeProcessorRootTest(QueueNames.SIMSToSFASIntegration), () => { auditUser: student.user, }, { - supplierStatus: SupplierStatus.Verified, + initialValues: { + supplierStatus: SupplierStatus.Verified, + }, }, ); // Update CAS details as expected. diff --git a/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts b/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts index 81b71a7c55..e38f17352a 100644 --- a/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts +++ b/sources/packages/backend/libs/test-utils/src/factories/cas-supplier.ts @@ -18,7 +18,7 @@ import * as faker from "faker"; * @param relations dependencies: * - `student` student for the CAS supplier record. * @param options optional params. - * - `supplierStatus` supplier status. + * - `initialValues` CAS supplier initial values. * @returns a saved fake CAS supplier. */ export async function saveFakeCASSupplier( @@ -27,8 +27,7 @@ export async function saveFakeCASSupplier( student?: Student; }, options?: { - supplierStatus?: SupplierStatus; - isValid?: boolean; + initialValues?: Partial; }, ): Promise { const auditUser = await db.user.save(createFakeUser()); @@ -48,7 +47,7 @@ export async function saveFakeCASSupplier( * - `student` related student. * - `auditUser` audit user for the record. * @param options optional params. - * - `supplierStatus` supplier status. + * - `initialValues` CAS supplier initial values. * @returns a fake CAS supplier. */ export function createFakeCASSupplier( @@ -57,18 +56,20 @@ export function createFakeCASSupplier( auditUser: User; }, options?: { - supplierStatus?: SupplierStatus; - isValid?: boolean; + initialValues?: Partial; }, ): CASSupplier { const casSupplier = new CASSupplier(); casSupplier.supplierStatus = - options?.supplierStatus ?? SupplierStatus.PendingSupplierVerification; + options?.initialValues?.supplierStatus ?? + SupplierStatus.PendingSupplierVerification; // Verified manually has a minimum of values populated. - if (options?.supplierStatus === SupplierStatus.VerifiedManually) { + if ( + options?.initialValues?.supplierStatus === SupplierStatus.VerifiedManually + ) { casSupplier.supplierAddress = {} as SupplierAddress; - casSupplier.isValid = options?.isValid ?? true; + casSupplier.isValid = options?.initialValues.isValid ?? true; } else { casSupplier.supplierAddress = { supplierSiteCode: faker.datatype.number(999).toString(), diff --git a/sources/packages/web/src/constants/report-constants.ts b/sources/packages/web/src/constants/report-constants.ts index 9122c83d27..19f9bbcff5 100644 --- a/sources/packages/web/src/constants/report-constants.ts +++ b/sources/packages/web/src/constants/report-constants.ts @@ -12,6 +12,10 @@ export const INSTITUTION_REPORTS: OptionItemAPIOutDTO[] = [ export const MINISTRY_REPORTS: OptionItemAPIOutDTO[] = [ { description: "Data Inventory", id: "Data_Inventory_Report" }, { description: "Disbursements", id: "Disbursement_Report" }, + { + description: "Disbursements Without Valid Supplier", + id: "Disbursements_Without_Valid_Supplier_Report", + }, { description: "eCert Errors", id: "ECert_Errors_Report" }, { description: "Forecast disbursements", @@ -29,8 +33,4 @@ export const MINISTRY_REPORTS: OptionItemAPIOutDTO[] = [ description: "Student Unmet Need", id: "Ministry_Student_Unmet_Need_Report", }, - { - description: "Disbursements Without Valid Supplier", - id: "Disbursements_Without_Valid_Supplier_Report", - }, ]; From bf1f6d5832e9c14ffa6846adb621c6b4aeab6f8d Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Tue, 26 Nov 2024 15:07:48 -0800 Subject: [PATCH 6/7] review issues --- .../apps/api/src/route-controllers/report/models/report.dto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts b/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts index f9553433cd..679034231f 100644 --- a/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts +++ b/sources/packages/backend/apps/api/src/route-controllers/report/models/report.dto.ts @@ -18,12 +18,12 @@ enum InstitutionReportNames { enum MinistryReportNames { ForecastDisbursements = "Disbursement_Forecast_Report", Disbursements = "Disbursement_Report", + DisbursementsWithoutValidSupplier = "Disbursements_Without_Valid_Supplier_Report", DataInventory = "Data_Inventory_Report", ECertErrors = "ECert_Errors_Report", InstitutionDesignation = "Institution_Designation_Report", StudentUnmetNeed = "Ministry_Student_Unmet_Need_Report", ProgramAndOfferingStatus = "Program_And_Offering_Status_Report", - DisbursementsWithoutValidSupplier = "Disbursements_Without_Valid_Supplier_Report", } /** From 3bc808202fcbcda91fef2d282e7f57e21a881292 Mon Sep 17 00:00:00 2001 From: Andre Pestana Date: Tue, 26 Nov 2024 15:27:44 -0800 Subject: [PATCH 7/7] review issues --- .../Create-disbursements-without-valid-supplier-report.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql index 393eaf45ae..170c14781c 100644 --- a/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql +++ b/sources/packages/backend/apps/db-migrations/src/sql/Reports/Create-disbursements-without-valid-supplier-report.sql @@ -39,7 +39,7 @@ VALUES INNER JOIN sims.cas_suppliers cas_suppliers ON cas_suppliers.student_id = students.id INNER JOIN sims.applications applications ON applications.student_id = students.id INNER JOIN sims.student_assessments student_assessments ON student_assessments.application_id = applications.id - LEFT JOIN sims.disbursement_schedules disbursement_schedules ON disbursement_schedules.student_assessment_id = student_assessments.id + INNER JOIN sims.disbursement_schedules disbursement_schedules ON disbursement_schedules.student_assessment_id = student_assessments.id INNER JOIN sims.disbursement_values disbursement_values ON disbursement_values.disbursement_schedule_id = disbursement_schedules.id WHERE disbursement_schedules.disbursement_schedule_status = ''Sent''