diff --git a/src/api/repositories/assessment/assessment-cslft-repository-v2.ts b/src/api/repositories/assessment/assessment-cslft-repository-v2.ts
index 671115ed..b91ab1c3 100644
--- a/src/api/repositories/assessment/assessment-cslft-repository-v2.ts
+++ b/src/api/repositories/assessment/assessment-cslft-repository-v2.ts
@@ -138,6 +138,9 @@ export class AssessmentCslftRepositoryV2 {
await this.load(parseInt(`${fundingRequestId}`));
let assess = await this.calculateBase();
+
+ const existingOA = await this.db("sfa.assessment").where({ id: assessmentId }).select("over_award").first();
+ if (existingOA) assess.over_award = existingOA.over_award;
assess.id = parseInt(`${assessmentId}`);
await this.calculateCosts(assess);
@@ -145,7 +148,6 @@ export class AssessmentCslftRepositoryV2 {
await this.calculateParental(assess);
let full = await this.postLoad(assess, this.application.id);
-
assess.csl_assessed_need = full.csl_assessed_need;
await this.calculateAward(assess);
@@ -471,13 +473,18 @@ export class AssessmentCslftRepositoryV2 {
"disbursed_amount"
);
+ const studentOverawards = await this.db("sfa.overaward").where({ student_id: this.student.id });
+ const assessmentOverawards = studentOverawards.filter((o) => input.id == o.assessment_id);
+
+ input.net_overaward = sumBy(studentOverawards, "amount");
+ input.has_overaward_recorded = assessmentOverawards.find((o) => o.amount < 0) != null;
+ input.has_overaward_applied = assessmentOverawards.find((o) => o.amount > 0) != null;
//over_award can only be as big as the calculated = clear partial
+ console.log("DOING MATH", input.over_award, input.assessed_amount);
+
input.net_amount =
- input.assessed_amount /* -
- (input.over_award ?? 0) */ -
- input.previous_cert -
- input.previous_disbursement /* -
+ input.assessed_amount /* - (input.over_award ?? 0) */ - input.previous_cert - input.previous_disbursement /* -
(input.return_uncashable_cert ?? 0) */;
input.net_amount = Math.round(input.net_amount * 100) / 100;
@@ -538,7 +545,10 @@ export class AssessmentCslftRepositoryV2 {
);
const calculated_award: number = Math.max(0, Math.round(calculated_award_min));
+ console.log("DOING MATH 2", assess.over_award);
+
if (assess.csl_full_amt_flag == 0) {
+ console.log("M1");
assess.assessed_amount = Math.max(
Math.min(calculated_award, assess.csl_request_amount ?? 0) -
(assess.over_award ?? 0) -
@@ -546,6 +556,7 @@ export class AssessmentCslftRepositoryV2 {
0
);
} else {
+ console.log("M2");
assess.assessed_amount =
Math.max((calculated_award ?? 0) - (assess.over_award ?? 0), 0) - (assess.return_uncashable_cert ?? 0);
}
@@ -956,7 +967,7 @@ export class AssessmentCslftRepositoryV2 {
(this.cslLookup.low_income_student_contrib_amount ?? 0) / e_month +
((family_income - income_threshold) / e_month) * ((this.cslLookup.student_contrib_percent ?? 0) / 100);
- const weekly_calc = weekly_student_contrib * Math.min(assess.study_weeks ?? 0, max_weeks) ?? 0;
+ const weekly_calc = weekly_student_contrib * Math.min(assess.study_weeks ?? 0, max_weeks);
assess.student_expected_contribution = Math.min(weekly_calc, this.cslLookup.student_contrib_max_amount ?? 0);
assess.student_expected_contribution = Math.max(
@@ -1041,14 +1052,14 @@ export class AssessmentCslftRepositoryV2 {
let ftGrant = this.otherFunds.find((f) => f.request_type_id == 35);
let ftDepGrant = this.otherFunds.find((f) => f.request_type_id == 32);
let disGrant = this.otherFunds.find((f) => f.request_type_id == 29);
- let disSEGrant = this.otherFunds.find((f) => f.request_type_id == 30);
+ //let disSEGrant = this.otherFunds.find((f) => f.request_type_id == 30);
let topup = this.otherFunds.find((f) => f.request_type_id == 28);
let totalGrants =
(ftGrant?.disbursed_amount ?? 0) +
(ftDepGrant?.disbursed_amount ?? 0) +
(disGrant?.disbursed_amount ?? 0) +
- (disSEGrant?.disbursed_amount ?? 0) +
+ //(disSEGrant?.disbursed_amount ?? 0) +
(topup?.disbursed_amount ?? 0);
assess.total_grant_awarded = totalGrants;
@@ -1060,7 +1071,15 @@ export class AssessmentCslftRepositoryV2 {
const calculated_award_min = Math.min(sixty - (assess.total_grant_awarded ?? 0), max_allowable ?? 0);
const calculated_award: number = Math.max(0, Math.round(calculated_award_min));
- assess.over_award = this.student.pre_over_award_amount ?? 0;
+ /* const totalOveraward = await this.db("sfa.overaward").where({
+ student_id: this.application.student_id,
+ }).sum("amount as total").first();
+
+ console.log("Total Overaward", totalOveraward?.total); */
+
+ //assess.over_award = assess.over_award ?? 0; // totalOveraward?.total ?? 0;
+
+ console.log("Setting Overaward", assess.over_award);
// Calculate the totaln_disbursments_required
if (assess.csl_full_amt_flag == 0) {
@@ -1461,4 +1480,8 @@ interface CSLFTAssessmentFull extends CSLFTAssessmentBase {
student_other_resources: number;
student_contrib_exempt_reason?: string;
spouse_contrib_exempt_reason?: string;
+
+ net_overaward: number;
+ has_overaward_recorded: boolean;
+ has_overaward_applied: boolean;
}
diff --git a/src/api/routes/admin/csg-threshold-router.ts b/src/api/routes/admin/csg-threshold-router.ts
index 70cbaed3..1d1b2987 100644
--- a/src/api/routes/admin/csg-threshold-router.ts
+++ b/src/api/routes/admin/csg-threshold-router.ts
@@ -46,19 +46,23 @@ csgThresholdRouter.delete(
async (req: Request, res: Response) => {
const { assessment_id, funding_request_id } = req.params;
- let disbursements = await db("sfa.disbursement").where({ assessment_id });
+ try {
+ let disbursements = await db("sfa.disbursement").where({ assessment_id });
- if (disbursements) {
- let eCertDisbursements = disbursements.filter((d) => d.csl_cert_seq_number);
+ if (disbursements) {
+ let eCertDisbursements = disbursements.filter((d) => d.csl_cert_seq_number);
- if (eCertDisbursements.length)
- return res.status(400).json({ errors: ["Cannot delete an assessment with eCert disbursements"] });
+ if (eCertDisbursements.length)
+ return res.status(400).json({ errors: ["Cannot delete an assessment with eCert disbursements"] });
- await db("sfa.disbursement").where({ assessment_id }).delete();
- }
+ await db("sfa.disbursement").where({ assessment_id }).delete();
+ }
- await db("sfa.assessment").where({ id: assessment_id }).delete();
- return res.status(200).json({ data: "Assessment Deleted" });
+ await db("sfa.assessment").where({ id: assessment_id }).delete();
+ return res.status(200).json({ data: "Assessment Deleted" });
+ } catch (e) {
+ res.status(400).json({ error: "Error deleting assessment - most likely due to applied overawards" });
+ }
}
);
@@ -73,7 +77,6 @@ csgThresholdRouter.put(
assessed_date,
csl_over_reason_id,
csl_non_reason_id,
- over_award,
return_uncashable_cert,
student_contribution_override,
spouse_contribution_override,
@@ -108,7 +111,6 @@ csgThresholdRouter.put(
csl_non_reason_id,
csl_over_reason_id,
return_uncashable_cert: cleanNumberOptional(return_uncashable_cert),
- over_award: cleanNumberOptional(over_award),
student_contribution_override: cleanNumberOptional(student_contribution_override),
spouse_contribution_override: cleanNumberOptional(spouse_contribution_override),
parent_contribution_override: cleanNumberOptional(parent_contribution_override),
@@ -136,7 +138,6 @@ csgThresholdRouter.put(
assessed_amount: calced.assessed_amount,
csl_assessed_need: calced.csl_assessed_need,
return_uncashable_cert: cleanNumberOptional(return_uncashable_cert),
- over_award: cleanNumberOptional(over_award),
student_contribution_override: cleanNumberOptional(student_contribution_override),
spouse_contribution_override: cleanNumberOptional(spouse_contribution_override),
parent_contribution_override: cleanNumberOptional(parent_contribution_override),
@@ -164,7 +165,6 @@ csgThresholdRouter.put(
(recalc as any).student_contribution_override = null;
(recalc as any).spouse_contribution_override = null;
(recalc as any).parent_contribution_override = null;
- (recalc as any).over_award = null;
(recalc as any).return_uncashable_cert = null;
(recalc as any).csl_non_reason_id = null;
(recalc as any).csl_over_reason_id = null;
@@ -197,9 +197,6 @@ csgThresholdRouter.post(
if (!loaded) return res.status(500).send("Error loading assessment");
- let existingOveraward = student.pre_over_award_amount ?? 0;
- existingOveraward += Math.abs(loaded.net_amount);
-
const amount = Math.round(loaded.net_amount * 100) / 100;
await db("sfa.overaward").insert({
@@ -213,8 +210,6 @@ csgThresholdRouter.post(
amount,
});
- //await db("sfa.student").where({ id: application.student_id }).update({ pre_over_award_amount: existingOveraward });
-
//await db("sfa.assessment").where({ id: assessment_id }).update(recalc);
return res.status(200).json({ data: "Assessment Saved" });
}
@@ -238,10 +233,38 @@ csgThresholdRouter.post(
if (!loaded) return res.status(500).send("Error loading assessment");
- let existingOveraward = student.pre_over_award_amount ?? 0;
- existingOveraward -= Math.abs(loaded.net_amount);
+ if (loaded.net_overaward < 0 && loaded.net_amount > 0) {
+ const toClear = Math.min(loaded.net_amount, Math.abs(loaded.net_overaward));
+
+ await db("sfa.overaward").insert({
+ student_id: student.id,
+ academic_year_id: application.academic_year_id,
+ application_id: fundingRequest.application_id,
+ funding_request_id,
+ assessment_id,
+ created_by: req.user.email,
+ note: "Created from overaward in CLSFT Assessment",
+ amount: toClear,
+ });
+
+ await db("sfa.assessment").where({ id: assessment_id }).update({
+ over_award: toClear,
+ over_award_applied_flg: "Yes",
+ });
+
+ let recalc = await repo.create(funding_request_id, assessment_id);
+
+ delete (recalc as any).id;
+ delete (recalc as any).assessment_type_id;
+ (recalc as any).student_contribution_override = null;
+ (recalc as any).spouse_contribution_override = null;
+ (recalc as any).parent_contribution_override = null;
+ (recalc as any).return_uncashable_cert = null;
+ (recalc as any).csl_non_reason_id = null;
+ (recalc as any).csl_over_reason_id = null;
- await db("sfa.student").where({ id: application.student_id }).update({ pre_over_award_amount: existingOveraward });
+ await db("sfa.assessment").where({ id: assessment_id }).update(recalc);
+ }
return res.status(200).json({ data: "Assessment Saved" });
}
diff --git a/src/web/src/components/application/assessments/components/csl-ft/tab-award.vue b/src/web/src/components/application/assessments/components/csl-ft/tab-award.vue
index 1129c73a..652e05d2 100644
--- a/src/web/src/components/application/assessments/components/csl-ft/tab-award.vue
+++ b/src/web/src/components/application/assessments/components/csl-ft/tab-award.vue
@@ -169,7 +169,7 @@
Disburse
+
+ This student has an outstanding overaward balance.
+
+
+ This assessment has an overward applied.
+
+
+ This assessment has an overward recorded.
+
diff --git a/src/web/src/components/application/assessments/store/csl-full-time.js b/src/web/src/components/application/assessments/store/csl-full-time.js
index 4c1f7a38..8a162477 100644
--- a/src/web/src/components/application/assessments/store/csl-full-time.js
+++ b/src/web/src/components/application/assessments/store/csl-full-time.js
@@ -238,19 +238,25 @@ const actions = {
});
},
- async clearOveraward() {
+ async clearOveraward({ dispatch }) {
console.log("CLEARING OVERAWRD");
let url = `${CSG_THRESHOLD_URL}/funding-request/${state.fundingRequest.id}/assessment/${state.assessment.id}/clear-overaward`;
return axios.post(url).then(async (resp) => {
- console.log("RESP", resp);
+ dispatch("loadCSLFTAssessment", {
+ applicationId: state.fundingRequest.application_id,
+ assessmentId: state.assessment.id,
+ });
});
},
- async recordOveraward({ state }) {
+ async recordOveraward({ dispatch, state }) {
let url = `${CSG_THRESHOLD_URL}/funding-request/${state.fundingRequest.id}/assessment/${state.assessment.id}/record-overaward`;
return axios.post(url).then(async (resp) => {
- console.log("RESP", resp);
+ dispatch("loadCSLFTAssessment", {
+ applicationId: state.fundingRequest.application_id,
+ assessmentId: state.assessment.id,
+ });
});
},
async deleteAssessment() {
diff --git a/src/web/src/components/application/assessments/views/CSLFT.vue b/src/web/src/components/application/assessments/views/CSLFT.vue
index 254419f6..e46b0946 100644
--- a/src/web/src/components/application/assessments/views/CSLFT.vue
+++ b/src/web/src/components/application/assessments/views/CSLFT.vue
@@ -12,9 +12,9 @@
Total Awarded: {{ totalAwarded }}
- {{ percentAwarded }} of Need
+ > -->
mdi-pin-outline
Record Overaward
-
+
mdi-eraser
- Clear Student Overaward
+ Apply Student Overaward
mdi-trash-can-outline
@@ -76,7 +76,7 @@
>CSG-PTDEP
{{ formatMoney(depAmount) }} -->
- Award
{{ formatMoney(assessment.net_amount) }}
+ Award
{{ formatMoney(assessment.assessed_amount) }}
MSFAA
@@ -188,10 +188,11 @@ export default {
...mapState("cslFullTimeStore", ["isLoading", "assessment", "fundingRequest", "disbursements", "msfaa"]),
...mapGetters(["cslClassifications", "disbursementTypes", "changeReasons"]),
totalAwarded() {
- return this.formatMoney(this.assessment.net_amount);
+ // this should be a sum of all disbursements amounts for all assessments
+ return this.formatMoney(this.assessment.assessed_amount);
},
percentAwarded() {
- return `${Math.round((100 * this.assessment.net_amount) / this.assessment.total_costs)}%`;
+ return `${Math.round((100 * this.assessment.assessed_amount) / this.assessment.total_costs)}%`;
},
assessmentItems() {
if (this.fundingRequest) {
@@ -237,11 +238,21 @@ export default {
canAddAssessment() {
return this.canSave && this.disbursements.length > 0;
},
- canClearOveraward() {
- return this.assessment.over_award && this.assessment.over_award > 0;
+ canApplyOveraward() {
+ return (
+ this.assessment.id &&
+ this.canSave &&
+ this.assessment.net_amount > 0 &&
+ !(this.assessment.has_overaward_applied || this.assessment.has_overaward_recorded)
+ );
},
canRecordOveraward() {
- return this.canSave && this.assessment.net_amount < 0 && (this.student.pre_over_award_amount ?? 0) < 1;
+ return (
+ this.assessment.id &&
+ this.canSave &&
+ this.assessment.net_amount < 0 &&
+ !(this.assessment.has_overaward_applied || this.assessment.has_overaward_recorded)
+ );
},
canDelete() {
return this.disbursements.length == 0;
@@ -304,16 +315,23 @@ export default {
async addAssessmentClick() {
await this.createAssessment();
},
- async clearOverawardClick() {
+ async applyOverawardClick() {
await this.clearOveraward();
},
async recordOverawardClick() {
- await this.recordOveraward();
+ await this.recordOveraward().then(() => {
+ this.showSuccess("Overaward recorded");
+ });
},
async deleteClick() {
- await this.deleteAssessment().then((resp) => {
- this.$router.push(`/application/${this.application.id}/cslft/${this.fundingRequest.id}`);
- });
+ await this.deleteAssessment()
+ .then((resp) => {
+ this.$router.push(`/application/${this.application.id}/cslft/${this.fundingRequest.id}`);
+ })
+ .catch((err) => {
+ console.log(err);
+ this.showError(err.response.data.error);
+ });
},
},
};
diff --git a/src/web/src/components/student/Screening.vue b/src/web/src/components/student/Screening.vue
index cdd02c13..3911ae3f 100644
--- a/src/web/src/components/student/Screening.vue
+++ b/src/web/src/components/student/Screening.vue
@@ -84,8 +84,7 @@