diff --git a/.github/workflows/release-process.yaml b/.github/workflows/release-process.yaml index 121d3989d..2efa095eb 100644 --- a/.github/workflows/release-process.yaml +++ b/.github/workflows/release-process.yaml @@ -105,6 +105,13 @@ jobs: yarn git checkout "${GITHUB_HEAD_REF}" yarn run release-it --ci --branch="${GITHUB_HEAD_REF}" --git.commitArgs=-n + - name: Enable Auto-Merge + if: steps.checkbox.outputs.result == 'true' && steps.up_to_date.outputs.result == 'true' && steps.pr_approval.outputs.result == 'true' && !github.event.pull_request.draft + run: | + PR_URL="${{ github.event.pull_request.html_url }}" + gh pr merge --auto --merge "$PR_URL" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Uncheck the checkbox if: steps.checkbox.outputs.result == 'true' && steps.up_to_date.outputs.result == 'true' && steps.pr_approval.outputs.result == 'true' && !github.event.pull_request.draft uses: actions/github-script@v7 diff --git a/.github/workflows/test-containers.yaml b/.github/workflows/test-containers.yaml index 58ef161d6..8da660dad 100644 --- a/.github/workflows/test-containers.yaml +++ b/.github/workflows/test-containers.yaml @@ -81,7 +81,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Self-hosted Renovate - uses: renovatebot/github-action@v40.2.9 + uses: renovatebot/github-action@v40.2.10 with: configurationFile: ./.github/renovate.json token: ${{ secrets.RENOVATE_GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index bf10c6cdf..a148315d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [1.193.3](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.193.2...v1.193.3) (2024-09-26) + +### Bug Fixes + +- format for Federal requested for history ([5ec38ba](https://github.com/bcgov/CONN-CCBC-portal/commit/5ec38ba9b7c308b22fbf1a24e6c26561e0c64902)) +- update PR to enable automerge after realease setup ([f16a726](https://github.com/bcgov/CONN-CCBC-portal/commit/f16a726bc967a192e13394ac227afee9f4304ea5)) + +## [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/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/formSchema/uiSchema/history/conditionalApproval.ts b/app/formSchema/uiSchema/history/conditionalApproval.ts index b8b1e70fe..17c9b43f9 100644 --- a/app/formSchema/uiSchema/history/conditionalApproval.ts +++ b/app/formSchema/uiSchema/history/conditionalApproval.ts @@ -24,6 +24,7 @@ const conditionalApprovalSchema = { title: 'ISED announcement', }, federalRequested: { + type: 'number', title: 'Federal requested', }, letterOfApprovalUpload: { 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/package.json b/app/package.json index a877682a4..2f536a4d0 100644 --- a/app/package.json +++ b/app/package.json @@ -40,7 +40,7 @@ "@emotion/styled": "^11.11.5", "@fortawesome/fontawesome-svg-core": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", - "@fortawesome/react-fontawesome": "^0.2.0", + "@fortawesome/react-fontawesome": "^0.2.2", "@graphile-contrib/pg-many-to-many": "^1.0.1", "@graphile/persisted-operations": "^0.1.1", "@growthbook/growthbook-react": "^0.9.0", 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(); }); diff --git a/app/yarn.lock b/app/yarn.lock index 01dcb5a6d..dbc39a0d4 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -2782,10 +2782,10 @@ dependencies: "@fortawesome/fontawesome-common-types" "6.2.0" -"@fortawesome/react-fontawesome@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" - integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw== +"@fortawesome/react-fontawesome@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz#68b058f9132b46c8599875f6a636dad231af78d4" + integrity sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g== dependencies: prop-types "^15.8.1" @@ -8455,9 +8455,9 @@ find-babel-config@^2.1.1: path-exists "^4.0.0" find-my-way@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-8.2.0.tgz#ef1b83d008114a300118c9c707d8dc65947d9960" - integrity sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA== + version "8.2.2" + resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-8.2.2.tgz#f3e78bc6ead2da4fdaa201335da3228600ed0285" + integrity sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA== dependencies: fast-deep-equal "^3.1.3" fast-querystring "^1.0.0" diff --git a/db/sqitch.plan b/db/sqitch.plan index 9e294d94e..cb502fc2a 100644 --- a/db/sqitch.plan +++ b/db/sqitch.plan @@ -679,3 +679,5 @@ 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 +@1.193.3 2024-09-26T18:57:54Z CCBC Service Account # release v1.193.3 diff --git a/lib/ci_cd/merge_process.py b/lib/ci_cd/merge_process.py index 51061b5f4..02150a9ff 100644 --- a/lib/ci_cd/merge_process.py +++ b/lib/ci_cd/merge_process.py @@ -63,53 +63,6 @@ def update_pr_description(pr_url, token): else: print(f"Failed to update PR description: {response.status_code}") -def get_pull_request_id(pr_url, token): - # Extract pull request number from the URL - pr_number = pr_url.split("/")[-1] - - # GraphQL query to get pull request ID - query = """ - query GetPullRequestID { - repository(owner: "%s", name: "%s") { - pullRequest(number: %s) { - id - } - } - } - """ % (repo_owner, repo_name, pr_number) - - # Send GraphQL request - headers = {"Authorization": f"Bearer {token}"} - response = requests.post("https://api.github.com/graphql", json={"query": query}, headers=headers) - - if response.status_code != 200: - print(f"Failed to retrieve pull request ID: {response.status_code}") - return None - - data = response.json() - pull_request_id = data.get("data", {}).get("repository", {}).get("pullRequest", {}).get("id") - return pull_request_id - -def enable_auto_merge(pull_request_id, token): - # GraphQL mutation to enable auto merge - mutation = """ - mutation EnableAutoMerge { - enablePullRequestAutoMerge(input: {pullRequestId: "%s", mergeMethod: MERGE}) { - clientMutationId - } - } - """ % pull_request_id - - # Send GraphQL request - headers = {"Authorization": f"Bearer {token}"} - response = requests.post("https://api.github.com/graphql", json={"query": mutation}, headers=headers) - - if response.status_code != 200: - print(f"Failed to enable auto merge: {response.status_code}") - return - - print("Auto merge enabled successfully!") - def check_header_secret(passed_value): # Get the value of the environment variable named HEADER_SECRET header_secret = os.environ.get('HEADER_SECRET') @@ -144,7 +97,3 @@ def check_header_secret(passed_value): parts = pr_url.split("/") repo_owner = parts[4] repo_name = parts[5] - - pull_request_id = get_pull_request_id(pr_url, token) - if pull_request_id: - enable_auto_merge(pull_request_id, token) diff --git a/package.json b/package.json index 652ffca51..ee06db5fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CONN-CCBC-portal", - "version": "1.193.1", + "version": "1.193.3", "main": "index.js", "repository": "https://github.com/bcgov/CONN-CCBC-portal.git", "author": "Romer, Meherzad CITZ:EX ",