diff --git a/src/api/index.ts b/src/api/index.ts index 3c9a56c5..bbc40d77 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -28,7 +28,7 @@ app.use( "block-all-mixed-content": [], "font-src": ["'self'", "https:", "data:"], "frame-ancestors": ["'self'"], - "img-src": ["'self'", "data:", "https:"], + "img-src": ["'self'", "data:", "https:", "http:"], "object-src": ["'none'"], "script-src": ["'self'", "'unsafe-eval'"], // added https to accomodate esri components? "script-src-attr": ["'none'"], diff --git a/src/api/models/application.ts b/src/api/models/application.ts index 6436bb51..3dc77c28 100644 --- a/src/api/models/application.ts +++ b/src/api/models/application.ts @@ -549,9 +549,9 @@ export function FundingFromDraft(draft: any): any[] { if (draft.funding_sources && draft.funding_sources.sources) { for (let source of draft.funding_sources.sources) { let application_type_id = 1; - let csfa_amounts = draft.funding_sources.csfa_amounts || ""; - let loan_amount = draft.funding_sources.csfa_loan_amount; - let yea_request_amount = draft.funding_sources.yea_amount; + let csfa_amounts = draft.funding_sources.csfa_amounts ?? ""; + let loan_amount = draft.funding_sources.csfa_loan_amount ?? 0; + let yea_request_amount = draft.funding_sources.yea_amount ?? 0; if (source == "Canada Student Financial Assistance (Full-Time)") application_type_id = 2; else if (source == "Canada Student Financial Assistance (Part-Time)") application_type_id = 3; @@ -600,7 +600,7 @@ export function FundingFromDraft(draft: any): any[] { csl_request_amount: application_type_id == 2 ? cleanNumber(loan_amount) : 0, is_csl_full_amount: application_type_id == 2 && csfa_amounts == "Full amount loans and grants", is_csg_only: csfa_amounts == "Grants only", - yea_request_amount, + yea_request_amount: cleanNumber(yea_request_amount), }); } } @@ -645,8 +645,13 @@ export function StudentFromDraft(draft: any): any { studentUpdate.high_school_id = educations[0].school; } - studentUpdate.high_school_left_year = parseInt(educations[0].left_high_school.split("/")[0]); - studentUpdate.high_school_left_month = parseInt(educations[0].left_high_school.split("/")[1]); + try { + studentUpdate.high_school_left_year = parseInt(educations[0].left_high_school.split("/")[0]); + studentUpdate.high_school_left_month = parseInt(educations[0].left_high_school.split("/")[1]); + } catch (err) { + console.log("ERROR PARSING educations[0].left_high_school", educations[0]); + } + studentUpdate.is_crown_ward = draft.statistical.crown_ward; if (!isInteger(studentUpdate.high_school_id)) { diff --git a/src/api/routes/admin/csl-certificate-audit-report-router.ts b/src/api/routes/admin/csl-certificate-audit-report-router.ts index 8c71374b..4797e5e7 100644 --- a/src/api/routes/admin/csl-certificate-audit-report-router.ts +++ b/src/api/routes/admin/csl-certificate-audit-report-router.ts @@ -1,7 +1,7 @@ import express, { Request, Response } from "express"; import knex from "knex"; import { param } from "express-validator"; -import { DB_CONFIG } from "../../config"; +import { DB_CONFIG, FRONTEND_URL } from "../../config"; import { renderReportAsHtml, renderReportAsPdf } from "@/utils/express-handlebars-pdf-client"; import moment from "moment"; @@ -22,7 +22,7 @@ cslCertificateAuditReportRouter.get( try { let notSentData = await db.raw(`SELECT d.transaction_number cert_num, m.id msfaa_num, m.received_date, CONCAT(p.first_name,' ', p.last_name) [name], rt.description request_type, d.issue_date, - d.due_date, d.disbursed_amount * 100 amount, d.csl_cert_seq_number seq + d.due_date, COALESCE(d.disbursed_amount, 0.00) * 100 amount, d.csl_cert_seq_number seq FROM sfa.disbursement d INNER JOIN sfa.funding_request fr ON (fr.id = d.funding_request_id) INNER JOIN sfa.request_type rt ON (rt.id = fr.request_type_id) @@ -38,7 +38,7 @@ cslCertificateAuditReportRouter.get( let sentData = await db.raw(`SELECT d.transaction_number cert_num, m.id msfaa_num, m.received_date, CONCAT(p.first_name,' ', p.last_name) [name], rt.description request_type, d.issue_date, - d.due_date, d.disbursed_amount * 100 amount, d.csl_cert_seq_number seq + d.due_date, COALESCE(d.disbursed_amount, 0.00) * 100 amount, d.csl_cert_seq_number seq FROM sfa.disbursement d INNER JOIN sfa.funding_request fr ON (fr.id = d.funding_request_id) INNER JOIN sfa.request_type rt ON (rt.id = fr.request_type_id) @@ -69,6 +69,10 @@ cslCertificateAuditReportRouter.get( } let html = await renderReportAsHtml(TEMPLATE_PATH, data); + + // fix the image locations (likely just the Yukon Logo.png) + html = html.replace("http://localhost:3000", FRONTEND_URL); + res.send(html); } catch (error: any) { console.log(error); diff --git a/src/api/routes/portal/application-router.ts b/src/api/routes/portal/application-router.ts index 39480b59..843037ab 100644 --- a/src/api/routes/portal/application-router.ts +++ b/src/api/routes/portal/application-router.ts @@ -92,7 +92,7 @@ portalApplicationRouter.get("/:sub/:draftId/required-documents", async (req: Req for (let doc of returnDocs) { doc.meets_conditions = true; - // if (doc.condition) console.log(doc, doc.condition); + // if (doc.condition) console.log(doc, doc.condition); switch (doc.condition) { case "CSL Only": @@ -266,17 +266,28 @@ portalApplicationRouter.put("/:sub/:draftId/submit", async (req: Request, res: R let appIds = applications.map((a) => a.id); if (appIds.includes(parseInt(draftId))) { - let application = await applicationService.submitDraft(student, parseInt(draftId)); - - if (application) { - let draftDocs = await documentService.getDocumentsForDraft(parseInt(draftId)); - documentService.draftToApplication(parseInt(draftId), application.id); + await applicationService + .submitDraft(student, parseInt(draftId)) + .then(async (application) => { + if (application && application.id) { + await documentService.getDocumentsForDraft(parseInt(draftId)); + documentService.draftToApplication(parseInt(draftId), application?.id); + + return res.json({ data: application }); + } else { + console.log("Application created, but returned empty", application); + } + }) + .catch((err) => { + console.log("Error Submitting Application:", err); + return res.json({ error: err }); + }); - return res.json({ data: application }); - } + return; } } - res.status(404); + + res.status(404).send("Not found"); }); // deletes a draft application diff --git a/src/api/services/portal/application-service.ts b/src/api/services/portal/application-service.ts index ec6a8b5e..9833ea00 100644 --- a/src/api/services/portal/application-service.ts +++ b/src/api/services/portal/application-service.ts @@ -67,161 +67,195 @@ export class PortalApplicationService { return await db("application_draft").withSchema(schema).where({ id }).update(draftPartial); } - async submitDraft(student: any, id: number): Promise { - let draft = await db("application_draft").withSchema(schema).where({ id }).first(); - - if (draft) { - let draftApp = JSON.parse(draft.application_json); - let combinedApp = { ...draft, ...draftApp }; - let conv = ApplicationFromDraft(combinedApp); - - let parents = ParentsFromDraft(combinedApp); - if (parents && parents[0]) { - let relationship_id = parents[0].relationship; - delete parents[0].relationship; - let p1 = await db("person").withSchema(schema).insert(parents[0]).returning("*"); - - if (p1 && p1.length == 1) { - conv.parent1_id = p1[0].id; - } - - await db("student_persons").withSchema(schema).insert({ - student_id: student.id, - person_id: p1[0].id, - relationship_id, - is_active: true, - }); - } - - if (parents && parents[1]) { - let relationship_id = parents[1].relationship; - delete parents[1].relationship; - let p2 = await db("person").withSchema(schema).insert(parents[1]).returning("*"); - - if (p2 && p2.length == 1) { - conv.parent2_id = p2[0].id; - } - - await db("student_persons").withSchema(schema).insert({ - student_id: student.id, - person_id: p2[0].id, - relationship_id, - is_active: true, - }); - } - - let addresses = AddressesFromDraft(combinedApp); - if (addresses && addresses.length > 0) { - for (let address of addresses) { - address.person_id = student.person_id; - let newAddrId = await db("person_address").withSchema(schema).insert(address).returning("*"); - - if ( - newAddrId && - newAddrId.length > 0 && - combinedApp.addresses.primary == "Permanent" && - address.address_type_id == 1 - ) - (conv as any).primary_address_id = newAddrId[0].id; - else if ( - newAddrId && - newAddrId.length > 0 && - combinedApp.addresses.primary == "School" && - address.address_type_id == 3 - ) - (conv as any).primary_address_id = newAddrId[0].id; - } - } - - if (combinedApp.addresses.home_address1_id != -1 && combinedApp.addresses.primary == "Permanent") { - (conv as any).primary_address_id = combinedApp.addresses.home_address1_id; - } - if (combinedApp.addresses.home_address2_id != -1 && combinedApp.addresses.primary == "School") { - (conv as any).primary_address_id = combinedApp.addresses.home_address2_id; - } - - let person = PersonFromDraft(combinedApp); - await db("person").withSchema(schema).where({ id: student.person_id }).update(person); - - let consents = ConsentFromDraft(combinedApp); - if (consents && consents.length > 0) { - for (let consent of consents) { - consent.student_id = student.id; - await db("student_consent").withSchema(schema).insert(consent); - } - } - - let residences = ResidenceFromDraft(combinedApp); - if (residences && residences.length > 0) { - for (let residence of residences) { - residence.student_id = student.id; - await db("residence").withSchema(schema).insert(residence); - } - } - - let newApplication = await db("application").withSchema(schema).insert(conv).returning("*"); + async submitDraft(student: any, id: number): Promise { + return new Promise(async (resolve, reject) => { + let draft = await db("application_draft").withSchema(schema).where({ id }).first(); + + if (draft) { + let trx = await db.transaction(); + let errorMessage = "Loading loading application information"; + + try { + let draftApp = JSON.parse(draft.application_json); + let combinedApp = { ...draft, ...draftApp }; + let conv = ApplicationFromDraft(combinedApp); + + /* let parents = ParentsFromDraft(combinedApp); + if (parents && parents[0]) { + let relationship_id = parents[0].relationship; + delete parents[0].relationship; + + parents[0].id = 123; + console.log("I AM IN P1 makind bad",) + + let p1 = await trx("person") + .withSchema(schema) + .insert(parents[0]) + .returning("*") + .then(async (r) => { + if (r && r.length == 1) { + conv.parent1_id = r[0].id; + await trx("student_persons").withSchema(schema).insert({ + student_id: student.id, + person_id: r[0].id, + relationship_id, + is_active: true, + }); + } + }); + + console.log("I AM IN P1", p1) - if (newApplication) { - let fundings = FundingFromDraft(combinedApp); - if (fundings && fundings.length > 0) { - for (let funding of fundings) { - funding.application_id = newApplication[0].id; - await db("funding_request").withSchema(schema).insert(funding); } - } - let otherFundings = OtherFundingFromDraft(combinedApp); - if (otherFundings && otherFundings.length > 0) { - for (let funding of otherFundings) { - funding.application_id = newApplication[0].id; - await db("agency_assistance").withSchema(schema).insert(funding); + if (parents && parents[1]) { + let relationship_id = parents[1].relationship; + delete parents[1].relationship; + let p2 = await trx("person").withSchema(schema).insert(parents[1]).returning("*"); + + if (p2 && p2.length == 1) { + conv.parent2_id = p2[0].id; + await trx("student_persons").withSchema(schema).insert({ + student_id: student.id, + person_id: p2[0].id, + relationship_id, + is_active: true, + }); + } + } */ + + let errorMessage = "Error creating addresses"; + let addresses = AddressesFromDraft(combinedApp); + if (addresses && addresses.length > 0) { + for (let address of addresses) { + address.person_id = student.person_id; + let newAddrId = await trx("person_address").withSchema(schema).insert(address).returning("*"); + + if ( + newAddrId && + newAddrId.length > 0 && + combinedApp.addresses.primary == "Permanent" && + address.address_type_id == 1 + ) + (conv as any).primary_address_id = newAddrId[0].id; + else if ( + newAddrId && + newAddrId.length > 0 && + combinedApp.addresses.primary == "School" && + address.address_type_id == 3 + ) + (conv as any).primary_address_id = newAddrId[0].id; + } } - } - let incomes = IncomeFromDraft(combinedApp); - if (incomes && incomes.length > 0) { - for (let income of incomes) { - income.application_id = newApplication[0].id; - await db("income").withSchema(schema).insert(income); + if (combinedApp.addresses.home_address1_id != -1 && combinedApp.addresses.primary == "Permanent") { + (conv as any).primary_address_id = combinedApp.addresses.home_address1_id; + } + if (combinedApp.addresses.home_address2_id != -1 && combinedApp.addresses.primary == "School") { + (conv as any).primary_address_id = combinedApp.addresses.home_address2_id; } - } - let expenses = ExpensesFromDraft(combinedApp); - if (expenses && expenses.length > 0) { - for (let expense of expenses) { - expense.application_id = newApplication[0].id; - await db("expense").withSchema(schema).insert(expense); + errorMessage = "Error updating person record"; + let person = PersonFromDraft(combinedApp); + await trx("person").withSchema(schema).where({ id: student.person_id }).update(person); + + errorMessage = "Error creating consents"; + let consents = ConsentFromDraft(combinedApp); + if (consents && consents.length > 0) { + for (let consent of consents) { + consent.student_id = student.id; + await trx("student_consent").withSchema(schema).insert(consent); + } } - } - let depends = DependantsFromDraft(combinedApp); - if (depends && depends.length > 0) { - for (let depend of depends) { - let elig = depend.eligibility; - delete depend.eligibility; - depend.student_id = student.id; - let newDep = await db("dependent").withSchema(schema).insert(depend).returning("*"); - - elig.application_id = newApplication[0].id; - elig.dependent_id = newDep[0].id; - await db("dependent_eligibility").withSchema(schema).insert(elig); + errorMessage = "Error creating residences"; + let residences = ResidenceFromDraft(combinedApp); + if (residences && residences.length > 0) { + for (let residence of residences) { + residence.student_id = student.id; + await trx("residence").withSchema(schema).insert(residence); + } + } + errorMessage = "Error creating new application"; + let newApplication = await trx("application").withSchema(schema).insert(conv).returning("*"); + + if (newApplication) { + errorMessage = "Error creating funding requests"; + let fundings = FundingFromDraft(combinedApp); + if (fundings && fundings.length > 0) { + for (let funding of fundings) { + funding.application_id = newApplication[0].id; + await trx("funding_request").withSchema(schema).insert(funding); + } + } + errorMessage = "Error creating other funding"; + + let otherFundings = OtherFundingFromDraft(combinedApp); + if (otherFundings && otherFundings.length > 0) { + for (let funding of otherFundings) { + funding.application_id = newApplication[0].id; + await trx("agency_assistance").withSchema(schema).insert(funding); + } + } + + errorMessage = "Error creating income records"; + let incomes = IncomeFromDraft(combinedApp); + if (incomes && incomes.length > 0) { + for (let income of incomes) { + income.application_id = newApplication[0].id; + await trx("income").withSchema(schema).insert(income); + } + } + + errorMessage = "Error creating expense records"; + let expenses = ExpensesFromDraft(combinedApp); + if (expenses && expenses.length > 0) { + for (let expense of expenses) { + expense.application_id = newApplication[0].id; + await trx("expense").withSchema(schema).insert(expense); + } + } + + errorMessage = "Error creating dependent records"; + let depends = DependantsFromDraft(combinedApp); + if (depends && depends.length > 0) { + for (let depend of depends) { + let elig = depend.eligibility; + delete depend.eligibility; + depend.student_id = student.id; + let newDep = await trx("dependent").withSchema(schema).insert(depend).returning("*"); + + elig.application_id = newApplication[0].id; + elig.dependent_id = newDep[0].id; + await trx("dependent_eligibility").withSchema(schema).insert(elig); + } + } + + errorMessage = "Error updating student record"; + let studentUpdate = StudentFromDraft(combinedApp); + await trx("student").withSchema(schema).where({ id: student.id }).update(studentUpdate); + + errorMessage = "Error setting draft status"; + await trx("application_draft").withSchema(schema).where({ id }).update({ + status: "Submitted", + application_id: newApplication[0].id, + submit_date: new Date(), + }); } - } - let studentUpdate = StudentFromDraft(combinedApp); - await db("student").withSchema(schema).where({ id: student.id }).update(studentUpdate); + errorMessage = ""; - await db("application_draft").withSchema(schema).where({ id }).update({ - status: "Submitted", - application_id: newApplication[0].id, - submit_date: new Date(), - }); + await trx.commit(); + resolve(newApplication[0]); + } catch (e: any) { + trx.rollback(); + console.log("ERROR SUBMITTING APPLICATION", e); + return reject(errorMessage); + } } - return newApplication[0]; - } - - return undefined; + resolve(undefined); + }); } async deleteDraft(id: number) { diff --git a/src/web/public/yukon-logo.png b/src/web/public/yukon-logo.png new file mode 100644 index 00000000..b348b1b1 Binary files /dev/null and b/src/web/public/yukon-logo.png differ diff --git a/src/web/src/components/application/assessments/store/csl-part-time.js b/src/web/src/components/application/assessments/store/csl-part-time.js index cac81f25..154fcb1b 100644 --- a/src/web/src/components/application/assessments/store/csl-part-time.js +++ b/src/web/src/components/application/assessments/store/csl-part-time.js @@ -61,12 +61,15 @@ const getters = { return (state.assessment?.student_ln150_income ?? 0) + (state.assessment?.spouse_ln150_income ?? 0); }, requestedAmount(state) { - if (state.fundingRequest?.is_csg_only === true) return "None"; - if (state.fundingRequest?.is_csl_full_amount === true) return "Full"; + if (state.fundingRequest?.is_csg_only === true) return "CSG Only"; + if (state.fundingRequest?.is_csl_full_amount === true) return "Full Amount"; return state.fundingRequest?.csl_request_amount ?? 0; }, totalGrants(state) { - return 0; // this needs to pull from CSGPT, CSGDep PT, CSG Disability + let value = 0; + // this needs to pull from CSGPT, CSGDep PT, CSG Disability + state.assessment.total_grant_awarded = value; + return value; }, maxAllowable(state) { @@ -113,8 +116,11 @@ const getters = { }, assessedAmount(state, getters) { - if (getters.pastThreshold) return 0; - return Math.min(getters.maxAllowable, getters.totalCosts - getters.totalGrants); + let value = 0; + if (!getters.pastThreshold) value = Math.min(getters.maxAllowable, getters.totalCosts - getters.totalGrants); + + state.assessment.assessed_amount = value; + return value; }, actualAward(state, getters) { let returned = `${state.assessment?.return_uncashable_cert}` ?? "0"; @@ -229,7 +235,8 @@ const actions = { study_weeks: weeksBetween(application.classes_start_date, application.classes_end_date), family_size: familySize, dependent_count: dependentCount, - study_province_id: application.study_province_id, + study_province_id: application.csl_previous_province_id, + spouse_province_id: application.spouse_last_jurisdiction_id, tuition_estimate: application.tuition_estimate_amount, books_supplies_cost: application.books_supplies_cost, student_ln150_income: application.student_ln150_income, @@ -250,17 +257,16 @@ const actions = { day_care_actual: monthlyDayCare, assessment_type_id: 1, - spouse_province_id: null, student_contrib_exempt: "N", spouse_contrib_exempt: "N", - period: 9, total_grant_awarded: 0, - assessed_amount: 88888, + assessed_amount: 0, student_contribution_review: "No", spouse_contribution_review: "No", parent_contribution_review: "No", }; + assessment.period = assessment.study_months <= 4 ? "S" : "P"; commit("SET_ASSESSMENT", assessment); } @@ -296,7 +302,8 @@ const actions = { study_weeks: weeksBetween(application.classes_start_date, application.classes_end_date), family_size: familySize, dependent_count: dependentCount, - study_province_id: application.study_province_id, + study_province_id: application.csl_previous_province_id, + spouse_province_id: application.spouse_last_jurisdiction_id, tuition_estimate: application.tuition_estimate_amount, books_supplies_cost: application.books_supplies_cost, student_ln150_income: application.student_ln150_income, @@ -317,17 +324,16 @@ const actions = { day_care_actual: monthlyDayCare, assessment_type_id: 1, - spouse_province_id: null, student_contrib_exempt: "N", spouse_contrib_exempt: "N", - period: 9, total_grant_awarded: 0, - assessed_amount: 88888, + assessed_amount: 0, student_contribution_review: "No", spouse_contribution_review: "No", parent_contribution_review: "No", }; + assessment.period = assessment.study_months <= 4 ? "S" : "P"; commit("SET_ASSESSMENT", assessment); dispatch("save"); diff --git a/src/web/src/components/application/assessments/views/CSLPT.vue b/src/web/src/components/application/assessments/views/CSLPT.vue index 14a42df9..ffcfb1e5 100644 --- a/src/web/src/components/application/assessments/views/CSLPT.vue +++ b/src/web/src/components/application/assessments/views/CSLPT.vue @@ -21,8 +21,11 @@ BASE COSTS - AWARD - MSFAA + Grant + Dependent Grant + Disability Grant + AWARD + MSFAA @@ -37,13 +40,22 @@ + + + + + + + + + -
+