From 100c817b56063a7152f781de44feeee9a1c5a66b Mon Sep 17 00:00:00 2001 From: R Ranathunga Date: Wed, 18 Sep 2024 15:01:22 -0700 Subject: [PATCH 1/2] chore: import fnha funding from sow tab 7 --- app/backend/lib/sow_import/tab_7.ts | 36 ++- .../helpers/ccbcSummaryGenerateFormData.tsx | 5 +- app/tests/backend/lib/sow_tab_7.test.ts | 221 +++++++++++++++++- 3 files changed, 250 insertions(+), 12 deletions(-) diff --git a/app/backend/lib/sow_import/tab_7.ts b/app/backend/lib/sow_import/tab_7.ts index c47905f8d..fbfd2f92b 100644 --- a/app/backend/lib/sow_import/tab_7.ts +++ b/app/backend/lib/sow_import/tab_7.ts @@ -27,6 +27,7 @@ const readBudget = async (sow_id, wb, sheet_name) => { fundingFromAllOtherSources: '', amountRequestedFromProvince: '', totalInfrastructureBankFunding: '', + totalFNHAFunding: '', totalFundingRequestedCCBC: '', }, detailedBudget: { @@ -126,6 +127,13 @@ const readBudget = async (sow_id, wb, sheet_name) => { 2627: '', total: '', }, + fnhaFunding: { + 2324: '', + 2425: '', + 2526: '', + 2627: '', + total: '', + }, otherFundingPartners: [], totalFinancialContribution: { 2324: '', @@ -472,6 +480,7 @@ const readBudget = async (sow_id, wb, sheet_name) => { budget[row]['K']; row++; // next 7 are possible other + let fnhaFundingRow = {}; for (let otherRow = row; otherRow < row + 7; otherRow++) { const otherSuspect = budget[otherRow]['B']; let otherValue; @@ -483,8 +492,14 @@ const readBudget = async (sow_id, wb, sheet_name) => { } // if we don't have the predefined phrase, we have a custom other if ( - otherValue.indexOf('Identify other source of funding by name') === -1 + otherValue.indexOf('Identify other source of funding by name') > -1 + ) { + continue; + } else if ( + otherValue.indexOf('First Nations Health Authority (FNHA)') > -1 ) { + fnhaFundingRow = budget[otherRow]; + } else { detailedBudget.summaryOfEstimatedProjectFunding.otherFundingPartners.push( { fundingPartnersName: budget[otherRow]['B'], @@ -497,6 +512,19 @@ const readBudget = async (sow_id, wb, sheet_name) => { ); } } + + // FNHA Funding + detailedBudget.summaryOfEstimatedProjectFunding.fnhaFunding[2324] = + fnhaFundingRow['G'] ?? 0; + detailedBudget.summaryOfEstimatedProjectFunding.fnhaFunding[2425] = + fnhaFundingRow['H'] ?? 0; + detailedBudget.summaryOfEstimatedProjectFunding.fnhaFunding[2526] = + fnhaFundingRow['I'] ?? 0; + detailedBudget.summaryOfEstimatedProjectFunding.fnhaFunding[2627] = + fnhaFundingRow['J'] ?? 0; + detailedBudget.summaryOfEstimatedProjectFunding.fnhaFunding.total = + fnhaFundingRow['K'] ?? 0; + detailedBudget.summaryTable.totalFNHAFunding = fnhaFundingRow['K'] ?? 0; } // get totals if (value.indexOf('Total Financial Contributions') > -1) { @@ -632,6 +660,12 @@ const ValidateData = (data) => { error: 'Invalid data: Amount CIB will contribute', }); } + if (typeof data.totalFNHAFunding !== 'number') { + errors.push({ + level: 'cell', + error: 'Invalid data: First Nations Health Authority (FNHA)', + }); + } if (typeof data.fundingFromAllOtherSources !== 'number') { errors.push({ level: 'cell', diff --git a/app/lib/helpers/ccbcSummaryGenerateFormData.tsx b/app/lib/helpers/ccbcSummaryGenerateFormData.tsx index d966b717a..d3e2656c7 100644 --- a/app/lib/helpers/ccbcSummaryGenerateFormData.tsx +++ b/app/lib/helpers/ccbcSummaryGenerateFormData.tsx @@ -173,7 +173,9 @@ const getSowData = (sowData, baseSowData) => { cibFunding: sowData?.nodes[0]?.sowTab7SBySowId?.nodes[0]?.jsonData?.summaryTable ?.totalInfrastructureBankFunding, - fhnaFunding: null, + fhnaFunding: + sowData?.nodes[0]?.sowTab7SBySowId?.nodes[0]?.jsonData?.summaryTable + ?.totalFNHAFunding, otherFunding: sowData?.nodes[0]?.sowTab7SBySowId?.nodes[0]?.jsonData?.summaryTable ?.fundingFromAllOtherSources, @@ -203,6 +205,7 @@ const getSowData = (sowData, baseSowData) => { fundingRequestedCcbc: 'SOW', applicantAmount: 'SOW', cibFunding: 'SOW', + fhnaFunding: 'SOW', otherFunding: 'SOW', totalProjectBudget: 'SOW', effectiveStartDate: 'SOW', diff --git a/app/tests/backend/lib/sow_tab_7.test.ts b/app/tests/backend/lib/sow_tab_7.test.ts index b3f7e9bd6..4342e5c0f 100644 --- a/app/tests/backend/lib/sow_tab_7.test.ts +++ b/app/tests/backend/lib/sow_tab_7.test.ts @@ -9,7 +9,7 @@ import LoadTab7Data from '../../../backend/lib/sow_import/tab_7'; jest.mock('../../../backend/lib/graphql'); -const tab7 = [ +const getTab7 = (includesFNHA = false) => [ { B: 'Universal Broadband Fund' }, { B: 'Step 7. Detailed Budget' }, { @@ -1624,14 +1624,23 @@ const tab7 = [ K: 0, }, { B: 'Other Funding Source', G: 1, H: 2, I: 3, J: 4, K: 10 }, - { - B: 'Identify other source of funding by name', - G: 0, - H: 0, - I: 0, - J: 0, - K: 0, - }, + includesFNHA + ? { + B: 'First Nations Health Authority (FNHA)', + G: 10000, + H: 25000, + I: 35000, + J: 10000, + K: 80000, + } + : { + B: 'Identify other source of funding by name', + G: 0, + H: 0, + I: 0, + J: 0, + K: 0, + }, { B: 'Identify other source of funding by name', G: 0, @@ -1735,6 +1744,9 @@ const tab7 = [ }, ]; +const tab7 = getTab7(); +const tab7WithFNHA = getTab7(true); + describe('sow tab 7 tests', () => { beforeEach(() => { mocked(performQuery).mockImplementation(async () => { @@ -1762,6 +1774,7 @@ describe('sow tab 7 tests', () => { amountRequestedFromProvince: 225000, totalInfrastructureBankFunding: 0, totalFundingRequestedCCBC: 450000, + totalFNHAFunding: 0, }, detailedBudget: { federalSharingRatio: 0.45, @@ -1838,6 +1851,13 @@ describe('sow tab 7 tests', () => { '2627': 25000, total: 225000, }, + fnhaFunding: { + '2324': 0, + '2425': 0, + '2526': 0, + '2627': 0, + total: 0, + }, infrastructureBankFunding: { '2324': 0, '2425': 0, @@ -1915,7 +1935,7 @@ describe('sow tab 7 tests', () => { }); it('should parse the worksheet and return expected errors', async () => { - const broken = { ...tab7 }; + const broken = structuredClone(tab7WithFNHA); broken[23]['H'] = 'garbage'; // Total Eligible Costs broken[24]['H'] = 'garbage'; // Total Ineligible Costs broken[25]['H'] = 'garbage'; // Total Project Cost @@ -1923,6 +1943,7 @@ describe('sow tab 7 tests', () => { broken[27]['J'] = 'garbage'; // Amount requested from the Province broken[28]['H'] = 'garbage'; // Amount Applicant will contribute broken[28]['J'] = 'garbage'; // Amount CIB will contribute + broken[1088]['K'] = 'garbage'; // Total FNHA Contributions broken[29]['H'] = 'garbage'; // Funding from all other sources broken[29]['J'] = 'garbage'; // Total requested from the CCBC Program @@ -1944,6 +1965,10 @@ describe('sow tab 7 tests', () => { error: 'Invalid data: Amount Applicant will contribute', }, { level: 'cell', error: 'Invalid data: Amount CIB will contribute' }, + { + level: 'cell', + error: 'Invalid data: First Nations Health Authority (FNHA)', + }, { level: 'cell', error: 'Invalid data: Funding from all other sources', @@ -1961,6 +1986,182 @@ describe('sow tab 7 tests', () => { expect(data).toEqual(expectedError); }); + it('should parse the worksheet and return fnha funding figures', async () => { + const expectedInput = { + input: { + sowId: 1, + jsonData: { + summaryTable: { + targetingVeryRemoteOrIndigenousOrSatelliteDependentCommunity: false, + totalEligibleCosts: 500000, + totalIneligibleCosts: 250000, + totalProjectCost: 750000, + amountRequestedFromFederalGovernment: 225000, + totalApplicantContribution: 300000, + fundingFromAllOtherSources: 225000, + amountRequestedFromProvince: 225000, + totalInfrastructureBankFunding: 0, + totalFundingRequestedCCBC: 450000, + totalFNHAFunding: 80000, + }, + detailedBudget: { + federalSharingRatio: 0.45, + provincialSharingRatio: 0.45, + }, + summaryOfEstimatedProjectCosts: { + estimatedProjectCosts: { + eligibleRuralBroadband: 500000, + eligibleVeryRemoteSatelliteIndigenousBroadband: 0, + eligibleMobile: 0, + totalEligibleCosts: 500000, + totalIneligibleCosts: 250000, + totalProjectCost: '', + }, + totalCostsPerCostCategory: { + directLabour: { cost: 80000, percentOfTotalEligibleCosts: 0.16 }, + directEquipment: { + cost: 140000, + percentOfTotalEligibleCosts: 0.28, + }, + directMaterials: { + cost: 180000, + percentOfTotalEligibleCosts: 0.36, + }, + directSatellite: { cost: 0, percentOfTotalEligibleCosts: 0 }, + directTravel: { cost: 0, percentOfTotalEligibleCosts: 0 }, + directOther: { cost: 100000, percentOfTotalEligibleCosts: 0.2 }, + totalEligible: { cost: 500000, percentOfTotalEligibleCosts: 1 }, + }, + thirtyPercentOfTotalEligibleCosts: 150000, + projectCosts: { + totalEligibleCosts: { + '2324': 100000, + '2425': 150000, + '2526': 150000, + '2627': 100000, + total: 500000, + }, + totalIneligibleCosts: { + '2324': 50000, + '2425': 100000, + '2526': 100000, + '2627': 0, + total: 250000, + }, + totalProjectCost: { + '2324': 100000, + '2425': 0.2, + '2526': undefined, + '2627': undefined, + total: undefined, + }, + }, + }, + summaryOfEstimatedProjectFunding: { + federalContribution: { + '2324': 0, + '2425': 75000, + '2526': 75000, + '2627': 75000, + total: 225000, + }, + applicationContribution: { + '2324': 125000, + '2425': 100000, + '2526': 75000, + '2627': 0, + total: 300000, + }, + provincialContribution: { + '2324': 25000, + '2425': 75000, + '2526': 100000, + '2627': 25000, + total: 225000, + }, + fnhaFunding: { + '2324': 10000, + '2425': 25000, + '2526': 35000, + '2627': 10000, + total: 80000, + }, + infrastructureBankFunding: { + '2324': 0, + '2425': 0, + '2526': 0, + '2627': 0, + total: 0, + }, + otherFundingPartners: [ + { + '2324': 1, + '2425': 2, + '2526': 3, + '2627': 4, + fundingPartnersName: 'Other Funding Source', + total: 10, + }, + ], + totalFinancialContribution: { + '2324': 150001, + '2425': 250002, + '2526': 250003, + '2627': 100004, + total: 750010, + }, + }, + currentFiscalProvincialContributionForecastByQuarter: { + aprilToJune: { + '2324': 0, + '2425': 18750, + '2526': 25000, + '2627': 8333.333333333334, + total: 52083.333333333336, + }, + julyToSeptember: { + '2324': 8333.333333333334, + '2425': 18750, + '2526': 25000, + '2627': 8333.333333333334, + total: 60416.66666666667, + }, + octoberToDecember: { + '2324': 8333.333333333334, + '2425': 18750, + '2526': 25000, + '2627': 8333.333333333334, + total: 60416.66666666667, + }, + januaryToMarch: { + '2324': 8333.333333333334, + '2425': 18750, + '2526': 25000, + '2627': undefined, + total: 52083.333333333336, + }, + fiscalYearTotal: { + '2324': 25000, + '2425': 75000, + '2526': 100000, + '2627': 25000, + total: 225000, + }, + }, + }, + }, + }; + jest.spyOn(XLSX.utils, 'sheet_to_json').mockReturnValue(tab7WithFNHA); + const wb = XLSX.read(null); + + await LoadTab7Data(1, wb, '7', request); + expect(performQuery).toHaveBeenCalledWith( + expect.anything(), + expectedInput, + expect.anything() + ); + }); + afterEach(() => { jest.clearAllMocks(); }); From 95401de6d473c9e8fb6c0dd8be6621bd95664ceb Mon Sep 17 00:00:00 2001 From: CCBC Service Account <116113628+ccbc-service-account@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:15:43 +0000 Subject: [PATCH 2/2] chore: release v1.193.2 --- CHANGELOG.md | 2 ++ db/sqitch.plan | 1 + package.json | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf10c6cdf..2358d1262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [1.193.2](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.193.1...v1.193.2) (2024-09-26) + ## [1.193.1](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.193.0...v1.193.1) (2024-09-18) ### Bug Fixes diff --git a/db/sqitch.plan b/db/sqitch.plan index 9e294d94e..353815322 100644 --- a/db/sqitch.plan +++ b/db/sqitch.plan @@ -679,3 +679,4 @@ tables/cbc_data_003_include_change_reason 2024-09-04T15:14:09Z Anthony Bushara < computed_columns/cbc_history 2024-09-03T15:16:07Z Anthony Bushara # Computed column to get application history on cbc project @1.193.0 2024-09-16T23:48:28Z CCBC Service Account # release v1.193.0 @1.193.1 2024-09-18T15:03:37Z CCBC Service Account # release v1.193.1 +@1.193.2 2024-09-26T16:15:41Z CCBC Service Account # release v1.193.2 diff --git a/package.json b/package.json index 652ffca51..db1042969 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CONN-CCBC-portal", - "version": "1.193.1", + "version": "1.193.2", "main": "index.js", "repository": "https://github.com/bcgov/CONN-CCBC-portal.git", "author": "Romer, Meherzad CITZ:EX ",