From 6abb0fdbe95f71f89a6cf933ea28ff079576ea01 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Wed, 11 Oct 2023 14:10:36 -0700 Subject: [PATCH 1/9] Reformat --- .../cheque-req-list-repository.ts | 629 +++++++++--------- .../routes/admin/cheque-req-list-router.ts | 68 +- 2 files changed, 330 insertions(+), 367 deletions(-) diff --git a/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts b/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts index dbe4bf5c..38573e27 100644 --- a/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts +++ b/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts @@ -3,98 +3,91 @@ import { BaseRepository } from "../base-repository"; import _ from "lodash"; interface ChequeReqDTO { - request_type_id: number, - disbursement_id: number, - disbursed_amount: number, - bg_id: number, - issue_date: Date | string, - f_year: number -}; + request_type_id: number; + disbursement_id: number; + disbursed_amount: number; + bg_id: number; + issue_date: Date | string; + f_year: number; +} export class ChequeReqList extends BaseRepository { - - //private applicationRepo: ApplicationRepository; - //private application: Partial = {}; - - constructor(maindb: Knex) { - super(maindb); - //this.applicationRepo = new ApplicationRepository(maindb); - } - - //AfterPForm () - async validate( - issueDate: string, - start_p: number, - ): Promise { - try { - let records: any = [] - let pdfData: any = [] - let batchTotal: any = 0; - let pdfDataSigned: any = [] - let batchTotalSigned: any = 0; - let serial_no_p = null; - - if (!start_p) { //start_p === '0' - //EXEC sfa.assign_cheque_req_batch @issue_date_p = @issue_date_p OUTPUT, @serial_no_p = @serial_no_p OUTPUT; - serial_no_p = await this.assignChequeReqBatch(issueDate); - - } else { - //:issue_date_p := TO_DATE(SUBSTR(:start_p,1,11),'DD MON RRRR'); - serial_no_p = start_p; - } - //:issue_date_str_p := TO_CHAR (:issue_date_p, 'YYYYMMDD'); -- Added for Windows 7 issue with dateCOUNT(d.disbursement_id) - const disburseCount = await this.mainDb('sfa.disbursement') - .count('id as count') - .where('financial_batch_run_date', issueDate) - .where('financial_batch_serial_no', serial_no_p) - .whereNotNull('issue_date'); //NOTE: Amy has confirmed that as long as the batch report will not pick up disbursements until they have an issue date - - if (!disburseCount?.[0].count) { - return { success: false, text: 'There are no new disbursements for this date. This will end the report.' } - } else { - records = await this.getInfoFileDAT(issueDate, serial_no_p || 0) ?? []; //cheque_req_export; - pdfData = await this.getPDFData(issueDate, serial_no_p || 0, false); - batchTotal = await this.getBatchTotal(issueDate, serial_no_p || 0, false); - pdfDataSigned = await this.getPDFData(issueDate, serial_no_p || 0, true); - batchTotalSigned = await this.getBatchTotal(issueDate, serial_no_p || 0, true); - - this.mainDb.raw('EXEC sfa.save_csl_nars_history ?, ?', [`'${issueDate}'`, serial_no_p]) - } - - const filename = this.generateFileName(issueDate, serial_no_p || 0); - - return { - success: true, data: { - records: [...records], - filename, - pdfData: [...pdfData], - batchTotal: [ ...batchTotal ], - pdfDataSigned: [...pdfDataSigned], - batchTotalSigned: [ ...batchTotalSigned ] - } - }; - } catch (error) { - return { - success: false, - text: "Error in validaet method" - }; - } + //private applicationRepo: ApplicationRepository; + //private application: Partial = {}; + + constructor(maindb: Knex) { + super(maindb); + //this.applicationRepo = new ApplicationRepository(maindb); + } + + //AfterPForm () + async validate(issueDate: string, start_p: number): Promise { + try { + let records: any = []; + let pdfData: any = []; + let batchTotal: any = 0; + let pdfDataSigned: any = []; + let batchTotalSigned: any = 0; + let serial_no_p = null; + + if (!start_p) { + //start_p === '0' + //EXEC sfa.assign_cheque_req_batch @issue_date_p = @issue_date_p OUTPUT, @serial_no_p = @serial_no_p OUTPUT; + serial_no_p = await this.assignChequeReqBatch(issueDate); + } else { + //:issue_date_p := TO_DATE(SUBSTR(:start_p,1,11),'DD MON RRRR'); + serial_no_p = start_p; + } + //:issue_date_str_p := TO_CHAR (:issue_date_p, 'YYYYMMDD'); -- Added for Windows 7 issue with dateCOUNT(d.disbursement_id) + const disburseCount = await this.mainDb("sfa.disbursement") + .count("id as count") + .where("financial_batch_run_date", issueDate) + .where("financial_batch_serial_no", serial_no_p) + .whereNotNull("issue_date"); //NOTE: Amy has confirmed that as long as the batch report will not pick up disbursements until they have an issue date + + if (!disburseCount?.[0].count) { + return { success: false, text: "There are no new disbursements for this date. This will end the report." }; + } else { + records = (await this.getInfoFileDAT(issueDate, serial_no_p || 0)) ?? []; //cheque_req_export; + pdfData = await this.getPDFData(issueDate, serial_no_p || 0, false); + batchTotal = await this.getBatchTotal(issueDate, serial_no_p || 0, false); + pdfDataSigned = await this.getPDFData(issueDate, serial_no_p || 0, true); + batchTotalSigned = await this.getBatchTotal(issueDate, serial_no_p || 0, true); + + this.mainDb.raw("EXEC sfa.save_csl_nars_history ?, ?", [`'${issueDate}'`, serial_no_p]); + } + + const filename = this.generateFileName(issueDate, serial_no_p || 0); + + return { + success: true, + data: { + records: [...records], + filename, + pdfData: [...pdfData], + batchTotal: [...batchTotal], + pdfDataSigned: [...pdfDataSigned], + batchTotalSigned: [...batchTotalSigned], + }, + }; + } catch (error) { + return { + success: false, + text: "Error in validaet method", + }; } - - async getPDFData( - issueDate: string, - serialNo: number, - isSigned: boolean - ): Promise { - try { - const pdfData = await this.mainDb - .select( - 's.id AS student_id', - 'app.id AS application_id', - 'rt.description AS funding_type', - 'd.financial_batch_id_year', - 'd.financial_batch_id', - this.mainDb.raw(` + } + + async getPDFData(issueDate: string, serialNo: number, isSigned: boolean): Promise { + try { + const pdfData = await this.mainDb + .select( + "s.id AS student_id", + "app.id AS application_id", + "rt.description AS funding_type", + "d.financial_batch_id_year", + "d.financial_batch_id", + this.mainDb.raw(` CASE WHEN rt.batch_group_id = 5 THEN CASE @@ -107,7 +100,7 @@ export class ChequeReqList extends BaseRepository { ELSE rt.batch_group_id END AS bg_id `), - this.mainDb.raw(` + this.mainDb.raw(` REPLACE( ISNULL( CAST(rt.batch_group_id AS VARCHAR(10)), @@ -125,30 +118,32 @@ export class ChequeReqList extends BaseRepository { '' ) AS batch_id `), - 'fr.request_type_id', - 'rt.financial_coding', - this.mainDb.raw(`COALESCE(p.first_name , '') + ' ' + COALESCE(p.last_name, '') AS name`), - 's.vendor_id', - this.mainDb.raw("FORMAT(disbursed_amount, 'C') AS disbursed_amount"), - this.mainDb.raw(`CASE WHEN app.student_number IS NULL THEN 'Yukon Student' ELSE app.student_number END AS invoice_id`), - this.mainDb.raw("UPPER(FORMAT(d.due_date, 'yyyy MMM dd')) AS due_date"), - 'app.id', - this.mainDb.raw("'S' as SPEC_HAND"), - 'd.tax_year', - this.mainDb.raw("UPPER(FORMAT(d.financial_batch_run_date, 'yyyy MMM dd')) AS invoice_date") - ) - .from('sfa.funding_request AS fr') - .join('sfa.request_type AS rt', 'rt.id', '=', 'fr.request_type_id') - .join('sfa.disbursement AS d', 'fr.id', '=', 'd.funding_request_id') - .join('sfa.application AS app', 'fr.application_id', '=', 'app.id') - .join('sfa.student AS s', 'app.student_id', '=', 's.id') - .join('SFA.person AS p', 's.person_id', '=', 'p.id') - .where('d.financial_batch_run_date', '=', issueDate) - .where('d.financial_batch_serial_no', '=', serialNo) - .whereNotNull('d.due_date') - .andWhere( - isSigned - ? this.mainDb.raw(` + "fr.request_type_id", + "rt.financial_coding", + this.mainDb.raw(`COALESCE(p.first_name , '') + ' ' + COALESCE(p.last_name, '') AS name`), + "s.vendor_id", + this.mainDb.raw("FORMAT(disbursed_amount, 'C') AS disbursed_amount"), + this.mainDb.raw( + `CASE WHEN app.student_number IS NULL THEN 'Yukon Student' ELSE app.student_number END AS invoice_id` + ), + this.mainDb.raw("UPPER(FORMAT(d.due_date, 'yyyy MMM dd')) AS due_date"), + "app.id", + this.mainDb.raw("'S' as SPEC_HAND"), + "d.tax_year", + this.mainDb.raw("UPPER(FORMAT(d.financial_batch_run_date, 'yyyy MMM dd')) AS invoice_date") + ) + .from("sfa.funding_request AS fr") + .join("sfa.request_type AS rt", "rt.id", "=", "fr.request_type_id") + .join("sfa.disbursement AS d", "fr.id", "=", "d.funding_request_id") + .join("sfa.application AS app", "fr.application_id", "=", "app.id") + .join("sfa.student AS s", "app.student_id", "=", "s.id") + .join("SFA.person AS p", "s.person_id", "=", "p.id") + .where("d.financial_batch_run_date", "=", issueDate) + .where("d.financial_batch_serial_no", "=", serialNo) + .whereNotNull("d.due_date") + .andWhere( + isSigned + ? this.mainDb.raw(` ( CASE WHEN rt.batch_group_id = 5 THEN CASE @@ -159,50 +154,43 @@ export class ChequeReqList extends BaseRepository { WHEN rt.batch_group_id = 1 THEN sfa.get_batch_group_id_fct(fr.id) ELSE rt.batch_group_id END - ) = 3` - ) - : this.mainDb.raw("1 = 1") - ) - .orderBy('s.vendor_id') - .orderBy('p.last_name') - .orderBy('d.financial_batch_id_year') - .orderBy('d.financial_batch_id') - .orderBy('p.first_name'); - - if (pdfData.length) { - const groupByBatchId = _.groupBy(pdfData, 'financial_batch_id') - - return Object.values(groupByBatchId); - } else { - return []; - } - } catch (error) { - console.log(error); - return undefined - } + ) = 3`) + : this.mainDb.raw("1 = 1") + ) + .orderBy("s.vendor_id") + .orderBy("p.last_name") + .orderBy("d.financial_batch_id_year") + .orderBy("d.financial_batch_id") + .orderBy("p.first_name"); + + if (pdfData.length) { + const groupByBatchId = _.groupBy(pdfData, "financial_batch_id"); + + return Object.values(groupByBatchId); + } else { + return []; + } + } catch (error) { + console.log(error); + return undefined; } - async getBatchTotal( - issueDate: string, - serialNo: number, - isSigned: boolean - ): Promise { - try { - const batchTotal = await this.mainDb - .select( - 'd.financial_batch_id', - this.mainDb.raw(`FORMAT(SUM(d.disbursed_amount), 'C') as total`)) - .from('sfa.funding_request AS fr') - .join('sfa.request_type AS rt', 'rt.id', '=', 'fr.request_type_id') - .join('sfa.disbursement AS d', 'fr.id', '=', 'd.funding_request_id') - .join('sfa.application AS app', 'fr.application_id', '=', 'app.id') - .join('sfa.student AS s', 'app.student_id', '=', 's.id') - .join('SFA.person AS p', 's.person_id', '=', 'p.id') - .where('d.financial_batch_run_date', '=', issueDate) - .where('d.financial_batch_serial_no', '=', serialNo) - .whereNotNull('d.due_date') - .andWhere( - isSigned - ? this.mainDb.raw(` + } + async getBatchTotal(issueDate: string, serialNo: number, isSigned: boolean): Promise { + try { + const batchTotal = await this.mainDb + .select("d.financial_batch_id", this.mainDb.raw(`FORMAT(SUM(d.disbursed_amount), 'C') as total`)) + .from("sfa.funding_request AS fr") + .join("sfa.request_type AS rt", "rt.id", "=", "fr.request_type_id") + .join("sfa.disbursement AS d", "fr.id", "=", "d.funding_request_id") + .join("sfa.application AS app", "fr.application_id", "=", "app.id") + .join("sfa.student AS s", "app.student_id", "=", "s.id") + .join("SFA.person AS p", "s.person_id", "=", "p.id") + .where("d.financial_batch_run_date", "=", issueDate) + .where("d.financial_batch_serial_no", "=", serialNo) + .whereNotNull("d.due_date") + .andWhere( + isSigned + ? this.mainDb.raw(` ( CASE WHEN rt.batch_group_id = 5 THEN CASE @@ -213,84 +201,77 @@ export class ChequeReqList extends BaseRepository { WHEN rt.batch_group_id = 1 THEN sfa.get_batch_group_id_fct(fr.id) ELSE rt.batch_group_id END - ) = 3` - ) - : this.mainDb.raw("1 = 1") - ) - .groupBy('d.financial_batch_id') - - return batchTotal || []; - } catch (error) { - console.log(error); - return undefined - } + ) = 3`) + : this.mainDb.raw("1 = 1") + ) + .groupBy("d.financial_batch_id"); + + return batchTotal || []; + } catch (error) { + console.log(error); + return undefined; } - //assign_cheque_req_batch () - async assignChequeReqBatch( - issueDate: string - ): Promise { - try { - const fb_serial = await this.getScalarValue("get_serial_fct", [ - `'${issueDate}'` - ]); - - let disb_list: ChequeReqDTO[] = []; // CURSOR disb_cur - let num_request_type; - let num_batch; - let num_bg; - let int_count; - let batch_year; - let ori_disb_sign; - let disb_sign; - let fb_seq_name; - let id_year; - let ori_fb_year; - - disb_list = await this.getDisburseList(issueDate) ?? []; - - num_request_type = null; - num_bg = null; - int_count = 0; - - //for await (const disburse of disb_list) { - for (let index = 0; index < disb_list.length; index++) { - const disburse = disb_list[index]; - - disb_sign = disburse.disbursed_amount < 0 - ? 'NEG' - : 'POS'; - - // If this is the first time through or the request type is new or the batch group had changed or the disbursement sign has changed - // or the financial batch year has changed or 25 records have been added to a batch then start a new batch - if ( - num_request_type === null || - num_request_type !== disburse.request_type_id || - num_bg === null || - num_bg !== disburse.bg_id || - ori_disb_sign === null || - ori_disb_sign !== disb_sign || - ori_fb_year === null || - ori_fb_year !== disburse.f_year || - int_count === 25 - ) { - num_request_type = disburse.request_type_id; - num_bg = disburse.bg_id; - ori_disb_sign = disb_sign; - ori_fb_year = disburse.f_year; - batch_year = parseInt(disburse.f_year.toString().substring(2, 4), 10); - - // Select the appropriate sequence name. - if (disburse.bg_id === 1) { - fb_seq_name = 'FB_' + disburse.f_year + '_STA_SEQ'; - } else if (disburse.bg_id === 2) { - fb_seq_name = 'FB_' + disburse.f_year + '_CSL_SEQ'; - } else if (disburse.bg_id === 3) { - fb_seq_name = 'FB_' + disburse.f_year + '_ORI_SEQ'; - } else if (disburse.bg_id === 4) { - fb_seq_name = 'FB_' + disburse.f_year + '_OTHER_SEQ'; - } - - const validateSequence: any = await this.mainDb.raw(` + } + //assign_cheque_req_batch () + async assignChequeReqBatch(issueDate: string): Promise { + try { + const fb_serial = await this.getScalarValue("get_serial_fct", [`'${issueDate}'`]); + + let disb_list: ChequeReqDTO[] = []; // CURSOR disb_cur + let num_request_type; + let num_batch; + let num_bg; + let int_count; + let batch_year; + let ori_disb_sign; + let disb_sign; + let fb_seq_name; + let id_year; + let ori_fb_year; + + disb_list = (await this.getDisburseList(issueDate)) ?? []; + + num_request_type = null; + num_bg = null; + int_count = 0; + + //for await (const disburse of disb_list) { + for (let index = 0; index < disb_list.length; index++) { + const disburse = disb_list[index]; + + disb_sign = disburse.disbursed_amount < 0 ? "NEG" : "POS"; + + // If this is the first time through or the request type is new or the batch group had changed or the disbursement sign has changed + // or the financial batch year has changed or 25 records have been added to a batch then start a new batch + if ( + num_request_type === null || + num_request_type !== disburse.request_type_id || + num_bg === null || + num_bg !== disburse.bg_id || + ori_disb_sign === null || + ori_disb_sign !== disb_sign || + ori_fb_year === null || + ori_fb_year !== disburse.f_year || + int_count === 25 + ) { + num_request_type = disburse.request_type_id; + num_bg = disburse.bg_id; + ori_disb_sign = disb_sign; + ori_fb_year = disburse.f_year; + batch_year = parseInt(disburse.f_year.toString().substring(2, 4), 10); + + // Select the appropriate sequence name. + if (disburse.bg_id === 1) { + fb_seq_name = "FB_" + disburse.f_year + "_STA_SEQ"; + } else if (disburse.bg_id === 2) { + fb_seq_name = "FB_" + disburse.f_year + "_CSL_SEQ"; + } else if (disburse.bg_id === 3) { + fb_seq_name = "FB_" + disburse.f_year + "_ORI_SEQ"; + } else if (disburse.bg_id === 4) { + fb_seq_name = "FB_" + disburse.f_year + "_OTHER_SEQ"; + } + + const validateSequence: any = await this.mainDb.raw(` SELECT 1 FROM sys.sequences sq INNER JOIN sys.schemas s ON s.schema_id = sq.schema_id @@ -298,65 +279,58 @@ export class ChequeReqList extends BaseRepository { AND s.name = 'sfa' `); - const existSequence = validateSequence?.length > 0; - - if (existSequence) { + const existSequence = validateSequence?.length > 0; - const getNumBatch: any = await this.mainDb - .raw(`SELECT NEXT VALUE FOR sfa.${fb_seq_name} AS num_batch`); + if (existSequence) { + const getNumBatch: any = await this.mainDb.raw(`SELECT NEXT VALUE FOR sfa.${fb_seq_name} AS num_batch`); - num_batch = parseInt(getNumBatch[0].num_batch); + num_batch = parseInt(getNumBatch[0].num_batch); - int_count = 1; - } else { - const createSequence: any = await this.mainDb.raw(` + int_count = 1; + } else { + const createSequence: any = await this.mainDb.raw(` CREATE SEQUENCE sfa.${fb_seq_name} START WITH 1 INCREMENT BY 1; `); - const getNumBatch: any = await this.mainDb - .raw(`SELECT NEXT VALUE FOR sfa.${fb_seq_name} AS num_batch`); - - num_batch = parseInt(getNumBatch[0].num_batch); - - int_count = 1; - } - - //Get the next batch number from the sequence - //EXEC('SELECT @num_batch = NEXT VALUE FOR ' + @fb_seq_name, N'@num_batch INT OUTPUT', @num_batch OUTPUT); - //SET @int_count = 1; - } else if ((num_request_type === disburse.request_type_id) && (int_count !== 25)) { - int_count++; - } - - const updateDisburse = await this.mainDb("sfa.disbursement") - .where({ id: disburse.disbursement_id }) - .update({ - financial_batch_id: num_batch, - financial_batch_id_year: batch_year, - financial_batch_run_date: issueDate, - financial_batch_serial_no: fb_serial - }); - } - - return fb_serial; - } catch (error) { - console.log(error); - return undefined; + const getNumBatch: any = await this.mainDb.raw(`SELECT NEXT VALUE FOR sfa.${fb_seq_name} AS num_batch`); + + num_batch = parseInt(getNumBatch[0].num_batch); + + int_count = 1; + } + + //Get the next batch number from the sequence + //EXEC('SELECT @num_batch = NEXT VALUE FOR ' + @fb_seq_name, N'@num_batch INT OUTPUT', @num_batch OUTPUT); + //SET @int_count = 1; + } else if (num_request_type === disburse.request_type_id && int_count !== 25) { + int_count++; } - } - async getDisburseList( - issueDate: string - ): Promise { - try { - const disb_list = await this.mainDb('sfa.funding_request as fr') - .select( - 'fr.request_type_id', - 'd.id as disbursement_id', - 'd.disbursed_amount', - this.mainDb.raw(` + const updateDisburse = await this.mainDb("sfa.disbursement").where({ id: disburse.disbursement_id }).update({ + financial_batch_id: num_batch, + financial_batch_id_year: batch_year, + financial_batch_run_date: issueDate, + financial_batch_serial_no: fb_serial, + }); + } + + return fb_serial; + } catch (error) { + console.log(error); + return undefined; + } + } + + async getDisburseList(issueDate: string): Promise { + try { + const disb_list = await this.mainDb("sfa.funding_request as fr") + .select( + "fr.request_type_id", + "d.id as disbursement_id", + "d.disbursed_amount", + this.mainDb.raw(` CASE WHEN rt.batch_group_id = 5 THEN CASE @@ -369,61 +343,56 @@ export class ChequeReqList extends BaseRepository { ELSE rt.batch_group_id END AS bg_id `), - 'd.issue_date', - this.mainDb.raw('sfa.get_fiscal_year_fct(d.issue_date) AS f_year'), - ) - .innerJoin('sfa.disbursement as d', 'fr.id', 'd.funding_request_id') - .innerJoin('sfa.request_type as rt', 'fr.request_type_id', 'rt.id') - .whereNotNull('rt.batch_group_id') - .where((builder) => { - builder.where('d.disbursed_amount', '<>', 0).orWhere('fr.request_type_id', 4); - }) - .where('d.issue_date', '<=', issueDate) - .where('d.issue_date', '>', this.mainDb.raw("CONVERT(DATE, '20050331', 112)")) - .whereNotNull('d.due_date') - .whereNull('d.financial_batch_id') - .orderBy('bg_id') - .orderBy('fr.request_type_id') - .orderBy('f_year') - .orderBy('d.disbursed_amount', 'desc'); - - return disb_list; - } catch (error) { - console.log(error); - return undefined; - } + "d.issue_date", + this.mainDb.raw("sfa.get_fiscal_year_fct(d.issue_date) AS f_year") + ) + .innerJoin("sfa.disbursement as d", "fr.id", "d.funding_request_id") + .innerJoin("sfa.request_type as rt", "fr.request_type_id", "rt.id") + .whereNotNull("rt.batch_group_id") + .where((builder) => { + builder.where("d.disbursed_amount", "<>", 0).orWhere("fr.request_type_id", 4); + }) + .where("d.issue_date", "<=", issueDate) + .where("d.issue_date", ">", this.mainDb.raw("CONVERT(DATE, '20050331', 112)")) + .whereNotNull("d.due_date") + .whereNull("d.financial_batch_id") + .orderBy("bg_id") + .orderBy("fr.request_type_id") + .orderBy("f_year") + .orderBy("d.disbursed_amount", "desc"); + + return disb_list; + } catch (error) { + console.log(error); + return undefined; } + } - async getInfoFileDAT( - issueDate: string, - serial_no: number - ): Promise { - try { - const records = await this.mainDb.raw(` + async getInfoFileDAT(issueDate: string, serial_no: number): Promise { + try { + const records = await this.mainDb.raw(` SELECT * FROM sfa.get_records_for_cheque_req_dat_file('${issueDate}', ${serial_no}) AS t1 ORDER BY t1.financial_batch_id_year, t1.financial_batch_id, t1.vendor_id; `); //recordsForDATFile - return records; - } catch (error) { - console.log(error); - return undefined - } + return records; + } catch (error) { + console.log(error); + return undefined; } - generateFileName( - issueDateStr: string, - serialNo: number - ): string { - const issueDate = new Date(issueDateStr); + } + generateFileName(issueDateStr: string, serialNo: number): string { + const issueDate = new Date(issueDateStr); - const formattedDate = issueDate.getFullYear().toString().slice(-2) + - ('0' + (issueDate.getMonth() + 1)).slice(-2) + - ('0' + issueDate.getDate()).slice(-2); + const formattedDate = + issueDate.getFullYear().toString().slice(-2) + + ("0" + (issueDate.getMonth() + 1)).slice(-2) + + ("0" + issueDate.getDate()).slice(-2); - const formattedSerialNo = ('0' + serialNo).slice(-2); + const formattedSerialNo = ("0" + serialNo).slice(-2); - const fileName = 'SFVO_' + formattedDate + '_' + formattedSerialNo; + const fileName = "SFVO_" + formattedDate + "_" + formattedSerialNo; - return fileName; - } -} \ No newline at end of file + return fileName; + } +} diff --git a/src/api/routes/admin/cheque-req-list-router.ts b/src/api/routes/admin/cheque-req-list-router.ts index fc7a8769..26a8f671 100644 --- a/src/api/routes/admin/cheque-req-list-router.ts +++ b/src/api/routes/admin/cheque-req-list-router.ts @@ -1,44 +1,38 @@ import knex from "knex"; import express, { Request, Response } from "express"; -import { body, param } from "express-validator"; -import { ReturnValidationErrors } from "../../middleware"; import { DB_CONFIG } from "../../config"; -import { ChequeReqList } from '../../repositories/cheque_req_list'; +import { ChequeReqList } from "../../repositories/cheque_req_list"; -const db = knex(DB_CONFIG) +const db = knex(DB_CONFIG); export const chequeReqRouter = express.Router(); -chequeReqRouter.get("/", - async (req: Request, res: Response) => { - try { - const { issueDate = "", reRunBatch = null } = req.query; - - let start_p = 0; - - if ( - reRunBatch !== null && - reRunBatch !== "" && - Number(reRunBatch) - ) { - start_p = Number(reRunBatch); - } - - if (issueDate?.length !== 10) { - return res.status(200).json({ - success: false, - text: 'Select a valid date' - }); - } - - const chequeRequest = new ChequeReqList(db); - - const records: any = await chequeRequest.validate(issueDate.toString(), start_p); - - return res.status(200).json({ ...records }); - - } catch (error) { - console.log(error); - return res.status(404).send(); - } +chequeReqRouter.get("/", async (req: Request, res: Response) => { + const { issueDate = "", reRunBatch = null } = req.query; + console.log("CHEKC REQ"); + + try { + let start_p = 0; + + if (reRunBatch !== null && reRunBatch !== "" && Number(reRunBatch)) { + start_p = Number(reRunBatch); + } + + if (issueDate?.length !== 10) { + return res.status(200).json({ + success: false, + text: "Select a valid date", + }); } -); \ No newline at end of file + + const chequeRequest = new ChequeReqList(db); + + console.log("VALIDATE") + + const records: any = await chequeRequest.validate(issueDate.toString(), start_p); + + return res.status(200).json({ ...records }); + } catch (error) { + console.log(error); + return res.status(404).send(); + } +}); From 1b58cfec7f97e20f0cf5127a7f199b0bcc503c30 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Thu, 12 Oct 2023 15:57:36 -0700 Subject: [PATCH 2/9] Reformat --- .../csfa-part-time/CSFAPartTime.vue | 1282 ++++++++--------- 1 file changed, 638 insertions(+), 644 deletions(-) diff --git a/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue b/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue index ef92183a..4f0dfb5a 100644 --- a/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue +++ b/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue @@ -1,681 +1,675 @@ \ No newline at end of file + From ea3f5c2b58ba24364ae750704d30059905871964 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Thu, 12 Oct 2023 15:58:05 -0700 Subject: [PATCH 3/9] Remove debugging --- src/api/routes/admin/cheque-req-list-router.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/api/routes/admin/cheque-req-list-router.ts b/src/api/routes/admin/cheque-req-list-router.ts index 26a8f671..7a0b7960 100644 --- a/src/api/routes/admin/cheque-req-list-router.ts +++ b/src/api/routes/admin/cheque-req-list-router.ts @@ -8,7 +8,6 @@ export const chequeReqRouter = express.Router(); chequeReqRouter.get("/", async (req: Request, res: Response) => { const { issueDate = "", reRunBatch = null } = req.query; - console.log("CHEKC REQ"); try { let start_p = 0; @@ -25,9 +24,6 @@ chequeReqRouter.get("/", async (req: Request, res: Response) => { } const chequeRequest = new ChequeReqList(db); - - console.log("VALIDATE") - const records: any = await chequeRequest.validate(issueDate.toString(), start_p); return res.status(200).json({ ...records }); From 66e7e11d00ec1c53924597b50016e80607658d60 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Thu, 12 Oct 2023 15:58:24 -0700 Subject: [PATCH 4/9] Minor cleanup --- .../cheque_req_list/cheque-req-list-repository.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts b/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts index 38573e27..abce41ff 100644 --- a/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts +++ b/src/api/repositories/cheque_req_list/cheque-req-list-repository.ts @@ -12,15 +12,10 @@ interface ChequeReqDTO { } export class ChequeReqList extends BaseRepository { - //private applicationRepo: ApplicationRepository; - //private application: Partial = {}; - constructor(maindb: Knex) { super(maindb); - //this.applicationRepo = new ApplicationRepository(maindb); } - //AfterPForm () async validate(issueDate: string, start_p: number): Promise { try { let records: any = []; @@ -45,7 +40,7 @@ export class ChequeReqList extends BaseRepository { .where("financial_batch_serial_no", serial_no_p) .whereNotNull("issue_date"); //NOTE: Amy has confirmed that as long as the batch report will not pick up disbursements until they have an issue date - if (!disburseCount?.[0].count) { + if (!disburseCount[0].count) { return { success: false, text: "There are no new disbursements for this date. This will end the report." }; } else { records = (await this.getInfoFileDAT(issueDate, serial_no_p || 0)) ?? []; //cheque_req_export; @@ -175,6 +170,7 @@ export class ChequeReqList extends BaseRepository { return undefined; } } + async getBatchTotal(issueDate: string, serialNo: number, isSigned: boolean): Promise { try { const batchTotal = await this.mainDb @@ -212,7 +208,7 @@ export class ChequeReqList extends BaseRepository { return undefined; } } - //assign_cheque_req_batch () + async assignChequeReqBatch(issueDate: string): Promise { try { const fb_serial = await this.getScalarValue("get_serial_fct", [`'${issueDate}'`]); @@ -381,6 +377,7 @@ export class ChequeReqList extends BaseRepository { return undefined; } } + generateFileName(issueDateStr: string, serialNo: number): string { const issueDate = new Date(issueDateStr); From c3d240bfa8f11f635a14e6176ee4340c705ba58a Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Thu, 12 Oct 2023 15:59:31 -0700 Subject: [PATCH 5/9] Adding Part-time in improved format --- src/api/routes/admin/csg-threshold-router.ts | 34 ++ src/web/src/components/application/Status.vue | 3 +- .../components/csg-disbursements.vue | 4 +- .../components/csl-pt/tab-award.vue | 6 +- .../components/csl-pt/tab-dependent.vue | 210 ++++++++++ .../components/csl-pt/tab-disability.vue | 162 ++++++++ .../components/csl-pt/tab-grant.vue | 168 ++++++++ .../assessments/store/csg-full-time.js | 6 +- .../store/csg-part-time-dependent.js | 367 ++++++++++++++++++ .../store/csg-part-time-disability.js | 275 +++++++++++++ .../assessments/store/csg-part-time.js | 338 ++++++++++++++++ .../assessments/store/csl-part-time.js | 43 +- .../application/assessments/views/CSLPT.vue | 85 +++- src/web/src/store/index.js | 8 +- 14 files changed, 1675 insertions(+), 34 deletions(-) create mode 100644 src/web/src/components/application/assessments/components/csl-pt/tab-dependent.vue create mode 100644 src/web/src/components/application/assessments/components/csl-pt/tab-disability.vue create mode 100644 src/web/src/components/application/assessments/components/csl-pt/tab-grant.vue create mode 100644 src/web/src/components/application/assessments/store/csg-part-time-dependent.js create mode 100644 src/web/src/components/application/assessments/store/csg-part-time-disability.js create mode 100644 src/web/src/components/application/assessments/store/csg-part-time.js diff --git a/src/api/routes/admin/csg-threshold-router.ts b/src/api/routes/admin/csg-threshold-router.ts index f7648bd7..73dda88d 100644 --- a/src/api/routes/admin/csg-threshold-router.ts +++ b/src/api/routes/admin/csg-threshold-router.ts @@ -268,6 +268,40 @@ csgThresholdRouter.get( } ); +csgThresholdRouter.get( + "/csgpt/:application_id", + param("application_id").isInt(), + ReturnValidationErrors, + async (req: Request, res: Response) => { + const { application_id } = req.params; + + let funding_request = await db("sfa.funding_request") + .where({ application_id, request_type_id: 31 }) + .orderBy("id", "desc") + .first(); + + if (funding_request) { + let assessment = await db("sfa.assessment") + .where({ + funding_request_id: funding_request.id, + }) + .orderBy("id", "desc") + .first(); + + let disbursements = await db("sfa.disbursement") + .where({ + funding_request_id: funding_request.id, + }) + .orderBy("issue_date") + .orderBy("id"); + + return res.json({ data: { funding_request, assessment, disbursements } }); + } + + res.status(404).send("Funding Request not found"); + } +); + csgThresholdRouter.post( "/csgftdep/:application_id/funding-request/:funding_request_id/assessment", param("application_id").isInt(), diff --git a/src/web/src/components/application/Status.vue b/src/web/src/components/application/Status.vue index 1431acbc..c73a47b3 100644 --- a/src/web/src/components/application/Status.vue +++ b/src/web/src/components/application/Status.vue @@ -18,7 +18,7 @@
- +
({}), @@ -47,6 +47,8 @@ export default { computed: { ...mapGetters(["cslClassifications", "disbursementTypes", "changeReasons"]), disbursements() { + console.log("STORE: ",`${this.store}/disbursements`) + let values = store.getters[`${this.store}/disbursements`]; return values; }, diff --git a/src/web/src/components/application/assessments/components/csl-pt/tab-award.vue b/src/web/src/components/application/assessments/components/csl-pt/tab-award.vue index 83cc7cd2..af269568 100644 --- a/src/web/src/components/application/assessments/components/csl-pt/tab-award.vue +++ b/src/web/src/components/application/assessments/components/csl-pt/tab-award.vue @@ -84,7 +84,7 @@ hide-details background-color="#ddd" append-icon="mdi-calculator" - :value="formatMoney(totalGrants)" + :value="formatMoney(assessment.total_grant_awarded)" /> @@ -176,6 +176,7 @@ Disburse + {{ fundingRequest }}
@@ -189,7 +190,7 @@ export default { }), computed: { ...mapState({ application: "selectedApplication" }), - ...mapState("cslPartTimeStore", ["assessment"]), + ...mapState("cslPartTimeStore", ["assessment", "fundingRequest"]), ...mapGetters("cslPartTimeStore", [ "totalCosts", "familyIncome", @@ -197,7 +198,6 @@ export default { "maxAllowable", "assessedAmount", "previousDisbursements", - "totalGrants", "actualAward", "netAmount", ]), diff --git a/src/web/src/components/application/assessments/components/csl-pt/tab-dependent.vue b/src/web/src/components/application/assessments/components/csl-pt/tab-dependent.vue new file mode 100644 index 00000000..d52182a0 --- /dev/null +++ b/src/web/src/components/application/assessments/components/csl-pt/tab-dependent.vue @@ -0,0 +1,210 @@ + + + diff --git a/src/web/src/components/application/assessments/components/csl-pt/tab-disability.vue b/src/web/src/components/application/assessments/components/csl-pt/tab-disability.vue new file mode 100644 index 00000000..5196b436 --- /dev/null +++ b/src/web/src/components/application/assessments/components/csl-pt/tab-disability.vue @@ -0,0 +1,162 @@ + + + diff --git a/src/web/src/components/application/assessments/components/csl-pt/tab-grant.vue b/src/web/src/components/application/assessments/components/csl-pt/tab-grant.vue new file mode 100644 index 00000000..de5e13a1 --- /dev/null +++ b/src/web/src/components/application/assessments/components/csl-pt/tab-grant.vue @@ -0,0 +1,168 @@ + + + diff --git a/src/web/src/components/application/assessments/store/csg-full-time.js b/src/web/src/components/application/assessments/store/csg-full-time.js index c57df533..016e3b78 100644 --- a/src/web/src/components/application/assessments/store/csg-full-time.js +++ b/src/web/src/components/application/assessments/store/csg-full-time.js @@ -12,7 +12,7 @@ const state = { disbursements: [], parentAssessment: {}, parentDisbursements: [], - baseRate: 0.00, + baseRate: 0.0, }; const getters = { disbursements(state) { @@ -145,10 +145,12 @@ const mutations = { }, }; const actions = { - async initialize(store, app) { + async initialize(store, { app, assessment }) { console.log("INIT"); store.dispatch("loadThresholds", app.academic_year_id); store.dispatch("loadCSLFTAssessment", { id: app.id, refreshChild: true }); + + console.log("MY ASSESS", assessment); }, async loadThresholds({ commit }, academicYear) { diff --git a/src/web/src/components/application/assessments/store/csg-part-time-dependent.js b/src/web/src/components/application/assessments/store/csg-part-time-dependent.js new file mode 100644 index 00000000..447daa4f --- /dev/null +++ b/src/web/src/components/application/assessments/store/csg-part-time-dependent.js @@ -0,0 +1,367 @@ +import axios from "axios"; +import moment from "moment"; +import { isNumber, isUndefined, isArray } from "lodash"; +import { parse } from "vue-currency-input"; +import { APPLICATION_URL, CSG_THRESHOLD_URL } from "@/urls"; +import store from "@/store"; + +const state = { + csgThresholds: [], + fundingRequest: {}, + assessment: {}, + + disbursements: [], + parentAssessment: {}, + parentDisbursements: [], + baseMiscAmount: 10, + baseRate: {}, +}; +const getters = { + disbursements(state) { + return state.disbursements; + }, + familyIncome(state) { + let val = state.assessment + ? (state.assessment.student_ln150_income || 0) + + (state.assessment.spouse_ln150_income || 0) + + (state.assessment.parent1_income || 0) + + (state.assessment.parent2_income || 0) + : 0; + return val; + }, + totalStudyCosts(state) { + let total = (state.application?.tuition_estimate_amount ?? 0) + (state.application?.books_supplies_cost ?? 0); + return total; + }, + totalTransportation(state) { + return state.assessment.p_trans_month * state.assessment.study_months; + }, + totalDayCare(state) { + return ( + Math.min(state.assessment.day_care_allowable, state.assessment.day_care_actual) * state.assessment.study_months + ); + }, + maxMiscellaneous(state, getters) { + return state.baseMiscAmount * state.application?.courses_per_week; + }, + totalMiscellaneous(state, getters) { + return getters.maxMiscellaneous * state.assessment.study_weeks; + }, + totalCosts(state, getters) { + return getters.totalStudyCosts + getters.totalTransportation + getters.totalDayCare + getters.totalMiscellaneous; + }, + + threshold(state) { + if (state.assessment && state.csgThresholds && state.csgThresholds.length > 0) { + let size = Math.min(state.assessment.family_size, 7); + let val = state.csgThresholds.filter((f) => f.family_size == size)[0]; + return val || {}; + } + return {}; + }, + + phaseOutRate(state, getters) { + let depCount = state.assessment?.dependent_count ?? 0; + let income = getters.familyIncome; + + if (income >= getters.threshold.income_cutoff) return 0; + else if (income > getters.threshold.income_threshold) { + if (depCount == 1 || depCount == 2) return getters.threshold.csgpt_dep2_phase_out_rate; + else if (depCount > 2) return getters.threshold.csgpt_dep3_phase_out_rate; + else return 0; + } else return 0; + }, + + assessedAmount(state, getters) { + if (isUndefined(state.assessment.study_weeks)) return 0; + return state.assessment.study_weeks * getters.weeklyRate; + }, + previousDisbursements(state) { + let amounts = state.disbursements.map((d) => d.disbursed_amount); + let total = amounts.reduce((t, a) => { + return t + a; + }, 0); + + return total; + }, + netAmount(state, getters) { + let rawVal = getters.assessedAmount - getters.previousDisbursements; + if (rawVal > 0 && rawVal < 100) return 100.0; + return Object.is(Math.round(rawVal), -0) ? 0 : Math.round(rawVal); + }, + + weeklyRate(state, getters) { + let depCount = state.assessment?.dependent_count ?? 0; + let rate = 0; + + if (depCount == 1 || depCount == 2) rate = state.baseRate.csgpt_dep_1_2_weekly_amount; + else if (depCount > 2) rate = state.baseRate.csgpt_dep_3_weekly_amount; + + let val = Math.max( + 0, + Math.min(rate, rate - getters.phaseOutRate * (getters.familyIncome - getters.threshold.income_threshold)) + ); + + return val; + }, +}; +const mutations = { + SET_THRESHOLDS(state, value) { + state.csgThresholds = value; + }, + SET_BASERATE(state, value) { + state.baseRate = value; + }, + SET_FUNDINGREQUEST(state, value) { + state.fundingRequest = value; + }, + SET_PARENTASSESSMENT(state, value) { + state.parentAssessment = value; + }, + SET_ASSESSMENT(state, value) { + state.assessment = value; + }, + SET_PARENTDISBURSEMENTS(state, value) { + state.parentDisbursements = value; + }, + SET_DISBURSEMENTS(state, value) { + for (let v of value) { + v.due_date = v.due_date ? moment.utc(v.due_date).format("YYYY-MM-DD") : undefined; + v.issue_date = v.issue_date ? moment.utc(v.issue_date).format("YYYY-MM-DD") : undefined; + } + + state.disbursements = value; + }, +}; +const actions = { + async initialize(store, { app, assessment }) { + console.log("Initializing CSGPTDEP"); + store.state.application = app; + store.state.parentAssessment = assessment; + + store.dispatch("loadThresholds", app.academic_year_id); + store.dispatch("loadAssessment", app.id); + }, + + async loadThresholds({ commit }, academicYear) { + axios.get(`${CSG_THRESHOLD_URL}/${academicYear}`).then((resp) => { + commit("SET_THRESHOLDS", resp.data.data); + commit("SET_BASERATE", resp.data.rates); + }); + }, + + loadAssessment({ commit, state }, applicationId) { + axios.get(`${CSG_THRESHOLD_URL}/csgptdep/${applicationId}`).then((resp) => { + commit("SET_FUNDINGREQUEST", resp.data.data.funding_request); + commit("SET_DISBURSEMENTS", resp.data.data.disbursements); + + if (resp.data.data.assessment) { + let assessment = resp.data.data.assessment; + assessment.assessed_date = moment.utc(assessment.assessed_date).format("YYYY-MM-DD"); + assessment.classes_start_date = moment.utc(assessment.classes_start_date).format("YYYY-MM-DD"); + assessment.classes_end_date = moment.utc(assessment.classes_end_date).format("YYYY-MM-DD"); + + commit("SET_ASSESSMENT", resp.data.data.assessment); + } else { + let dependentCount = 0; + let familySize = 1; + + // Common-law or Married + if ([3, 4].includes(state.application.csl_classification)) familySize++; + + if (store.getters.selectedStudent && isArray(store.getters.selectedStudent.dependent_info)) { + dependentCount = store.getters.selectedStudent.dependent_info.filter( + (d) => d.is_csg_eligible && d.application_id == state.fundingRequest.application_id + ).length; + } + familySize += dependentCount; + + let parent = state.parentAssessment; + let assessment = { + assessed_date: moment().format("YYYY-MM-DD"), + study_weeks: parent.study_weeks, + classes_start_date: moment.utc(parent.classes_start_date).format("YYYY-MM-DD"), + classes_end_date: moment.utc(parent.classes_end_date).format("YYYY-MM-DD"), + study_months: parent.study_months, + family_size: familySize, + dependent_count: dependentCount, + student_ln150_income: parent.student_ln150_income, + spouse_ln150_income: parent.spouse_ln150_income, + parent1_income: parent.parent1_income, + parent2_income: parent.parent2_income, + relocation_total: parent.relocation_total, + discretionary_cost: parent.discretionary_cost, + discretionary_cost_actual: parent.discretionary_cost_actual, + tuition_estimate: parent.tuition_estimate, + books_supplies_cost: parent.books_supplies_cost, + r_trans_16wk: parent.r_trans_16wk, + shelter_month: parent.shelter_month, + p_trans_month: parent.p_trans_month, + day_care_allowable: parent.day_care_allowable, + day_care_actual: parent.day_care_actual, + depend_food_allowable: parent.depend_food_allowable, + depend_tran_allowable: parent.depend_tran_allowable, + spouse_expected_contribution: parent.spouse_expected_contribution, + student_expected_contribution: parent.student_expected_contribution, + student_contrib_exempt: parent.student_contrib_exempt, + spouse_contrib_exempt: parent.spouse_contrib_exempt, + student_contribution_review: parent.student_contribution_review, + spouse_contribution_review: parent.spouse_contribution_review, + parent_contribution_review: parent.parent_contribution_review, + }; + + commit("SET_ASSESSMENT", assessment); + } + }); + }, + + async recalculate({ state, dispatch, commit }) { + dispatch("loadAssessment", { id: state.fundingRequest.application_id, refreshChild: false }).then(() => { + let parent = state.parentAssessment; + let dependentCount = 0; + let familySize = 1; + + // Common-law or Married + if ([3, 4].includes(state.application.csl_classification)) familySize++; + + if (store.getters.selectedStudent && isArray(store.getters.selectedStudent.dependent_info)) { + dependentCount = store.getters.selectedStudent.dependent_info.filter( + (d) => d.is_csg_eligible && d.application_id == state.fundingRequest.application_id + ).length; + } + familySize += dependentCount; + + let assessment = { + id: state.assessment.id, + assessed_date: moment().format("YYYY-MM-DD"), + study_weeks: parent.study_weeks, + classes_start_date: moment.utc(parent.classes_start_date).format("YYYY-MM-DD"), + classes_end_date: moment.utc(parent.classes_end_date).format("YYYY-MM-DD"), + study_months: parent.study_months, + family_size: familySize, + dependent_count: dependentCount, + student_ln150_income: parent.student_ln150_income, + spouse_ln150_income: parent.spouse_ln150_income, + parent1_income: parent.parent1_income, + parent2_income: parent.parent2_income, + relocation_total: parent.relocation_total, + discretionary_cost: parent.discretionary_cost, + discretionary_cost_actual: parent.discretionary_cost_actual, + tuition_estimate: parent.tuition_estimate, + books_supplies_cost: parent.books_supplies_cost, + r_trans_16wk: parent.r_trans_16wk, + shelter_month: parent.shelter_month, + p_trans_month: parent.p_trans_month, + day_care_allowable: parent.day_care_allowable, + day_care_actual: parent.day_care_actual, + depend_food_allowable: parent.depend_food_allowable, + depend_tran_allowable: parent.depend_tran_allowable, + spouse_expected_contribution: parent.spouse_expected_contribution, + student_expected_contribution: parent.student_expected_contribution, + student_contrib_exempt: parent.student_contrib_exempt, + spouse_contrib_exempt: parent.spouse_contrib_exempt, + student_contribution_review: parent.student_contribution_review, + spouse_contribution_review: parent.spouse_contribution_review, + parent_contribution_review: parent.parent_contribution_review, + }; + + commit("SET_ASSESSMENT", assessment); + dispatch("save"); + }); + }, + + async makeDisbursements({ getters, commit, state, dispatch }, numberOfDisbursements) { + let parts = Math.ceil(getters.netAmount / numberOfDisbursements); + let disbursedValues = []; + + let total = 0; + + for (let i = 0; i < numberOfDisbursements - 1; i++) { + let amount = parse(formatMoney(parts), { currency: "usd" }); + total += amount; + + disbursedValues.push({ + disbursed_amount: amount, + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), // today + }); + } + + let remainder = parse(formatMoney(getters.netAmount - total), { currency: "usd" }); + + disbursedValues.push({ + disbursed_amount: remainder, + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), + }); + + await commit("SET_DISBURSEMENTS", [...state.disbursements, ...disbursedValues]); + + await axios.put(`${APPLICATION_URL}/${state.fundingRequest.application_id}/status/${state.fundingRequest.id}`, { + data: { status_id: 7 }, // Awarded + }); + + dispatch("save"); + }, + + async removeDisbursement({ state }, { item, index }) { + if (item.id) { + state.disbursements.splice(index, 1); + await axios.delete( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/disbursement/${item.id}` + ); + } else { + state.disbursements.splice(index, 1); + } + }, + + async addDisbursement({ state }) { + state.disbursements.push({ + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), // today + }); + }, + + async save({ state, dispatch }) { + state.assessment.disbursements = state.disbursements; + + if (state.assessment.id) { + axios + .put( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/assessment/${state.assessment.id}`, + state.assessment + ) + .then((resp) => { + dispatch("loadAssessment", state.fundingRequest.application_id); + }); + } else { + axios + .post( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/assessment`, + state.assessment + ) + .then((resp) => { + dispatch("loadAssessment", state.fundingRequest.application_id); + }); + } + }, +}; + +export default { + state, + getters, + mutations, + actions, + namespaced: true, +}; + +function formatMoney(input) { + if (isNumber(input)) { + return Intl.NumberFormat("en", { + currency: "USD", + style: "currency", + }).format(input); + } + + return ""; +} diff --git a/src/web/src/components/application/assessments/store/csg-part-time-disability.js b/src/web/src/components/application/assessments/store/csg-part-time-disability.js new file mode 100644 index 00000000..2c51e0a4 --- /dev/null +++ b/src/web/src/components/application/assessments/store/csg-part-time-disability.js @@ -0,0 +1,275 @@ +import axios from "axios"; +import moment from "moment"; +import { isNumber } from "lodash"; +import { parse } from "vue-currency-input"; +import { APPLICATION_URL, CSG_THRESHOLD_URL } from "@/urls"; + +const state = { + csgThresholds: [], + fundingRequest: undefined, + assessment: {}, + + disbursements: [], + parentAssessment: {}, + parentDisbursements: [], + baseRate: 0.0, +}; +const getters = { + disbursements(state) { + return state.disbursements; + }, + previousDisbursements(state) { + let amounts = state.disbursements.map((d) => d.disbursed_amount); + let total = amounts.reduce((t, a) => { + return t + a; + }, 0); + + return total; + }, + assessedAmount(state) { + if (!state.fundingRequest) return 0; + return state.baseRate; + }, + netAmount(state, getters) { + let rawVal = getters.assessedAmount - getters.previousDisbursements; + if (rawVal > 0 && rawVal < 100) return 100.0; + return Object.is(Math.round(rawVal), -0) ? 0 : Math.round(rawVal); + }, +}; +const mutations = { + SET_THRESHOLDS(state, value) { + state.csgThresholds = value; + }, + SET_BASERATE(state, value) { + state.baseRate = value; + }, + SET_FUNDINGREQUEST(state, value) { + state.fundingRequest = value; + }, + SET_PARENTASSESSMENT(state, value) { + state.parentAssessment = value; + }, + SET_ASSESSMENT(state, value) { + state.assessment = value; + }, + SET_PARENTDISBURSEMENTS(state, value) { + state.parentDisbursements = value; + }, + SET_DISBURSEMENTS(state, value) { + for (let v of value) { + v.due_date = v.due_date ? moment.utc(v.due_date).format("YYYY-MM-DD") : undefined; + v.issue_date = v.issue_date ? moment.utc(v.issue_date).format("YYYY-MM-DD") : undefined; + } + + state.disbursements = value; + }, +}; +const actions = { + async initialize(store, { app, assessment }) { + console.log("Initializing CSGPDIS"); + store.state.application = app; + store.state.parentAssessment = assessment; + + store.dispatch("loadThresholds", app.academic_year_id); + store.dispatch("loadAssessment", app.id); + }, + + async loadThresholds({ commit }, academicYear) { + axios.get(`${CSG_THRESHOLD_URL}/${academicYear}`).then((resp) => { + commit("SET_THRESHOLDS", resp.data.data); + commit("SET_BASERATE", resp.data.rates.csg_pd_yearly_amount); + }); + }, + + loadAssessment({ commit, state }, applicationId) { + axios + .get(`${CSG_THRESHOLD_URL}/csgd/${applicationId}`) + .then((resp) => { + commit("SET_FUNDINGREQUEST", resp.data.data.funding_request); + commit("SET_DISBURSEMENTS", resp.data.data.disbursements); + + if (resp.data.data.assessment) { + let assessment = resp.data.data.assessment; + assessment.assessed_date = moment.utc(assessment.assessed_date).format("YYYY-MM-DD"); + assessment.classes_start_date = moment.utc(assessment.classes_start_date).format("YYYY-MM-DD"); + assessment.classes_end_date = moment.utc(assessment.classes_end_date).format("YYYY-MM-DD"); + + commit("SET_ASSESSMENT", resp.data.data.assessment); + } else { + let parent = state.parentAssessment; + let assessment = { + assessed_date: moment().format("YYYY-MM-DD"), + study_weeks: parent.study_weeks, + classes_start_date: moment.utc(parent.classes_start_date).format("YYYY-MM-DD"), + classes_end_date: moment.utc(parent.classes_end_date).format("YYYY-MM-DD"), + study_months: parent.study_months, + family_size: parent.family_size, + dependent_count: parent.dependent_count, + student_ln150_income: parent.student_ln150_income, + spouse_ln150_income: parent.spouse_ln150_income, + relocation_total: parent.relocation_total, + discretionary_cost: parent.discretionary_cost, + discretionary_cost_actual: parent.discretionary_cost_actual, + tuition_estimate: parent.tuition_estimate, + books_supplies_cost: parent.books_supplies_cost, + r_trans_16wk: parent.r_trans_16wk, + shelter_month: parent.shelter_month, + p_trans_month: parent.p_trans_month, + day_care_allowable: parent.day_care_allowable, + day_care_actual: parent.day_care_actual, + depend_food_allowable: parent.depend_food_allowable, + depend_tran_allowable: parent.depend_tran_allowable, + spouse_expected_contribution: parent.spouse_expected_contribution, + student_expected_contribution: parent.student_expected_contribution, + student_contrib_exempt: parent.student_contrib_exempt, + spouse_contrib_exempt: parent.spouse_contrib_exempt, + student_contribution_review: parent.student_contribution_review, + spouse_contribution_review: parent.spouse_contribution_review, + parent_contribution_review: parent.parent_contribution_review, + }; + + commit("SET_ASSESSMENT", assessment); + } + }) + .catch((e) => { + commit("SET_FUNDINGREQUEST", undefined); + commit("SET_DISBURSEMENTS", []); + commit("SET_ASSESSMENT", {}); + }); + }, + + async recalculate({ state, dispatch, commit }) { + dispatch("loadAssessment", { id: state.fundingRequest.application_id, refreshChild: false }).then(() => { + let parent = state.parentAssessment; + + let assessment = { + id: state.assessment.id, + assessed_date: moment().format("YYYY-MM-DD"), + study_weeks: parent.study_weeks, + classes_start_date: moment.utc(parent.classes_start_date).format("YYYY-MM-DD"), + classes_end_date: moment.utc(parent.classes_end_date).format("YYYY-MM-DD"), + study_months: parent.study_months, + family_size: parent.family_size, + dependent_count: parent.dependent_count, + student_ln150_income: parent.student_ln150_income, + spouse_ln150_income: parent.spouse_ln150_income, + relocation_total: parent.relocation_total, + discretionary_cost: parent.discretionary_cost, + discretionary_cost_actual: parent.discretionary_cost_actual, + tuition_estimate: parent.tuition_estimate, + books_supplies_cost: parent.books_supplies_cost, + r_trans_16wk: parent.r_trans_16wk, + shelter_month: parent.shelter_month, + p_trans_month: parent.p_trans_month, + day_care_allowable: parent.day_care_allowable, + day_care_actual: parent.day_care_actual, + depend_food_allowable: parent.depend_food_allowable, + depend_tran_allowable: parent.depend_tran_allowable, + spouse_expected_contribution: parent.spouse_expected_contribution, + student_expected_contribution: parent.student_expected_contribution, + student_contrib_exempt: parent.student_contrib_exempt, + spouse_contrib_exempt: parent.spouse_contrib_exempt, + student_contribution_review: parent.student_contribution_review, + spouse_contribution_review: parent.spouse_contribution_review, + parent_contribution_review: parent.parent_contribution_review, + }; + + commit("SET_ASSESSMENT", assessment); + dispatch("save"); + }); + }, + + async makeDisbursements({ getters, commit, state, dispatch }, numberOfDisbursements) { + let parts = getters.netAmount / numberOfDisbursements; + let disbursedValues = []; + + let total = 0; + + for (let i = 0; i < numberOfDisbursements - 1; i++) { + let amount = parse(formatMoney(parts), { currency: "usd" }); + total += amount; + + disbursedValues.push({ + disbursed_amount: amount, + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), // today + }); + } + + let remainder = parse(formatMoney(getters.netAmount - total), { currency: "usd" }); + + disbursedValues.push({ + disbursed_amount: remainder, + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), + }); + + await commit("SET_DISBURSEMENTS", [...state.disbursements, ...disbursedValues]); + + await axios.put(`${APPLICATION_URL}/${state.fundingRequest.application_id}/status/${state.fundingRequest.id}`, { + data: { status_id: 7 }, // Awarded + }); + + dispatch("save"); + }, + async removeDisbursement({ state }, { item, index }) { + if (item.id) { + state.disbursements.splice(index, 1); + await axios.delete( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/disbursement/${item.id}` + ); + } else { + state.disbursements.splice(index, 1); + } + }, + + async addDisbursement({ state }) { + state.disbursements.push({ + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), // today + }); + }, + + async save({ state, dispatch }) { + state.assessment.disbursements = state.disbursements; + + if (state.assessment.id) { + axios + .put( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/assessment/${state.assessment.id}`, + state.assessment + ) + .then((resp) => { + dispatch("loadAssessment", state.fundingRequest.application_id); + }); + } else { + axios + .post( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/assessment`, + state.assessment + ) + .then((resp) => { + dispatch("loadAssessment", state.fundingRequest.application_id); + }); + } + }, +}; + +export default { + state, + getters, + mutations, + actions, + namespaced: true, +}; + +function formatMoney(input) { + if (isNumber(input)) { + return Intl.NumberFormat("en", { + currency: "USD", + style: "currency", + }).format(input); + } + + return ""; +} diff --git a/src/web/src/components/application/assessments/store/csg-part-time.js b/src/web/src/components/application/assessments/store/csg-part-time.js new file mode 100644 index 00000000..c874ab22 --- /dev/null +++ b/src/web/src/components/application/assessments/store/csg-part-time.js @@ -0,0 +1,338 @@ +import axios from "axios"; +import moment from "moment"; +import { isNumber, isUndefined } from "lodash"; +import { parse } from "vue-currency-input"; +import { APPLICATION_URL, CSG_THRESHOLD_URL } from "@/urls"; + +const state = { + csgThresholds: [], + fundingRequest: {}, + assessment: {}, + + disbursements: [], + parentAssessment: {}, + parentDisbursements: [], + baseMiscAmount: 10, + baseRate: 0.0, +}; +const getters = { + disbursements(state) { + return state.disbursements; + }, + familyIncome(state) { + let val = state.assessment + ? (state.assessment.student_ln150_income || 0) + + (state.assessment.spouse_ln150_income || 0) + + (state.assessment.parent1_income || 0) + + (state.assessment.parent2_income || 0) + : 0; + return val; + }, + totalStudyCosts(state) { + let total = (state.application?.tuition_estimate_amount ?? 0) + (state.application?.books_supplies_cost ?? 0); + return total; + }, + totalTransportation(state) { + return state.assessment.p_trans_month * state.assessment.study_months; + }, + totalDayCare(state) { + return ( + Math.min(state.assessment.day_care_allowable, state.assessment.day_care_actual) * state.assessment.study_months + ); + }, + maxMiscellaneous(state, getters) { + return state.baseMiscAmount * state.application?.courses_per_week; + }, + totalMiscellaneous(state, getters) { + return getters.maxMiscellaneous * state.assessment.study_weeks; + }, + totalCosts(state, getters) { + return getters.totalStudyCosts + getters.totalTransportation + getters.totalDayCare + getters.totalMiscellaneous; + }, + + threshold(state) { + if (state.assessment && state.csgThresholds && state.csgThresholds.length > 0) { + let size = Math.min(state.assessment.family_size, 7); + let val = state.csgThresholds.filter((f) => f.family_size == size)[0]; + return val || {}; + } + return {}; + }, + + phaseOutRate(state, getters) { + let income = getters.familyIncome; + + if (income >= getters.threshold.income_cutoff) return 0; + else if (income > getters.threshold.income_threshold) return getters.threshold.csgpt_phase_out_rate; + else return 0; + }, + + assessedAmount(state, getters) { + if (isUndefined(state.assessment.study_months)) return 0; + + let amt = Math.max( + 0, + Math.min( + getters.totalCosts, + state.baseRate, + state.baseRate - getters.phaseOutRate * (getters.familyIncome - getters.threshold.income_threshold) + ) + ); + + return amt; + }, + previousDisbursements(state) { + let amounts = state.disbursements.map((d) => d.disbursed_amount); + let total = amounts.reduce((t, a) => { + return t + a; + }, 0); + + return total; + }, + netAmount(state, getters) { + let rawVal = getters.assessedAmount - getters.previousDisbursements; + if (rawVal > 0 && rawVal < 100) return 100.0; + return Object.is(Math.round(rawVal), -0) ? 0 : Math.round(rawVal); + }, + thresholdRange(state, getters) { + if (getters.threshold) { + return `${formatMoney(getters.threshold.income_threshold)} - ${formatMoney(getters.threshold.income_cutoff)}`; + } + return ""; + }, +}; +const mutations = { + SET_THRESHOLDS(state, value) { + state.csgThresholds = value; + }, + SET_BASERATE(state, value) { + state.baseRate = value; + }, + SET_FUNDINGREQUEST(state, value) { + state.fundingRequest = value; + }, + SET_PARENTASSESSMENT(state, value) { + state.parentAssessment = value; + }, + SET_ASSESSMENT(state, value) { + state.assessment = value; + }, + SET_PARENTDISBURSEMENTS(state, value) { + state.parentDisbursements = value; + }, + SET_DISBURSEMENTS(state, value) { + for (let v of value) { + v.due_date = v.due_date ? moment.utc(v.due_date).format("YYYY-MM-DD") : undefined; + v.issue_date = v.issue_date ? moment.utc(v.issue_date).format("YYYY-MM-DD") : undefined; + } + + state.disbursements = value; + }, +}; +const actions = { + async initialize(store, { app, assessment }) { + console.log("Initializing CSGPT"); + store.state.application = app; + store.state.parentAssessment = assessment; + + store.dispatch("loadThresholds", app.academic_year_id); + store.dispatch("loadAssessment", app.id); + }, + + async loadThresholds({ commit }, academicYear) { + axios.get(`${CSG_THRESHOLD_URL}/${academicYear}`).then((resp) => { + commit("SET_THRESHOLDS", resp.data.data); + commit("SET_BASERATE", resp.data.rates.csgpt_yearly_amount); + }); + }, + + loadAssessment({ commit, state }, applicationId) { + axios.get(`${CSG_THRESHOLD_URL}/csgpt/${applicationId}`).then((resp) => { + commit("SET_FUNDINGREQUEST", resp.data.data.funding_request); + commit("SET_DISBURSEMENTS", resp.data.data.disbursements); + + if (resp.data.data.assessment) { + let assessment = resp.data.data.assessment; + assessment.assessed_date = moment.utc(assessment.assessed_date).format("YYYY-MM-DD"); + assessment.classes_start_date = moment.utc(assessment.classes_start_date).format("YYYY-MM-DD"); + assessment.classes_end_date = moment.utc(assessment.classes_end_date).format("YYYY-MM-DD"); + + commit("SET_ASSESSMENT", resp.data.data.assessment); + } else { + let parent = state.parentAssessment; + let assessment = { + assessed_date: moment().format("YYYY-MM-DD"), + study_weeks: parent.study_weeks, + classes_start_date: moment.utc(parent.classes_start_date).format("YYYY-MM-DD"), + classes_end_date: moment.utc(parent.classes_end_date).format("YYYY-MM-DD"), + study_months: parent.study_months, + family_size: parent.family_size, + dependent_count: parent.dependent_count, + student_ln150_income: parent.student_ln150_income, + spouse_ln150_income: parent.spouse_ln150_income, + parent1_income: parent.parent1_income, + parent2_income: parent.parent2_income, + relocation_total: parent.relocation_total, + discretionary_cost: parent.discretionary_cost, + discretionary_cost_actual: parent.discretionary_cost_actual, + tuition_estimate: parent.tuition_estimate, + books_supplies_cost: parent.books_supplies_cost, + r_trans_16wk: parent.r_trans_16wk, + shelter_month: parent.shelter_month, + p_trans_month: parent.p_trans_month, + day_care_allowable: parent.day_care_allowable, + day_care_actual: parent.day_care_actual, + depend_food_allowable: parent.depend_food_allowable, + depend_tran_allowable: parent.depend_tran_allowable, + spouse_expected_contribution: parent.spouse_expected_contribution, + student_expected_contribution: parent.student_expected_contribution, + student_contrib_exempt: parent.student_contrib_exempt, + spouse_contrib_exempt: parent.spouse_contrib_exempt, + student_contribution_review: parent.student_contribution_review, + spouse_contribution_review: parent.spouse_contribution_review, + parent_contribution_review: parent.parent_contribution_review, + }; + + commit("SET_ASSESSMENT", assessment); + } + }); + }, + + async recalculate({ state, dispatch, commit }) { + dispatch("loadAssessment", { id: state.fundingRequest.application_id, refreshChild: false }).then(() => { + let parent = state.parentAssessment; + + let assessment = { + id: state.assessment.id, + assessed_date: moment().format("YYYY-MM-DD"), + study_weeks: parent.study_weeks, + classes_start_date: moment.utc(parent.classes_start_date).format("YYYY-MM-DD"), + classes_end_date: moment.utc(parent.classes_end_date).format("YYYY-MM-DD"), + study_months: parent.study_months, + family_size: parent.family_size, + dependent_count: parent.dependent_count, + student_ln150_income: parent.student_ln150_income, + spouse_ln150_income: parent.spouse_ln150_income, + parent1_income: parent.parent1_income, + parent2_income: parent.parent2_income, + relocation_total: parent.relocation_total, + discretionary_cost: parent.discretionary_cost, + discretionary_cost_actual: parent.discretionary_cost_actual, + tuition_estimate: parent.tuition_estimate, + books_supplies_cost: parent.books_supplies_cost, + r_trans_16wk: parent.r_trans_16wk, + shelter_month: parent.shelter_month, + p_trans_month: parent.p_trans_month, + day_care_allowable: parent.day_care_allowable, + day_care_actual: parent.day_care_actual, + depend_food_allowable: parent.depend_food_allowable, + depend_tran_allowable: parent.depend_tran_allowable, + spouse_expected_contribution: parent.spouse_expected_contribution, + student_expected_contribution: parent.student_expected_contribution, + student_contrib_exempt: parent.student_contrib_exempt, + spouse_contrib_exempt: parent.spouse_contrib_exempt, + student_contribution_review: parent.student_contribution_review, + spouse_contribution_review: parent.spouse_contribution_review, + parent_contribution_review: parent.parent_contribution_review, + }; + + commit("SET_ASSESSMENT", assessment); + dispatch("save"); + }); + }, + + async makeDisbursements({ getters, commit, state, dispatch }, numberOfDisbursements) { + let parts = Math.ceil(getters.netAmount / numberOfDisbursements); + let disbursedValues = []; + + let total = 0; + + for (let i = 0; i < numberOfDisbursements - 1; i++) { + let amount = parse(formatMoney(parts), { currency: "usd" }); + total += amount; + + disbursedValues.push({ + disbursed_amount: amount, + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), // today + }); + } + + let remainder = parse(formatMoney(getters.netAmount - total), { currency: "usd" }); + + disbursedValues.push({ + disbursed_amount: remainder, + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), + }); + + await commit("SET_DISBURSEMENTS", [...state.disbursements, ...disbursedValues]); + + await axios.put(`${APPLICATION_URL}/${state.fundingRequest.application_id}/status/${state.fundingRequest.id}`, { + data: { status_id: 7 }, // Awarded + }); + + dispatch("save"); + }, + + async removeDisbursement({ state }, { item, index }) { + if (item.id) { + state.disbursements.splice(index, 1); + await axios.delete( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/disbursement/${item.id}` + ); + } else { + state.disbursements.splice(index, 1); + } + }, + + async addDisbursement({ state }) { + state.disbursements.push({ + disbursement_type_id: 4, + issue_date: moment().format("YYYY-MM-DD"), // today + }); + }, + + async save({ state, dispatch }) { + state.assessment.disbursements = state.disbursements; + + if (state.assessment.id) { + axios + .put( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/assessment/${state.assessment.id}`, + state.assessment + ) + .then((resp) => { + dispatch("loadAssessment", state.fundingRequest.application_id); + }); + } else { + axios + .post( + `${CSG_THRESHOLD_URL}/csgftdep/${state.fundingRequest.application_id}/funding-request/${state.fundingRequest.id}/assessment`, + state.assessment + ) + .then((resp) => { + dispatch("loadAssessment", state.fundingRequest.application_id); + }); + } + }, +}; + +export default { + state, + getters, + mutations, + actions, + namespaced: true, +}; + +function formatMoney(input) { + if (isNumber(input)) { + return Intl.NumberFormat("en", { + currency: "USD", + style: "currency", + }).format(input); + } + + return ""; +} 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 154fcb1b..df2eba23 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 @@ -66,10 +66,7 @@ const getters = { return state.fundingRequest?.csl_request_amount ?? 0; }, totalGrants(state) { - let value = 0; - // this needs to pull from CSGPT, CSGDep PT, CSG Disability - state.assessment.total_grant_awarded = value; - return value; + return state.assessment.total_grant_awarded; }, maxAllowable(state) { @@ -117,6 +114,10 @@ const getters = { assessedAmount(state, getters) { let value = 0; + + + console.log(getters.totalCosts , getters.totalGrants) + if (!getters.pastThreshold) value = Math.min(getters.maxAllowable, getters.totalCosts - getters.totalGrants); state.assessment.assessed_amount = value; @@ -179,10 +180,10 @@ const mutations = { }, }; const actions = { - async initialize(store, app) { + async initialize(localStore, app) { console.log("Initializing CSLPT"); - await store.dispatch("loadThresholds", app.academic_year_id); - store.dispatch("loadCSLPTAssessment", app.id); + await localStore.dispatch("loadThresholds", app.academic_year_id); + await localStore.dispatch("loadCSLPTAssessment", app.id); }, async loadThresholds({ commit }, academicYear) { @@ -195,7 +196,7 @@ const actions = { }, loadCSLPTAssessment({ commit, state, getters }, applicationId) { - axios.get(`${CSG_THRESHOLD_URL}/cslpt/${applicationId}`).then((resp) => { + axios.get(`${CSG_THRESHOLD_URL}/cslpt/${applicationId}`).then(async (resp) => { let application = store.getters.selectedApplication; commit("SET_APPLICATION", application); commit("SET_FUNDINGREQUEST", resp.data.data.funding_request); @@ -227,6 +228,11 @@ const actions = { let provinceMax = state.childcare?.find((c) => c.province_id == state.application.study_province_id); let dayCareAllowable = provinceMax?.max_amount ?? 0; + let totalGrants = 0; + totalGrants += store.getters["csgPartTimeStore/assessedAmount"]; + totalGrants += store.getters["csgPartTimeDependentStore/assessedAmount"]; + totalGrants += store.getters["csgPartTimeDisabilityStore/assessedAmount"]; + let assessment = { assessed_date: moment().format("YYYY-MM-DD"), classes_start_date: moment.utc(application.classes_start_date).format("YYYY-MM-DD"), @@ -260,7 +266,7 @@ const actions = { student_contrib_exempt: "N", spouse_contrib_exempt: "N", - total_grant_awarded: 0, + total_grant_awarded: totalGrants, assessed_amount: 0, student_contribution_review: "No", spouse_contribution_review: "No", @@ -270,13 +276,19 @@ const actions = { commit("SET_ASSESSMENT", assessment); } + + // child store initializers + await store.dispatch("csgPartTimeStore/initialize", { app: application, assessment: state.assessment }); + await store.dispatch("csgPartTimeDependentStore/initialize", { app: application, assessment: state.assessment }); + await store.dispatch("csgPartTimeDisabilityStore/initialize", { app: application, assessment: state.assessment }); }); }, async recalculate({ state, dispatch, commit }) { - dispatch("loadCSLPTAssessment", { id: state.fundingRequest.application_id, refreshChild: false }).then(() => { + dispatch("loadCSLPTAssessment", state.fundingRequest.application_id).then(() => { let dependentCount = 0; let familySize = 1; + let application = state.application; // Common-law or Married if ([3, 4].includes(state.application.csl_classification)) familySize++; @@ -294,6 +306,11 @@ const actions = { let provinceMax = state.childcare?.find((c) => c.province_id == state.application.study_province_id); let dayCareAllowable = provinceMax?.max_amount ?? 0; + let totalGrants = 0; + totalGrants += store.getters["csgPartTimeStore/assessedAmount"]; + totalGrants += store.getters["csgPartTimeDependentStore/assessedAmount"]; + totalGrants += store.getters["csgPartTimeDisabilityStore/assessedAmount"]; + let assessment = { assessed_date: moment().format("YYYY-MM-DD"), classes_start_date: moment.utc(application.classes_start_date).format("YYYY-MM-DD"), @@ -327,7 +344,7 @@ const actions = { student_contrib_exempt: "N", spouse_contrib_exempt: "N", - total_grant_awarded: 0, + total_grant_awarded: totalGrants, assessed_amount: 0, student_contribution_review: "No", spouse_contribution_review: "No", @@ -335,6 +352,8 @@ const actions = { }; assessment.period = assessment.study_months <= 4 ? "S" : "P"; + console.log(assessment); + commit("SET_ASSESSMENT", assessment); dispatch("save"); }); @@ -435,5 +454,3 @@ function formatMoney(input) { return ""; } - -function buildAssessment(application, fundingReqest) {} diff --git a/src/web/src/components/application/assessments/views/CSLPT.vue b/src/web/src/components/application/assessments/views/CSLPT.vue index ffcfb1e5..7cedd1dd 100644 --- a/src/web/src/components/application/assessments/views/CSLPT.vue +++ b/src/web/src/components/application/assessments/views/CSLPT.vue @@ -19,12 +19,18 @@ - BASE - COSTS - Grant - Dependent Grant - Disability Grant - AWARD + Base + Costs
{{ formatMoney(totalCosts) }}
+ Grant
{{ formatMoney(grantAmount) }}
+ Dependent Grant
+ {{ formatMoney(depAmount) }}
+ Disability Grant
+ {{ formatMoney(disAmount) }}
+ Loan
{{ formatMoney(assessedAmount) }}
MSFAA
@@ -37,13 +43,13 @@ - + - + - + @@ -55,10 +61,32 @@
-
+
+ + + + + + diff --git a/src/web/src/store/index.js b/src/web/src/store/index.js index e4613b8f..33d7c1ac 100644 --- a/src/web/src/store/index.js +++ b/src/web/src/store/index.js @@ -80,6 +80,9 @@ import csgMatureStore from "../components/application/assessments/store/csg-matu import csgFullTimeStore from "../components/application/assessments/store/csg-full-time"; import csgDisabilitySEStore from "../components/application/assessments/store/csg-disability-se"; import cslPartTimeStore from "../components/application/assessments/store/csl-part-time"; +import csgPartTimeStore from "../components/application/assessments/store/csg-part-time"; +import csgPartTimeDependentStore from "../components/application/assessments/store/csg-part-time-dependent"; +import csgPartTimeDisabilityStore from "../components/application/assessments/store/csg-part-time-disability"; // Administration Stores import reportsStore from "@/modules/Administration/store/ReportsStore"; @@ -571,7 +574,10 @@ export default new Vuex.Store({ csgFullTimeStore, csgDisabilitySEStore, cslPartTimeStore, - + csgPartTimeStore, + csgPartTimeDependentStore, + csgPartTimeDisabilityStore, + reportsStore, }, }); From 8cd34d2f0ce098365f47b66777697a37593ee0c3 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Thu, 12 Oct 2023 16:17:35 -0700 Subject: [PATCH 6/9] Reformat --- src/api/routes/admin/application-router.ts | 354 ++++++++++-------- src/web/src/components/ConfirmDialog.vue | 2 +- .../application/assessments/views/CSLPT.vue | 10 +- .../csfa-part-time/CSFAPartTime.vue | 29 +- 4 files changed, 200 insertions(+), 195 deletions(-) diff --git a/src/api/routes/admin/application-router.ts b/src/api/routes/admin/application-router.ts index 17863337..e48ecd51 100644 --- a/src/api/routes/admin/application-router.ts +++ b/src/api/routes/admin/application-router.ts @@ -168,29 +168,30 @@ applicationRouter.post( } ); -applicationRouter.get("/flags", async (req: Request, res: Response) => { +applicationRouter.get("/flags", async (req: Request, res: Response) => { let flagList = await db("sfa.application").whereNotNull("flags").select("flags").distinct(); - let flags = uniq(flagList.flatMap(f => f.flags.split(","))).map(i => i.trim()).filter(i => !isEmpty(i)); + let flags = uniq(flagList.flatMap((f) => f.flags.split(","))) + .map((i) => i.trim()) + .filter((i) => !isEmpty(i)); - res.json({data: flags }) -}) + res.json({ data: flags }); +}); applicationRouter.get("/flags/:flag", ReturnValidationErrors, async (req: Request, res: Response) => { try { const { flag } = req.params; let applications = await db("sfa.application") - .leftJoin("sfa.institution_campus", "application.institution_campus_id", "institution_campus.id") - .leftJoin("sfa.institution", "institution.id", "institution_campus.institution_id") - .leftJoin("sfa.student", "student.id", "application.student_id") - .leftJoin("sfa.person", "student.person_id", "person.id") - .select("application.*") - .select("institution.name as institution_name") - .select("person.first_name") - .select("person.last_name") - .limit(150) - .whereLike("flags", `%${flag}%`) - .orderBy("updated_at", "desc"); - + .leftJoin("sfa.institution_campus", "application.institution_campus_id", "institution_campus.id") + .leftJoin("sfa.institution", "institution.id", "institution_campus.institution_id") + .leftJoin("sfa.student", "student.id", "application.student_id") + .leftJoin("sfa.person", "student.person_id", "person.id") + .select("application.*") + .select("institution.name as institution_name") + .select("person.first_name") + .select("person.last_name") + .limit(150) + .whereLike("flags", `%${flag}%`) + .orderBy("updated_at", "desc"); for (let item of applications) { item.title = `${item.first_name} ${item.last_name} - ${item.academic_year_id}: ${item.institution_name}`; @@ -526,72 +527,83 @@ applicationRouter.get("/:id", [param("id").notEmpty()], ReturnValidationErrors, res.status(404).send(); }); +applicationRouter.delete( + "/:id", + [param("id").notEmpty()], + ReturnValidationErrors, + async (req: Request, res: Response) => { + const { id } = req.params; -applicationRouter.delete("/:id", [param("id").notEmpty()], ReturnValidationErrors, async (req: Request, res: Response) => { - const {id} = req.params; + let disbursements = await db("sfa.disbursement") + .join("sfa.funding_request", "funding_request.id", "disbursement.funding_request_id") + .where("funding_request.application_id", id) + .select("disbursement.*"); + + if (disbursements.length > 0) { + return res + .status(400) + .json({ + data: {}, + messages: [{ variant: "error", text: "This application has disbursements and cannot be deleted" }], + }); + } - let disbursements = await db("sfa.disbursement") - .join("sfa.funding_request","funding_request.id","disbursement.funding_request_id") - .where("funding_request.application_id", id) - .select("disbursement.*"); + let fundingRequests = await db("sfa.funding_request").where({ application_id: id }).select("id"); + let frIds = fundingRequests.map((r) => r.id); - if (disbursements.length > 0) { - return res.status(400).json({data: {}, messages: [{variant: "error", text: "This application has disbursements and cannot be deleted"}]}) - } + let msfaas = await db("sfa.msfaa").where({ application_id: id }).select("id"); + let msIds = msfaas.map((r) => r.id); - let fundingRequests = await db("sfa.funding_request").where({application_id: id}).select("id"); - let frIds = fundingRequests.map(r => r.id); - - let msfaas = await db("sfa.msfaa").where({application_id: id}).select("id"); - let msIds = msfaas.map(r => r.id); + let trx = await db.transaction(); - let trx = await db.transaction(); + try { + let d1 = trx("sfa.agency_assistance").where({ application_id: id }).delete(); + let d2 = trx("sfa.application_part_time_reason").where({ application_id: id }).delete(); + let d3 = trx("sfa.course_enrolled").where({ application_id: id }).delete(); + let d4 = trx("sfa.dependent_eligibility").where({ application_id: id }).delete(); + let d5 = trx("sfa.disability").where({ application_id: id }).delete(); + let d6 = trx("sfa.disability_requirement").where({ application_id: id }).delete(); + let d7 = trx("sfa.equipment_required").where({ application_id: id }).delete(); + let d8 = trx("sfa.expense").where({ application_id: id }).delete(); + let d9 = trx("sfa.income").where({ application_id: id }).delete(); + let d10 = trx("sfa.investment").where({ application_id: id }).delete(); + let d11 = trx("sfa.parent_dependent").where({ application_id: id }).delete(); + let d12 = trx("sfa.parent_resident").where({ application_id: id }).delete(); + let d13 = trx("sfa.requirement_met").where({ application_id: id }).delete(); + let d14 = trx("sfa.file_reference").where({ application_id: id }).update({ application_id: null }); + let d15 = trx("sfa.csl_nars_history").where({ application_id: id }).delete(); + let d16 = trx("sfa.disbursement").whereIn("funding_request_id", frIds).delete(); + let d17 = trx("sfa.assessment").whereIn("funding_request_id", frIds).delete(); + let d18 = trx("sfa.msfaa_email_log").whereIn("msfaa_id", msIds).delete(); + let d19 = trx("sfa.communication_log").whereIn("msfaa_id", msIds).delete(); + + Promise.all([d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19]) + .then(async () => { + let d20 = trx("sfa.funding_request").where({ application_id: id }).delete(); + let d21 = trx("sfa.msfaa").where({ application_id: id }).delete(); + + await Promise.all([d20, d21]).then(async () => { + return trx("sfa.application").where({ id }).delete(); + }); - try { - let d1 = trx("sfa.agency_assistance").where({application_id: id}).delete() - let d2 = trx("sfa.application_part_time_reason").where({application_id: id}).delete() - let d3 = trx("sfa.course_enrolled").where({application_id: id}).delete() - let d4 = trx("sfa.dependent_eligibility").where({application_id: id}).delete() - let d5 = trx("sfa.disability").where({application_id: id}).delete() - let d6 = trx("sfa.disability_requirement").where({application_id: id}).delete() - let d7 = trx("sfa.equipment_required").where({application_id: id}).delete() - let d8 = trx("sfa.expense").where({application_id: id}).delete() - let d9 = trx("sfa.income").where({application_id: id}).delete() - let d10 = trx("sfa.investment").where({application_id: id}).delete() - let d11 = trx("sfa.parent_dependent").where({application_id: id}).delete() - let d12 = trx("sfa.parent_resident").where({application_id: id}).delete() - let d13 = trx("sfa.requirement_met").where({application_id: id}).delete() - let d14 = trx("sfa.file_reference").where({application_id: id}).update({application_id: null}) - let d15 = trx("sfa.csl_nars_history").where({application_id: id}).delete() - let d16 = trx("sfa.disbursement").whereIn("funding_request_id", frIds).delete() - let d17 = trx("sfa.assessment").whereIn("funding_request_id", frIds).delete() - let d18 = trx("sfa.msfaa_email_log").whereIn("msfaa_id", msIds).delete() - let d19 = trx("sfa.communication_log").whereIn("msfaa_id", msIds).delete() - - Promise.all([d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,d18,d19]) - .then(async () => { - let d20 = trx("sfa.funding_request").where({application_id: id}).delete() - let d21 = trx("sfa.msfaa").where({application_id: id}).delete() - - await Promise.all([d20, d21]).then(async () => { - return trx("sfa.application").where({id}).delete(); + await trx.commit(); + res.json({ data: {}, messages: [{ variant: "success", text: "Application deleted" }] }); + }) + .catch(async (err) => { + await trx.rollback(); + console.log("ERROR DELETING, ROLLBACK", err.message); + return res + .status(500) + .json({ data: {}, messages: [{ variant: "error", text: "Error deleting application: " + err.message }] }); }); - - await trx.commit(); - res.json({data: {}, messages: [{variant: "success", text: "Application deleted"}]}) - }) - .catch(async(err) => { - await trx.rollback(); - console.log("ERROR DELETING, ROLLBACK", err.message) - return res.status(500).json({ data: {}, messages: [{variant: "error", text: "Error deleting application: " + err.message}]}) - }) - } - catch(e: any) { - trx.rollback(); - return res.status(500).json({ data: {}, messages: [{variant: "error", text: "Error deleting application: " + e.message}]}) + } catch (e: any) { + trx.rollback(); + return res + .status(500) + .json({ data: {}, messages: [{ variant: "error", text: "Error deleting application: " + e.message }] }); + } } -}); - +); applicationRouter.put("/:id", [param("id").notEmpty()], ReturnValidationErrors, async (req: Request, res: Response) => { let { id } = req.params; @@ -742,103 +754,115 @@ applicationRouter.post("/:application_id/student/:student_id/files", async (req: // updates _met applicationRouter.post( - "/:application_id/student/:student_id/files/:requirement_type_id", - [ - param("application_id").isInt().notEmpty(), - param("student_id").isInt().notEmpty(), - param("requirement_type_id").isInt().notEmpty() - ], - ReturnValidationErrors, - async (req: Request, res: Response) => { - try { - const { application_id, student_id, requirement_type_id } = req.params; - let { completed_date, data } = req.body; - const application: any = await db("sfa.file_reference").where({ application_id: application_id }).andWhere({ student_id: student_id }).andWhere({ requirement_type_id: requirement_type_id }).first(); - - const alreadyExist: any = await db("sfa.requirement_met").where({ application_id: application_id }).andWhere({ requirement_type_id: requirement_type_id }).first(); - const compDate = completed_date; - - if (application) { - if(alreadyExist) { - try { - const appId = application_id; - const resUpdate = await db("sfa.requirement_met").where({application_id: application_id}).andWhere({requirement_type_id: requirement_type_id}) - //.update({ ...data }); - .update({ completed_date: completed_date && completed_date !== 'null' ? completed_date : null}); - - return resUpdate ? - res.json({ messages: [{ variant: "success", text: "Saved" }] }) - : - res.json({ messages: [{ variant: "error", text: "Failed" }] }); - - } catch (error) { - return res.json({ messages: [{ text: "Failed to update Funding Request", variant: "error" }] }); - } - } else { - let resInsert; - try { - resInsert = await db("sfa.requirement_met").insert({ completed_date: completed_date && completed_date !== 'null' ? completed_date : null, requirement_type_id, application_id }); - - } catch(error) { - console.log(error) - return res.json({ messages: [{ variant: "error", text: "Failed to update Funding Request" }] }); - } - return resInsert ? - res.json({ messages: [{ variant: "success", text: "Saved" }] }) - : - res.json({ messages: [{ variant: "error", text: "Save failed" }] }); - } - + "/:application_id/student/:student_id/files/:requirement_type_id", + [ + param("application_id").isInt().notEmpty(), + param("student_id").isInt().notEmpty(), + param("requirement_type_id").isInt().notEmpty(), + ], + ReturnValidationErrors, + async (req: Request, res: Response) => { + try { + const { application_id, student_id, requirement_type_id } = req.params; + let { completed_date, data } = req.body; + const application: any = await db("sfa.file_reference") + .where({ application_id: application_id }) + .andWhere({ student_id: student_id }) + .andWhere({ requirement_type_id: requirement_type_id }) + .first(); - } + const alreadyExist: any = await db("sfa.requirement_met") + .where({ application_id: application_id }) + .andWhere({ requirement_type_id: requirement_type_id }) + .first(); + const compDate = completed_date; - return res.status(404).send(); + if (application) { + if (alreadyExist) { + try { + const appId = application_id; + const resUpdate = await db("sfa.requirement_met") + .where({ application_id: application_id }) + .andWhere({ requirement_type_id: requirement_type_id }) + //.update({ ...data }); + .update({ completed_date: completed_date && completed_date !== "null" ? completed_date : null }); - } catch (error) { - console.error(error); - return res.status(400).send(error); + return resUpdate + ? res.json({ messages: [{ variant: "success", text: "Saved" }] }) + : res.json({ messages: [{ variant: "error", text: "Failed" }] }); + } catch (error) { + return res.json({ messages: [{ text: "Failed to update Funding Request", variant: "error" }] }); + } + } else { + let resInsert; + try { + resInsert = await db("sfa.requirement_met").insert({ + completed_date: completed_date && completed_date !== "null" ? completed_date : null, + requirement_type_id, + application_id, + }); + } catch (error) { + console.log(error); + return res.json({ messages: [{ variant: "error", text: "Failed to update Funding Request" }] }); + } + return resInsert + ? res.json({ messages: [{ variant: "success", text: "Saved" }] }) + : res.json({ messages: [{ variant: "error", text: "Save failed" }] }); } + } + + return res.status(404).send(); + } catch (error) { + console.error(error); + return res.status(400).send(error); } + } ); // downloads a document with extra parameters applicationRouter.get( - "/:application_id/student/:student_id/files/:file_type/fellow_type/:fellow_type/fellow/:fellow", - async (req: Request, res: Response) => { - - const { student_id, application_id, file_type, fellow_type, fellow } = req.params; - - - let doc:any; - switch(fellow_type) { - case "dependent": - doc = await db("sfa.file_reference").where({ application_id: application_id}).andWhere({student_id: student_id}).andWhere - ({requirement_type_id: file_type}).andWhere({dependent_id: fellow}).orderBy("upload_date", "desc").first(); - break; - case "parent": - doc = await db("sfa.file_reference").where({ application_id: application_id}).andWhere({student_id: student_id}).andWhere - ({requirement_type_id: file_type}).andWhere({fellow_type: fellow}).orderBy("upload_date", "desc").first(); - break; - - } - - if(doc) { - let fileReference = await documentService.getDocumentWithFile(doc.object_key); - - if ( - fileReference && - fileReference.student_id == parseInt(student_id) && - fileReference.application_id == parseInt(application_id) - ) { - res.set("Content-disposition", "attachment; filename=" + fileReference.file_name); - res.set("Content-type", fileReference.mime_type); - return res.send(fileReference.file_contents); - } - + "/:application_id/student/:student_id/files/:file_type/fellow_type/:fellow_type/fellow/:fellow", + async (req: Request, res: Response) => { + const { student_id, application_id, file_type, fellow_type, fellow } = req.params; + + let doc: any; + switch (fellow_type) { + case "dependent": + doc = await db("sfa.file_reference") + .where({ application_id: application_id }) + .andWhere({ student_id: student_id }) + .andWhere({ requirement_type_id: file_type }) + .andWhere({ dependent_id: fellow }) + .orderBy("upload_date", "desc") + .first(); + break; + case "parent": + doc = await db("sfa.file_reference") + .where({ application_id: application_id }) + .andWhere({ student_id: student_id }) + .andWhere({ requirement_type_id: file_type }) + .andWhere({ fellow_type: fellow }) + .orderBy("upload_date", "desc") + .first(); + break; } - - res.status(404).send(); + + if (doc) { + let fileReference = await documentService.getDocumentWithFile(doc.object_key); + + if ( + fileReference && + fileReference.student_id == parseInt(student_id) && + fileReference.application_id == parseInt(application_id) + ) { + res.set("Content-disposition", "attachment; filename=" + fileReference.file_name); + res.set("Content-type", fileReference.mime_type); + return res.send(fileReference.file_contents); + } } + + res.status(404).send(); + } ); applicationRouter.put( @@ -2408,10 +2432,9 @@ applicationRouter.post( .innerJoin("sfa.student AS s", "s.id", "app.student_id") .where("a.id", insert_response[0].id) .first(); - + if (student?.vendor_id) { for (const item of dataDisburse) { - if (!existYEARequestType && item?.disbursement_type_id === 1) { existYEARequestType = true; } @@ -2444,16 +2467,17 @@ applicationRouter.post( const updateYeaRequestType = await db("sfa.funding_request") .where({ id: funding_request_id }) .update({ yea_request_type: existYEARequestType ? 1 : 2 }); - } else { return res.json({ messages: [ - { text: "Saved, but student must have a Vendor ID to create disbursements", variant: "success" }, + { + text: "Saved, but student must have a Vendor ID to create disbursements", + variant: "success", + }, ], data: [], }); } - } const updateStatusFundingRequest = await db("sfa.funding_request") diff --git a/src/web/src/components/ConfirmDialog.vue b/src/web/src/components/ConfirmDialog.vue index d21e0e8f..3d98a31d 100644 --- a/src/web/src/components/ConfirmDialog.vue +++ b/src/web/src/components/ConfirmDialog.vue @@ -3,7 +3,7 @@ {{ title }} {{ message }} - + Confirm {{messageButton}} diff --git a/src/web/src/components/application/assessments/views/CSLPT.vue b/src/web/src/components/application/assessments/views/CSLPT.vue index 7cedd1dd..43587834 100644 --- a/src/web/src/components/application/assessments/views/CSLPT.vue +++ b/src/web/src/components/application/assessments/views/CSLPT.vue @@ -10,7 +10,7 @@
Assessment - CSLPT + >Assessment: CSL-PT Recalculate @@ -21,16 +21,16 @@ Base Costs
{{ formatMoney(totalCosts) }}
- Grant
{{ formatMoney(grantAmount) }}
+ CSG-PT
{{ formatMoney(grantAmount) }}
Dependent Grant
+ >CSG-PTDEP
{{ formatMoney(depAmount) }}
Disability Grant
+ >CSGD
{{ formatMoney(disAmount) }}
- Loan
{{ formatMoney(assessedAmount) }}
+ CSL-PT
{{ formatMoney(assessedAmount) }}
MSFAA
diff --git a/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue b/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue index 4f0dfb5a..0d315a44 100644 --- a/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue +++ b/src/web/src/components/application/csfa-funding-requests/csfa-part-time/CSFAPartTime.vue @@ -14,10 +14,9 @@
- +
fr.request_type_id === 5); @@ -558,7 +539,7 @@ export default { }, async addFundingRequest(type) { try { - const resInsert = await axios.post(APPLICATION_URL + `/${this.application.id}/status`, { + const resInsert = await axios.post(`${APPLICATION_URL}/${this.application.id}/status`, { request_type_id: type, received_date: new Date(), }); @@ -587,7 +568,7 @@ export default { return; } - const resInsert = await axios.post(APPLICATION_URL + `/${this.application.id}/course`, { + const resInsert = await axios.post(`${APPLICATION_URL}/${this.application.id}/course`, { data: { ...this.newRecord, application_id: this.application.id }, }); const message = resInsert?.data?.messages[0]; From 1e945ef1afdda61bf189e7464f0f04dc9db7ad30 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Fri, 13 Oct 2023 06:27:50 -0700 Subject: [PATCH 7/9] Cleanup format --- src/api/routes/admin/application-router.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/api/routes/admin/application-router.ts b/src/api/routes/admin/application-router.ts index e48ecd51..856fc77a 100644 --- a/src/api/routes/admin/application-router.ts +++ b/src/api/routes/admin/application-router.ts @@ -540,12 +540,10 @@ applicationRouter.delete( .select("disbursement.*"); if (disbursements.length > 0) { - return res - .status(400) - .json({ - data: {}, - messages: [{ variant: "error", text: "This application has disbursements and cannot be deleted" }], - }); + return res.status(400).json({ + data: {}, + messages: [{ variant: "error", text: "This application has disbursements and cannot be deleted" }], + }); } let fundingRequests = await db("sfa.funding_request").where({ application_id: id }).select("id"); @@ -647,12 +645,9 @@ applicationRouter.post( status_date, comments, }; - const checkIsActive = await db("sfa.request_type").where("id", request_type_id).first(); - const checkIfExist = await db("sfa.funding_request") - .where("request_type_id", request_type_id) - .where("application_id", application_id) - .first(); + // see if this application already has this funding request + const checkIfExist = await db("sfa.funding_request").where({ request_type_id, application_id }).first(); if (checkIfExist) { return res.json({ @@ -660,6 +655,9 @@ applicationRouter.post( }); } + // make sure request type is active + const checkIsActive = await db("sfa.request_type").where("id", request_type_id).first(); + if (checkIsActive?.is_active) { if (newRecord.request_type_id === 1) { const isSTACandidate = await db("sfa.institution_campus") @@ -976,7 +974,7 @@ applicationRouter.delete( async (req: Request, res: Response) => { const { id } = req.params; try { - const verifyRecord: any = await db("sfa.funding_request").where({ id: id }).first(); + const verifyRecord: any = await db("sfa.funding_request").where({ id }).first(); if (!verifyRecord) { return res.status(404).send({ messages: [{ variant: "error", text: "The record does not exits" }] }); From 150ccf9074dfad34a7fa7b8214bf64d2976bd2c3 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Fri, 13 Oct 2023 06:28:24 -0700 Subject: [PATCH 8/9] CSL PT --- src/web/src/components/application/Status.vue | 12 +- .../components/csg-disbursements.vue | 4 +- .../components/csl-disbursements.vue | 2 +- .../components/csl-pt/tab-award.vue | 381 ++++++++++-------- .../components/csl-pt/tab-base.vue | 364 ++++++++--------- .../components/csl-pt/tab-costs.vue | 326 +++++++-------- .../components/csl-pt/tab-dependent.vue | 361 +++++++++-------- .../components/csl-pt/tab-disability.vue | 277 +++++++------ .../components/csl-pt/tab-grant.vue | 277 +++++++------ .../components/csl-pt/tab-msfaa.vue | 278 ++++++------- .../components/cslpt-disbursements.vue | 8 +- .../store/csg-part-time-dependent.js | 26 ++ .../store/csg-part-time-disability.js | 19 +- .../assessments/store/csg-part-time.js | 18 + .../assessments/store/csl-part-time.js | 20 +- .../application/assessments/views/CSLPT.vue | 99 ++--- 16 files changed, 1344 insertions(+), 1128 deletions(-) diff --git a/src/web/src/components/application/Status.vue b/src/web/src/components/application/Status.vue index c73a47b3..250892f0 100644 --- a/src/web/src/components/application/Status.vue +++ b/src/web/src/components/application/Status.vue @@ -17,8 +17,14 @@
-
- +
+
Add - +