-
Notifications
You must be signed in to change notification settings - Fork 14
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
Conversation
cancelledDate: IsNull(), | ||
}, | ||
{ | ||
cancelledDate: nowISODate, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pending = 0, | ||
Signed = 1, | ||
CancelledSystem = 2, | ||
CancelledOtherProvince = 4, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
...s/packages/backend/apps/api/src/route-controllers/application/application.aest.controller.ts
Show resolved
Hide resolved
There was a problem hiding this 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
Kudos, SonarCloud Quality Gate passed!
|
There was a problem hiding this 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
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( |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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({ |
There was a problem hiding this comment.
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,
},
);
There was a problem hiding this comment.
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)) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 😉
Great work @andrewsignori-aot . Added few comments. |
There was a problem hiding this 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.
There was a problem hiding this 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.
There was a problem hiding this 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({ |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this 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
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)