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

#1791 - Enable Assessments tab view and NOA view for Public Institution Users - Part 1 #1926

Merged
merged 15 commits into from
May 15, 2023
4 changes: 4 additions & 0 deletions sources/packages/backend/apps/api/src/app.aest.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ import {
ConfirmationOfEnrollmentControllerService,
OverawardAESTController,
OverawardControllerService,
ApplicationExceptionControllerService,
StudentAppealControllerService,
RestrictionControllerService,
} from "./route-controllers";
import { AuthModule } from "./auth/auth.module";
Expand Down Expand Up @@ -109,6 +111,8 @@ import {
OverawardAESTController,
],
providers: [
ApplicationExceptionControllerService,
StudentAppealControllerService,
WorkflowClientService,
InstitutionRestrictionService,
SupportingUserService,
Expand Down
29 changes: 25 additions & 4 deletions sources/packages/backend/apps/api/src/app.institutions.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import {
StudentService,
EducationProgramOfferingImportCSVService,
EducationProgramOfferingValidationService,
DisbursementReceiptService,
StudentAppealService,
ApplicationExceptionService,
StudentAppealRequestsService,
} from "./services";
import {
ApplicationControllerService,
Expand All @@ -46,8 +50,17 @@ import {
StudentInstitutionsController,
OverawardInstitutionsController,
StudentControllerService,
RestrictionInstitutionsController,
AssessmentInstitutionsController,
AssessmentControllerService,
OverawardControllerService,
ApplicationExceptionInstitutionsController,
ApplicationExceptionControllerService,
UserInstitutionsController,
ApplicationInstitutionsController,
UserControllerService,
StudentAppealInstitutionsController,
StudentAppealControllerService,
RestrictionInstitutionsController,
NoteInstitutionsController,
RestrictionControllerService,
} from "./route-controllers";
Expand All @@ -66,9 +79,6 @@ import {
SFASApplicationService,
SFASPartTimeApplicationsService,
} from "@sims/services/sfas";
import { UserInstitutionsController } from "./route-controllers/user/user.institutions.controller";
import { UserControllerService } from "./route-controllers/user/user.controller.service";
import { ApplicationInstitutionsController } from "./route-controllers/application/application.institutions.controller";

@Module({
imports: [AuthModule],
Expand All @@ -85,6 +95,10 @@ import { ApplicationInstitutionsController } from "./route-controllers/applicati
EducationProgramOfferingInstitutionsController,
UserInstitutionsController,
StudentInstitutionsController,
AssessmentInstitutionsController,
OverawardInstitutionsController,
ApplicationExceptionInstitutionsController,
StudentAppealInstitutionsController,
RestrictionInstitutionsController,
OverawardInstitutionsController,
NoteInstitutionsController,
Expand Down Expand Up @@ -136,7 +150,14 @@ import { ApplicationInstitutionsController } from "./route-controllers/applicati
NoteSharedService,
StudentControllerService,
RestrictionSharedService,
AssessmentControllerService,
DisbursementReceiptService,
StudentAppealService,
ApplicationExceptionService,
StudentAppealRequestsService,
OverawardControllerService,
ApplicationExceptionControllerService,
StudentAppealControllerService,
],
})
export class AppInstitutionsModule {}
2 changes: 2 additions & 0 deletions sources/packages/backend/apps/api/src/app.students.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
ApplicationControllerService,
OverawardStudentsController,
OverawardControllerService,
StudentAppealControllerService,
} from "./route-controllers";
import { AuthModule } from "./auth/auth.module";
import { ConfigModule } from "@sims/utilities/config";
Expand Down Expand Up @@ -112,6 +113,7 @@ import { ATBCIntegrationModule } from "@sims/integrations/atbc-integration";
DisbursementOverawardService,
NoteSharedService,
OverawardControllerService,
StudentAppealControllerService,
],
})
export class AppStudentsModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
} from "../models/pagination.dto";
import { Role } from "../../auth/roles.enum";
import { WorkflowClientService } from "@sims/services";
import { ApplicationExceptionControllerService } from "./application-exception.controller.service";

@AllowAuthorizedParty(AuthorizedParties.aest)
@Groups(UserGroups.AESTUser)
Expand All @@ -53,6 +54,7 @@ export class ApplicationExceptionAESTController extends BaseController {
constructor(
private readonly applicationExceptionService: ApplicationExceptionService,
private readonly workflowClientService: WorkflowClientService,
private readonly applicationExceptionControllerService: ApplicationExceptionControllerService,
) {
super();
}
Expand All @@ -70,23 +72,9 @@ export class ApplicationExceptionAESTController extends BaseController {
async getExceptionById(
@Param("exceptionId", ParseIntPipe) exceptionId: number,
): Promise<ApplicationExceptionAPIOutDTO> {
const applicationException =
await this.applicationExceptionService.getExceptionById(exceptionId);
if (!applicationException) {
throw new NotFoundException("Student application exception not found.");
}
return {
exceptionStatus: applicationException.exceptionStatus,
submittedDate: applicationException.createdAt,
noteDescription: applicationException.exceptionNote?.description,
assessedByUserName: getUserFullName(applicationException.assessedBy),
assessedDate: applicationException.assessedDate,
exceptionRequests: applicationException.exceptionRequests.map(
(request) => ({
exceptionName: request.exceptionName,
}),
),
};
return this.applicationExceptionControllerService.getExceptionDetails(
exceptionId,
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Injectable, NotFoundException } from "@nestjs/common";
import { ApplicationExceptionService } from "../../services";
import { getUserFullName } from "../../utilities";
import { ApplicationExceptionAPIOutDTO } from "./models/application-exception.dto";

@Injectable()
export class ApplicationExceptionControllerService {
constructor(
private readonly applicationExceptionService: ApplicationExceptionService,
) {}

/**
* Get a student application exception detected after the student application was
* submitted, for instance, when there are documents to be reviewed.
* @param exceptionId exception to be retrieved.
* @param studentId student id.
* @returns student application exception information.
*/
async getExceptionDetails(
exceptionId: number,
studentId?: number,
): Promise<ApplicationExceptionAPIOutDTO> {
const applicationException =
await this.applicationExceptionService.getExceptionDetails(
exceptionId,
studentId,
);
if (!applicationException) {
throw new NotFoundException("Student application exception not found.");
}
return {
exceptionStatus: applicationException.exceptionStatus,
submittedDate: applicationException.createdAt,
noteDescription: applicationException.exceptionNote?.description,
assessedByUserName: getUserFullName(applicationException.assessedBy),
assessedDate: applicationException.assessedDate,
exceptionRequests: applicationException.exceptionRequests.map(
(request) => ({
exceptionName: request.exceptionName,
}),
),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Controller, Get, Param, ParseIntPipe } from "@nestjs/common";
import {
AllowAuthorizedParty,
IsBCPublicInstitution,
HasStudentDataAccess,
} from "../../auth/decorators";
import { AuthorizedParties } from "../../auth/authorized-parties.enum";
import { ClientTypeBaseRoute } from "../../types";
import { ApiNotFoundResponse, ApiTags } from "@nestjs/swagger";
import BaseController from "../BaseController";
import { ApplicationExceptionAPIOutDTO } from "./models/application-exception.dto";
import { ApplicationExceptionControllerService } from "./application-exception.controller.service";

/**
* Application exception controller for institutions.
*/
@AllowAuthorizedParty(AuthorizedParties.institution)
@Controller("application-exception")
@IsBCPublicInstitution()
@HasStudentDataAccess("studentId")
@ApiTags(`${ClientTypeBaseRoute.Institution}-application-exception`)
export class ApplicationExceptionInstitutionsController extends BaseController {
constructor(
private readonly applicationExceptionControllerService: ApplicationExceptionControllerService,
) {
super();
}

/**
* Get a student application exception of a student.
* @param studentId student id.
* @param exceptionId exception to be retrieved.
* @returns student application exception information.
*/
@Get("student/:studentId/exception/:exceptionId")
@ApiNotFoundResponse({
description: "Student application exception not found.",
})
async getException(
@Param("studentId", ParseIntPipe) studentId: number,
@Param("exceptionId", ParseIntPipe) exceptionId: number,
): Promise<ApplicationExceptionAPIOutDTO> {
return this.applicationExceptionControllerService.getExceptionDetails(
exceptionId,
studentId,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@ import {
AssessmentNOAAPIOutDTO,
RequestAssessmentSummaryAPIOutDTO,
AwardDetailsAPIOutDTO,
RequestAssessmentTypeAPIOutDTO,
} from "./models/assessment.dto";
import {
ApiNotFoundResponse,
ApiTags,
ApiUnprocessableEntityResponse,
} from "@nestjs/swagger";
import { AssessmentControllerService } from "./assessment.controller.service";
import {
EducationProgramOfferingService,
ApplicationExceptionService,
} from "../../services";
import { ApplicationExceptionStatus } from "@sims/sims-db";

@AllowAuthorizedParty(AuthorizedParties.aest)
@Groups(UserGroups.AESTUser)
Expand All @@ -30,59 +24,23 @@ import { ApplicationExceptionStatus } from "@sims/sims-db";
export class AssessmentAESTController extends BaseController {
constructor(
private readonly assessmentControllerService: AssessmentControllerService,
private readonly educationProgramOfferingService: EducationProgramOfferingService,
private readonly applicationExceptionService: ApplicationExceptionService,
) {
super();
}

/**
* Get all pending and declined requests related to an application which would result
* a new assessment when that request is approved.
* @param applicationId application number.
* @param applicationId application id.
* @returns assessment requests or exceptions for a student application.
*/
@Get("application/:applicationId/requests")
async getRequestedAssessmentSummary(
@Param("applicationId", ParseIntPipe) applicationId: number,
): Promise<RequestAssessmentSummaryAPIOutDTO[]> {
const requestAssessmentSummary: RequestAssessmentSummaryAPIOutDTO[] = [];
const offeringChange =
await this.educationProgramOfferingService.getOfferingRequestsByApplicationId(
applicationId,
);
if (offeringChange) {
requestAssessmentSummary.push({
id: offeringChange.id,
submittedDate: offeringChange.submittedDate,
status: offeringChange.offeringStatus,
requestType: RequestAssessmentTypeAPIOutDTO.OfferingRequest,
programId: offeringChange.educationProgram.id,
});
}
const applicationExceptions =
await this.applicationExceptionService.getExceptionsByApplicationId(
applicationId,
ApplicationExceptionStatus.Pending,
ApplicationExceptionStatus.Declined,
);
// When a pending or denied application exception exist then no other request can exist
// for the given application.
if (applicationExceptions.length > 0) {
const applicationExceptionArray: RequestAssessmentSummaryAPIOutDTO[] =
applicationExceptions.map((applicationException) => ({
id: applicationException.id,
submittedDate: applicationException.createdAt,
status: applicationException.exceptionStatus,
requestType: RequestAssessmentTypeAPIOutDTO.StudentException,
}));
return requestAssessmentSummary.concat(applicationExceptionArray);
}
const appeals =
await this.assessmentControllerService.getPendingAndDeniedAppeals(
applicationId,
);
return requestAssessmentSummary.concat(appeals);
return this.assessmentControllerService.requestedStudentAssessmentSummary(
applicationId,
);
}

/**
Expand Down
Loading