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

#1759 - Reissue MSFAA - Part 1 - New SIMS API Endpoint #1928

Merged
merged 10 commits into from
May 10, 2023

Conversation

andrewsignori-aot
Copy link
Collaborator

@andrewsignori-aot andrewsignori-aot commented May 5, 2023

  • Methos for MSFAA creation (used during assessment) and reissue were centralized to execute the below process in the same way.
    • Ensure that any pending MSFAA is canceled. A pending MSFAA is a never signed or canceled record.
    • Create the new MSFAA number.
    • Associate the new MSFAA number with any pending disbursement for the same student and same offering intensity.
  • Created a new API endpoint under the Ministry application controller to reissue the MSFAA.

E2E Tests for reissuing the MSFAA from SIMS API

ApplicationAESTController(e2e)-reissueMSFAA
√ Should reissue an MSFAA and associate with both disbursements when both disbursements are pending and the current MSFAA is signed but canceled. (449 ms)
√ Should reissue an MSFAA and associate with only the pending disbursement when one disbursement is not pending and the other is pending and the current MSFAA is canceled. (228 ms)
√ Should reissue an MSFAA and associate with only pending disbursements across multiple applications for the same offering intensity and same student when some disbursements are pending, some are not and there is at least on application from a different intensity. (427 ms)
√ Should throw a UnprocessableEntityException when the associated MSFAA is not cancelled. (152 ms)
√ Should throw a UnprocessableEntityException when there is no pending disbursement associated with the application. (141 ms)
√ Should throw a UnprocessableEntityException when the application is not in the expected status. (59 ms)
√ Should throw a NotFoundException when the application does not exist. (11 ms)

@andrewsignori-aot andrewsignori-aot self-assigned this May 6, 2023
@andrewsignori-aot andrewsignori-aot changed the title #1759 - Reissue MSFAA #1759 - Reissue MSFAA - Part 1 May 8, 2023
@andrewsignori-aot andrewsignori-aot changed the title #1759 - Reissue MSFAA - Part 1 #1759 - Reissue MSFAA - Part 1 - New SIMS API Endpoint May 8, 2023
cancelledDate: IsNull(),
},
{
cancelledDate: nowISODate,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm, I was thinking do we need any other indication to know this process happened as part of reissuing the new MSAFAA and was not canceled as part of the file integration? or do we care about that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File integrations contain new issuing provinces and system cancellation does not.
No requirements so far to make them different other than the above-mentioned.

* @returns number to be used for the next MSFAA.
*/
private async consumeNextSequence(
offeringIntensity: OfferingIntensity,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add it to the comment

*/
async reissueMSFAA(
referenceApplicationId: number,
auditUserId: number,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add it to the comment

const currentMSFAA = createFakeMSFAANumber(
{ student },
{
state: MSFAAStates.Signed | MSFAAStates.CancelledOtherProvince,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't this give the sum of 1 and 4 that is 5
image
does, it satisfy the condition that we need?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please review how the check is done.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry but I didn't understand why using the bitwise operations here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrepestana-aot please let me know if need more information and please review the code for the createFakeMSFAANumber method.
#1928 (comment)

msfaaNumber.student = relations.student;
msfaaNumber.referenceApplication = relations?.referenceApplication;

if (!options?.state || options.state & MSFAAStates.Pending) {
Copy link
Contributor

@ann-aot ann-aot May 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm, why we went for bitwise operations

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Pending = 0,
Signed = 1,
CancelledSystem = 2,
CancelledOtherProvince = 4,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we not using 3 due to bitwise operations?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, wouldn't it be good to comment here that a MSFAAStates 3 should be a "Signed" + "CancelledSystem"? That was my understanding at least.

Copy link
Collaborator Author

@andrewsignori-aot andrewsignori-aot May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The combination between the enum items is free. It can be as below or others.

  • Pending
  • Signed
  • Signed | CancelledSystem
  • Signed | CancelledSystem | CancelledOtherProvince
  • Signed | CancelledOtherProvince

Copy link
Contributor

@ann-aot ann-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work @andrewsignori-aot. Added some comments

@sonarqubecloud
Copy link

sonarqubecloud bot commented May 9, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

Copy link
Contributor

@ann-aot ann-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 Thanks for doing the changes

@github-actions
Copy link

github-actions bot commented May 9, 2023

Backend Unit Tests Coverage Report

Totals Coverage
Statements: 18.1% ( 2019 / 11155 )
Methods: 8.26% ( 119 / 1441 )
Lines: 20.89% ( 1771 / 8478 )
Branches: 10.44% ( 129 / 1236 )

@github-actions
Copy link

github-actions bot commented May 9, 2023

E2E Workflow Workers Coverage Report

Totals Coverage
Statements: 33.02% ( 177 / 536 )
Methods: 22.08% ( 17 / 77 )
Lines: 40.1% ( 158 / 394 )
Branches: 3.08% ( 2 / 65 )

@github-actions
Copy link

github-actions bot commented May 9, 2023

E2E Queue Consumers Coverage Report

Totals Coverage
Statements: 68.32% ( 371 / 543 )
Methods: 57.97% ( 40 / 69 )
Lines: 70.47% ( 327 / 464 )
Branches: 40% ( 4 / 10 )

@github-actions
Copy link

github-actions bot commented May 9, 2023

E2E SIMS API Coverage Report

Totals Coverage
Statements: 40.47% ( 2781 / 6872 )
Methods: 33.52% ( 299 / 892 )
Lines: 45.74% ( 2345 / 5127 )
Branches: 16.06% ( 137 / 853 )

const nowISODate = getISODateOnlyString(now);
// Cancel any pending MSFAA record that was never reported as signed or cancelled.
// This will ensure that the newly created MSFAA will be the only one valid.
await entityManager.getRepository(MSFAANumber).update(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that is is a very rare edge case scenario where

Student submit an application where MSFAA was valid during submission and before the disbursement was sent it expired and a new application got created with new MSFAA in the mean time.

Hence when reissuing msfaa we are checking for this MSFAA which was never reported or cancelled.

But I have a question here, while re-issuing should we not use this non-reported msfaa number? Is there anything like a policy which stops us doing it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to recall the exact reason to have them canceled actually. The goal was to ensure that when a new MSFAA is created there will be only one "not signed".
For instance, the student created an application, generated an MSFAA, and never completed it. After 3 years the same student comes back and a new MSFAA will be generated, in this situation that old record will be "cancelled by the system".
I believe that the idea was just to keep the DB looking better with only one possible not-signed/not-canceled MSFAA.

// Associate pending disbursements with the new MSFAA.
const disbursementScheduleRepo =
entityManager.getRepository(DisbursementSchedule);
const schedulesToUpdate = await disbursementScheduleRepo.find({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can directly use update like this right?

await disbursementScheduleRepo.update(
        {
          disbursementScheduleStatus: DisbursementScheduleStatus.Pending,
          studentAssessment: {
            application: { student: { id: studentId } },
            offering: { offeringIntensity: offeringIntensity },
          },
        },
        {
          msfaaNumber: newMSFAANumber,
          modifier: auditUser,
          updatedAt: now,
        },
      );

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my first attempt. Typeorm does not allow it apparently and, unless I am missing something, this is probably the reason why we do not have any other similar update like this.
Please notice that the main difference is that the "where" clause for this would include relations.

ApplicationStatus.Cancelled,
ApplicationStatus.Overwritten,
];
if (nowAllowedApplicationStatuses.includes(application.applicationStatus)) {
Copy link
Collaborator

@dheepak-aot dheepak-aot May 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why didn't we include this condition in the query?

Also the Query can be based on status [Assessment,Enrolment,Completed] which will pick just the eligible one and also we can skip line 260-265 based on application being in one of these status.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to "Why didn't we include this condition in the query?": the idea was to provide a more a specific error instead of a generic "Application not found" for this situation. I believe that in the past we talked about both approaches being acceptable.

About checking for "Assessment,Enrolment,Completed", the MSFAA as per the assessment workflow right now can be generated while the application is "In Progress", for instance (unless we change it). The idea was only to provide a certain level of validation and ensure that the offering would be present.

const [firstSchedule, secondSchedule] =
application.currentAssessment.disbursementSchedules;
const endpoint = `/aest/application/${application.id}/reissue-msfaa`;
const token = await getAESTToken(AESTGroups.BusinessAdministrators);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious to know, couldn't find the AEST group who can re-issue msfaa, is it BusinessAdministrators?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned today at the daily meeting, there was no requirement for a specific role. It will be added to the ticket and taken care of in the upcoming PR for this ticket 😉

@dheepak-aot
Copy link
Collaborator

Great work @andrewsignori-aot . Added few comments.

Copy link
Collaborator

@andrepestana-aot andrepestana-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job. I'm just not very sure about the bitwise operations idea and left some comments.

Copy link
Collaborator

@andrepestana-aot andrepestana-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation.

Copy link
Collaborator

@dheepak-aot dheepak-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarifications. LGTM. 👍

*/
@Post(":applicationId/reissue-msfaa")
@ApiNotFoundResponse({ description: "Application id not found." })
@ApiUnprocessableEntityResponse({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool implementation 👍

schedule.disbursementScheduleStatus ===
DisbursementScheduleStatus.Pending,
);
if (!pendingDisbursement) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Collaborator

@guru-aot guru-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work @andrewsignori-aot

@andrewsignori-aot andrewsignori-aot merged commit 674ad2f into main May 10, 2023
@andrewsignori-aot andrewsignori-aot deleted the feature/#1759-re-issue-msfaa branch May 10, 2023 19:04
@andrewsignori-aot andrewsignori-aot temporarily deployed to DEV May 10, 2023 19:04 — with GitHub Actions Inactive
@andrewsignori-aot andrewsignori-aot temporarily deployed to DEV May 10, 2023 19:08 — with GitHub Actions Inactive
@andrewsignori-aot andrewsignori-aot temporarily deployed to DEV May 10, 2023 19:08 — with GitHub Actions Inactive
@andrewsignori-aot andrewsignori-aot temporarily deployed to DEV May 10, 2023 19:19 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants