From 6f4ddae67f1aaa2e42e5adf9a522573e5119c197 Mon Sep 17 00:00:00 2001 From: Kuan Fan <31664961+kuanfandevops@users.noreply.github.com> Date: Fri, 17 Nov 2023 14:39:00 -0800 Subject: [PATCH] Tracking pull request to merge release-2.13.0 to master (#2723) * update to 2.13.0 * update pr number * feat: enabled visibility of credit transfer agreement date and categorization for BCeID users BCeID users can now view the date of the written agreement and both potential and final categorization in the Transaction History section. * fix: credit trade transactions assigning category when not needed * fix: create migration file * refactor: added migration to update expirations for two signing authority assertions * fix: sql script * fix: trade category if statement * Fix: TFRS - Roles page throwing an error for BCeID users 197 * fix: fixed migration ordering * fix: migration updating missing rescinded history items --------- Co-authored-by: Hamed Valiollahi Bayeki Co-authored-by: Kevin Hashimoto Co-authored-by: Alex Zorkin <47334977+AlexZorkin@users.noreply.github.com> Co-authored-by: Prashanth Co-authored-by: Your Name --- .github/workflows/create-release.yaml | 1 + .github/workflows/dev-release.yaml | 8 +-- .github/workflows/tfrs-release.yaml | 6 +- .pipeline/lib/config.js | 4 +- .../migrations/0011_credit_trade_category.py | 14 +++++ ...signing_authority_assertion_expirations.py | 39 ++++++++++++ ...reate_missing_rescinded_history_records.py | 59 +++++++++++++++++++ backend/api/services/CreditTradeService.py | 9 +-- backend/api/viewsets/CreditTrade.py | 2 +- frontend/package.json | 2 +- .../CreditTransferSigningHistory.js | 2 +- .../OrganizationRolesContainer.js | 4 ++ 12 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 backend/api/migrations/0011_credit_trade_category.py create mode 100644 backend/api/migrations/0012_update_signing_authority_assertion_expirations.py create mode 100644 backend/api/migrations/0013_create_missing_rescinded_history_records.py diff --git a/.github/workflows/create-release.yaml b/.github/workflows/create-release.yaml index b0f2b126d..d6abc1145 100644 --- a/.github/workflows/create-release.yaml +++ b/.github/workflows/create-release.yaml @@ -24,6 +24,7 @@ jobs: with: name: ${{ steps.newereleasename.outputs.value }} tag_name: ${{ steps.newereleasename.outputs.value }} + target_commitish: master body: | ${{ github.event.pull_request.body }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/dev-release.yaml b/.github/workflows/dev-release.yaml index 2f8581401..274bfbcc1 100644 --- a/.github/workflows/dev-release.yaml +++ b/.github/workflows/dev-release.yaml @@ -1,11 +1,11 @@ ## For each release, the value of name, branches, RELEASE_NAME and PR_NUMBER need to be adjusted accordingly ## For each release, update lib/config.js: version and releaseBranch -name: TFRS Dev release-2.12.0 +name: TFRS Dev release-2.13.0 on: push: - branches: [ release-2.12.0 ] + branches: [ release-2.13.0 ] paths: - frontend/** - backend/** @@ -15,8 +15,8 @@ on: env: ## The pull request number of the Tracking pull request to merge the release branch to main ## Also remember to update the version in .pipeline/lib/config.js - PR_NUMBER: 2701 - RELEASE_NAME: release-2.12.0 + PR_NUMBER: 2723 + RELEASE_NAME: release-2.13.0 concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/tfrs-release.yaml b/.github/workflows/tfrs-release.yaml index d5d910994..604214a31 100644 --- a/.github/workflows/tfrs-release.yaml +++ b/.github/workflows/tfrs-release.yaml @@ -1,7 +1,7 @@ ## For each release, the value of name, branches, RELEASE_NAME and PR_NUMBER need to be adjusted accordingly ## For each release, update lib/config.js: version and releaseBranch -name: TFRS release-2.12.0 +name: TFRS release-2.13.0 on: workflow_dispatch: @@ -10,8 +10,8 @@ on: env: ## The pull request number of the Tracking pull request to merge the release branch to main ## Also remember to update the version in .pipeline/lib/config.js - PR_NUMBER: 2701 - RELEASE_NAME: release-2.12.0 + PR_NUMBER: 2723 + RELEASE_NAME: release-2.13.0 concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.pipeline/lib/config.js b/.pipeline/lib/config.js index 21c4b42aa..821505397 100644 --- a/.pipeline/lib/config.js +++ b/.pipeline/lib/config.js @@ -1,7 +1,7 @@ 'use strict'; const options= require('@bcgov/pipeline-cli').Util.parseArguments() const changeId = options.pr //aka pull-request -const version = '2.12.0' +const version = '2.13.0' const name = 'tfrs' const ocpName = 'apps.silver.devops' @@ -13,7 +13,7 @@ options.git.repository='tfrs' const phases = { build: { namespace:'0ab226-tools' , name: `${name}`, phase: 'build' , changeId:changeId, suffix: `-build-${changeId}` , instance: `${name}-build-${changeId}` , version:`${version}-${changeId}`, tag:`build-${version}-${changeId}`, - releaseBranch: 'release-2.12.0' + releaseBranch: 'release-2.13.0' }, dev: {namespace:'0ab226-dev' , name: `${name}`, phase: 'dev' , changeId:changeId, suffix: `-dev` , instance: `${name}-dev` , version:`${version}`, tag:`dev-${version}`, dbServiceName: 'tfrs-spilo', diff --git a/backend/api/migrations/0011_credit_trade_category.py b/backend/api/migrations/0011_credit_trade_category.py new file mode 100644 index 000000000..49ee08af6 --- /dev/null +++ b/backend/api/migrations/0011_credit_trade_category.py @@ -0,0 +1,14 @@ +# Generated by Django 3.2.23 on 2023-11-06 23:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0010_migrate_compliance_report'), + ] + + operations = [ + migrations.RunSQL("UPDATE credit_trade SET trade_category_id = null FROM credit_trade_type WHERE credit_trade.trade_category_id IS NOT NULL AND credit_trade_type.id = credit_trade.trade_category_id AND credit_trade_type.the_type NOT IN ('Buy', 'Sell');") + ] \ No newline at end of file diff --git a/backend/api/migrations/0012_update_signing_authority_assertion_expirations.py b/backend/api/migrations/0012_update_signing_authority_assertion_expirations.py new file mode 100644 index 000000000..e63a1dc93 --- /dev/null +++ b/backend/api/migrations/0012_update_signing_authority_assertion_expirations.py @@ -0,0 +1,39 @@ +import logging +from django.db import migrations, transaction +from django.utils import timezone + +def update_expiration_dates(apps, schema_editor): + """ + Sets new expiration dates for specific SigningAuthorityAssertion records + If any record is not updated, all changes are reverted. + """ + signing_authority_assertion = apps.get_model('api', 'SigningAuthorityAssertion') + new_expiration_date = timezone.datetime.strptime('2023-11-06', "%Y-%m-%d").date() + + # IDs of the SigningAuthorityAssertion records to update + assertion_ids = [2, 3] + + with transaction.atomic(): + for assertion_id in assertion_ids: + try: + assertion = signing_authority_assertion.objects.get(id=assertion_id) + assertion.expiration_date = new_expiration_date + assertion.save() + except signing_authority_assertion.DoesNotExist: + logging.warning( + 'Failed to update SigningAuthorityAssertion: No entry found with id "%s"; ' + 'all changes within this transaction will be reverted.', + assertion_id + ) + +class Migration(migrations.Migration): + """ + Attaches the update function to the migration operations + """ + dependencies = [ + ('api', '0011_credit_trade_category'), + ] + + operations = [ + migrations.RunPython(update_expiration_dates), + ] diff --git a/backend/api/migrations/0013_create_missing_rescinded_history_records.py b/backend/api/migrations/0013_create_missing_rescinded_history_records.py new file mode 100644 index 000000000..37578efd0 --- /dev/null +++ b/backend/api/migrations/0013_create_missing_rescinded_history_records.py @@ -0,0 +1,59 @@ +from django.db import migrations +from django.core.exceptions import ValidationError + +def create_missing_credit_trade_history(apps, schema_editor): + CreditTrade = apps.get_model('api', 'CreditTrade') + CreditTradeHistory = apps.get_model('api', 'CreditTradeHistory') + User = apps.get_model('auth', 'User') + Role = apps.get_model('api', 'Role') + + for credit_trade in CreditTrade.objects.filter(is_rescinded=True): + if not CreditTradeHistory.objects.filter(credit_trade_id=credit_trade.id, is_rescinded=True).exists(): + user = credit_trade.create_user if credit_trade.create_user else User.objects.first() + + user_roles = Role.objects.filter(user_roles__user_id=user.id) + + role_id = None + if user_roles.filter(name="GovDirector").exists(): + role_id = user_roles.get(name="GovDirector").id + elif user_roles.filter(name="GovDeputyDirector").exists(): + role_id = user_roles.get(name="GovDeputyDirector").id + elif user_roles.exists(): + role_id = user_roles.first().id + + history = CreditTradeHistory( + credit_trade_id=credit_trade.id, + respondent_id=credit_trade.respondent.id, + status_id=credit_trade.status.id, + type_id=credit_trade.type.id, + number_of_credits=credit_trade.number_of_credits, + fair_market_value_per_credit=credit_trade.fair_market_value_per_credit, + zero_reason_id=credit_trade.zero_reason.id if credit_trade.zero_reason else None, + trade_effective_date=credit_trade.trade_effective_date, + compliance_period_id=credit_trade.compliance_period.id if credit_trade.compliance_period else None, + is_rescinded=True, + create_user=user, + user_role_id=role_id, + date_of_written_agreement=credit_trade.date_of_written_agreement, + category_d_selected=credit_trade.category_d_selected + ) + + try: + history.full_clean() + history.save() + except ValidationError as error: + # Handle validation error if necessary + raise ValidationError(error) + + # Update the create_timestamp field + history.create_timestamp = credit_trade.update_timestamp + history.save(update_fields=['create_timestamp']) + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0012_update_signing_authority_assertion_expirations'), + ] + + operations = [ + migrations.RunPython(create_missing_credit_trade_history), + ] diff --git a/backend/api/services/CreditTradeService.py b/backend/api/services/CreditTradeService.py index 67b15d062..fd48cad19 100644 --- a/backend/api/services/CreditTradeService.py +++ b/backend/api/services/CreditTradeService.py @@ -172,16 +172,17 @@ def calculate_transfer_category(agreement_date, proposal_date, category_d_select @staticmethod - def approve(credit_trade, update_user=None): + def approve(credit_trade, update_user=None, batch_process=False): """ Transfers the credits between the organizations Sets the Credit Transfer to Approved """ status_approved = CreditTradeStatus.objects.get(status="Approved") - # Calculate and assign trade category - credit_trade.trade_category = CreditTradeService.calculate_transfer_category( - credit_trade.date_of_written_agreement, credit_trade.create_timestamp, credit_trade.category_d_selected) + # Calculate and assign trade category. Dont assign category if transfer are added through historical data entry or if credit trade type is NOT 1 (buy) or 2 (sell) + if not batch_process and credit_trade.type_id in (1, 2): + credit_trade.trade_category = CreditTradeService.calculate_transfer_category( + credit_trade.date_of_written_agreement, credit_trade.create_timestamp, credit_trade.category_d_selected) # Set the effective_date to today if credit_trade's trade_effective_date is null or in the past, # otherwise use trade_effective_date diff --git a/backend/api/viewsets/CreditTrade.py b/backend/api/viewsets/CreditTrade.py index 0e9e31585..5742826de 100644 --- a/backend/api/viewsets/CreditTrade.py +++ b/backend/api/viewsets/CreditTrade.py @@ -229,7 +229,7 @@ def batch_process(self, request): for credit_trade in credit_trades: credit_trade.update_user_id = request.user.id - CreditTradeService.approve(credit_trade) + CreditTradeService.approve(credit_trade,batch_process=True) CreditTradeService.dispatch_notifications( None, credit_trade) diff --git a/frontend/package.json b/frontend/package.json index 025d172f0..f0c4b0fe2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "tfrs", - "version": "2.12.0", + "version": "2.13.0", "dependencies": { "@babel/eslint-parser": "^7.19.1", "@babel/plugin-proposal-object-rest-spread": "^7.20.7", diff --git a/frontend/src/credit_transfers/components/CreditTransferSigningHistory.js b/frontend/src/credit_transfers/components/CreditTransferSigningHistory.js index a3e35f111..31fe47282 100644 --- a/frontend/src/credit_transfers/components/CreditTransferSigningHistory.js +++ b/frontend/src/credit_transfers/components/CreditTransferSigningHistory.js @@ -163,7 +163,7 @@ class CreditTransferSigningHistory extends Component { const lastHistoryItem = history[history.length - 1] const createdByGov = history[0].creditTrade?.initiator?.id === 1 - if (history.length > 0 && loggedInUser.isGovernmentUser && !createdByGov) { + if (history.length > 0 && !createdByGov) { const agreementDate = dateOfWrittenAgreement || history[0].createTimestamp const { category, nextChangeInMonths } = CreditTransferSigningHistory .calculateTransferCategoryAndNextChange(agreementDate, history[0].createTimestamp, categoryDSelected) diff --git a/frontend/src/organizations/OrganizationRolesContainer.js b/frontend/src/organizations/OrganizationRolesContainer.js index 34021c5a6..308459cad 100644 --- a/frontend/src/organizations/OrganizationRolesContainer.js +++ b/frontend/src/organizations/OrganizationRolesContainer.js @@ -19,6 +19,10 @@ const OrganizationRolesContainer = props => { ,