Skip to content

Commit

Permalink
Merge pull request #324 from icefoganalytics/test
Browse files Browse the repository at this point in the history
More overawards
  • Loading branch information
datajohnson authored Dec 17, 2024
2 parents 3322fea + d104026 commit 7b64374
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 52 deletions.
41 changes: 32 additions & 9 deletions src/api/repositories/assessment/assessment-cslft-repository-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,16 @@ 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);
await this.calculateContribution(assess);
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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -538,14 +545,18 @@ 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) -
(assess.return_uncashable_cert ?? 0),
0
);
} else {
console.log("M2");
assess.assessed_amount =
Math.max((calculated_award ?? 0) - (assess.over_award ?? 0), 0) - (assess.return_uncashable_cert ?? 0);
}
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
65 changes: 44 additions & 21 deletions src/api/routes/admin/csg-threshold-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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" });
}
}
);

Expand All @@ -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,
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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({
Expand All @@ -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" });
}
Expand All @@ -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" });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
</v-col>
<v-col cols="12" md="3">
<v-text-field
label="Outstanding overaward"
label="Overaward applied"
readonly
outlined
dense
Expand Down Expand Up @@ -288,6 +288,17 @@
<v-btn color="primary" class="ml-3" @click="disburseClick">Disburse</v-btn>
</v-col>
</v-row>

<v-alert v-if="assessment.net_overaward < 0" class="mt-4" dense type="warning"
>This student has an outstanding overaward balance.</v-alert
>

<v-alert v-if="assessment.has_overaward_applied" class="mt-4" dense type="warning">
This assessment has an overward applied.
</v-alert>
<v-alert v-if="assessment.has_overaward_recorded" class="mt-4" dense type="warning">
This assessment has an overward recorded.
</v-alert>
</div>
<v-divider class="my-5" />
<cslft-disbursements v-on:showError="showError" v-on:showSuccess="showSuccess"></cslft-disbursements>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
48 changes: 33 additions & 15 deletions src/web/src/components/application/assessments/views/CSLFT.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
<v-chip class="my-0 ml-3 text-regular" color="brown lighten-4" style="font-weight: 400"
>Total Awarded: {{ totalAwarded }}</v-chip
>
<v-chip class="my-0 ml-3" color="indigo lighten-4" style="font-weight: 400"
<!-- <v-chip class="my-0 ml-3" color="indigo lighten-4" style="font-weight: 400"
>{{ percentAwarded }} of Need</v-chip
>
> -->
<v-chip
class="my-0 ml-3"
:color="msfaa?.msfaa_status == 'Received' ? 'green lighten-3' : 'orange lighten-4'"
Expand Down Expand Up @@ -51,9 +51,9 @@
<v-list-item-icon><v-icon>mdi-pin-outline</v-icon></v-list-item-icon>
<v-list-item-title>Record Overaward</v-list-item-title>
</v-list-item>
<v-list-item v-if="canClearOveraward" @click="clearOverawardClick">
<v-list-item v-if="canApplyOveraward" @click="applyOverawardClick">
<v-list-item-icon><v-icon>mdi-eraser</v-icon></v-list-item-icon>
<v-list-item-title>Clear Student Overaward</v-list-item-title>
<v-list-item-title>Apply Student Overaward</v-list-item-title>
</v-list-item>
<v-list-item v-if="canDelete" @click="deleteClick">
<v-list-item-icon><v-icon>mdi-trash-can-outline</v-icon></v-list-item-icon>
Expand All @@ -76,7 +76,7 @@
>CSG-PTDEP<br />
{{ formatMoney(depAmount) }}</v-tab
> -->
<v-tab key="3">Award<br />{{ formatMoney(assessment.net_amount) }}</v-tab>
<v-tab key="3">Award<br />{{ formatMoney(assessment.assessed_amount) }}</v-tab>
<v-tab key="4">MSFAA</v-tab>
</v-tabs>
<v-divider></v-divider>
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
});
},
},
};
Expand Down
Loading

0 comments on commit 7b64374

Please sign in to comment.