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 => {
,