From 3543d4ad01b3a69a7c522bd330988a7134c69138 Mon Sep 17 00:00:00 2001 From: Kuan Fan <31664961+kuanfandevops@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:59:12 -0700 Subject: [PATCH] Emergency Release 1.59.1 (#2258) * add emergency release-1.59.1 * add pull_request events * Update package.json * Transfer fix (#2244) * fix: removes unecessary data from transfer * fix: new user serializer passes only basic user info to frontend -get history modified so that approved and disapproved statuses created by government are excluded so that communications/status changes within government are not shown in network tab * removes id from user basic serializer * more fixes * small change + tests * Update version to be 1.59.1 in package.json --------- Co-authored-by: emi-hi Co-authored-by: Kuan Fan <31664961+kuanfandevops@users.noreply.github.com> * Update emergency-release-build-1.59.1.yaml --------- Co-authored-by: tim738745 <98717409+tim738745@users.noreply.github.com> Co-authored-by: emi-hi --- .../emergency-release-build-1.59.1.yaml | 185 ++++++++++++++++++ backend/api/serializers/credit_transfer.py | 31 ++- backend/api/serializers/organization.py | 10 + backend/api/serializers/user.py | 13 +- backend/api/tests/test_credit_transfers.py | 51 ++++- backend/api/viewsets/credit_transfer.py | 12 +- frontend/package.json | 2 +- frontend/src/app/routes/CreditTransfers.js | 1 + .../src/app/utilities/getSupplierSummary.js | 22 +-- .../CreditTransfersDetailsContainer.js | 10 + .../components/CreditTransfersDetailsPage.js | 9 +- .../CreditTransfersDetailsSupplierTable.js | 7 +- 12 files changed, 320 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/emergency-release-build-1.59.1.yaml diff --git a/.github/workflows/emergency-release-build-1.59.1.yaml b/.github/workflows/emergency-release-build-1.59.1.yaml new file mode 100644 index 000000000..b82c92a56 --- /dev/null +++ b/.github/workflows/emergency-release-build-1.59.1.yaml @@ -0,0 +1,185 @@ +## For each release, please update the value of workflow name, branches and PR_NUMBER +## Also update frontend/package.json version + +name: Emergency Release Build 1.59.1 + +on: + workflow_dispatch: + +env: + ## The pull request number of the Tracking pull request to merge the release branch to main + PR_NUMBER: 2244 + VERSION: 1.59.1 + GIT_URL: https://github.com/bcgov/zeva.git + TOOLS_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-tools + DEV_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-dev + TEST_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-test + PROD_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-prod + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # call-unit-test: + # uses: ./.github/workflows/unit-test-template.yaml + # with: + # pr-number: 2244 + + build: + name: Build ZEVA on Openshift + runs-on: ubuntu-latest + timeout-minutes: 60 + # needs: call-unit-test + + steps: + - name: Check out repository + uses: actions/checkout@v4.1.1 + with: + ref: refs/pull/${{ env.PR_NUMBER }}/head + + - name: Log in to Openshift + uses: redhat-actions/oc-login@v1.3 + with: + openshift_server_url: ${{ secrets.OPENSHIFT_SERVER }} + openshift_token: ${{ secrets.OPENSHIFT_TOKEN }} + insecure_skip_tls_verify: true + namespace: ${{ env.TOOLS_NAMESPACE }} + + - name: Build ZEVA Backend + run: | + cd openshift/templates/backend + oc process -f ./backend-bc.yaml NAME=zeva SUFFIX=-build-${{ env.PR_NUMBER }} VERSION=build-${{ env.VERSION }}-${{ env.PR_NUMBER }} GIT_URL=${{ env.GIT_URL }} GIT_REF=refs/pull/${{ env.PR_NUMBER }}/head | oc apply --wait=true -f - -n ${{ env.TOOLS_NAMESPACE }} + oc start-build --wait=true zeva-backend-build-${{ env.PR_NUMBER }} + + - name: Build ZEVA Frontend + run: | + cd openshift/templates/frontend + oc process -f ./frontend-bc-docker.yaml NAME=zeva SUFFIX=-build-${{ env.PR_NUMBER }} VERSION=build-${{ env.VERSION }}-${{ env.PR_NUMBER }} GIT_URL=${{ env.GIT_URL }} GIT_REF=refs/pull/${{ env.PR_NUMBER }}/head | oc apply --wait=true -f - -n ${{ env.TOOLS_NAMESPACE }} + oc start-build --wait=true zeva-frontend-build-${{ env.PR_NUMBER }} + + deploy-on-test: + name: Deploy ZEVA on Test + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: build + + steps: + - name: Check out repository + uses: actions/checkout@v4.1.1 + with: + ref: refs/pull/${{ env.PR_NUMBER }}/head + + - name: Log in to Openshift + uses: redhat-actions/oc-login@v1.3 + with: + openshift_server_url: ${{ secrets.OPENSHIFT_SERVER }} + openshift_token: ${{ secrets.OPENSHIFT_TOKEN }} + insecure_skip_tls_verify: true + namespace: ${{ env.TOOLS_NAMESPACE }} + + - name: Ask for approval for ZEVA Test deployment + uses: trstringer/manual-approval@v1.6.0 + with: + secret: ${{ github.TOKEN }} + approvers: AlexZorkin,emi-hi,tim738745,kuanfandevops,prv-proton + minimum-approvals: 1 + issue-title: "ZEVA ${{ env.VERSION }} Test Deployment" + + - name: Tag Backend Image from tools to Test + run: | + oc tag ${{ env.TOOLS_NAMESPACE }}/zeva-backend:build-${{ env.VERSION }}-${{ env.PR_NUMBER }} ${{ env.TEST_NAMESPACE }}/zeva-backend:test-${{ env.VERSION }} + + - name: Tag Frontend Image from tools to Test + run: | + oc tag ${{ env.TOOLS_NAMESPACE }}/zeva-frontend:build-${{ env.VERSION }}-${{ env.PR_NUMBER }} ${{ env.TEST_NAMESPACE }}/zeva-frontend:test-${{ env.VERSION }} + + # helm status will show an error if the helm release doesn't exist. The error will be ignored. + - name: Deploy zeva-frontend on Test + shell: bash {0} + run: | + cd charts/zeva-apps/charts/zeva-frontend + helm status -n ${{ env.TEST_NAMESPACE }} zeva-frontend-test + if [ $? -eq 0 ]; then + echo "zeva-frontend-test release exists already" + helm upgrade --install --set frontendImageTagname=test-${{ env.VERSION }},openshiftLicensePlate=${{ secrets.OPENSHIFT_NAMESPACE_PLATE }} -n ${{ env.TEST_NAMESPACE }} -f ./values-test.yaml zeva-frontend-test . + else + echo "zeva-frontend-test release does not exist" + helm install --set frontendImageTagname=test-${{ env.VERSION }},openshiftLicensePlate=${{ secrets.OPENSHIFT_NAMESPACE_PLATE }} -n ${{ env.TEST_NAMESPACE }} -f ./values-test.yaml zeva-frontend-test . + fi + + # helm status will show an error if the helm release doesn't exist. The error will be ignored. + - name: Deply zeva-backend on Test + shell: bash {0} + run: | + cd charts/zeva-apps/charts/zeva-backend + helm status -n ${{ env.TEST_NAMESPACE }} zeva-backend-test + if [ $? -eq 0 ]; then + echo "zeva-backend-test release exists already" + helm upgrade --set backendImageTagname=test-${{ env.VERSION }} -n ${{ env.TEST_NAMESPACE }} -f ./values-test.yaml zeva-backend-test . + else + echo "zeva-backend-test release does not exist" + helm install --set backendImageTagname=test-${{ env.VERSION }} -n ${{ env.TEST_NAMESPACE }} -f ./values-test.yaml zeva-backend-test . + fi + + deploy-on-prod: + name: Deploy ZEVA on Prod + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: deploy-on-test + + steps: + - name: Check out repository + uses: actions/checkout@v4.1.1 + with: + ref: refs/pull/${{ env.PR_NUMBER }}/head + + - name: Log in to Openshift + uses: redhat-actions/oc-login@v1.3 + with: + openshift_server_url: ${{ secrets.OPENSHIFT_SERVER }} + openshift_token: ${{ secrets.OPENSHIFT_TOKEN }} + insecure_skip_tls_verify: true + namespace: ${{ env.TOOLS_NAMESPACE }} + + - name: Ask for approval for ZEVA Prod deployment + uses: trstringer/manual-approval@v1.6.0 + with: + secret: ${{ github.TOKEN }} + approvers: AlexZorkin,kuanfandevops,tim738745,emi-hi + minimum-approvals: 1 + issue-title: "ZEVA ${{ env.VERSION }} Prod Deployment" + + - name: Tag Frontend Image from tools to Prod + run: | + oc tag ${{ env.TOOLS_NAMESPACE }}/zeva-frontend:build-${{ env.VERSION }}-${{ env.PR_NUMBER }} ${{ env.PROD_NAMESPACE }}/zeva-frontend:prod-${{ env.VERSION }} + + - name: Tag Backend Image from tools to Prod + run: | + oc tag ${{ env.TOOLS_NAMESPACE }}/zeva-backend:build-${{ env.VERSION }}-${{ env.PR_NUMBER }} ${{ env.PROD_NAMESPACE }}/zeva-backend:prod-${{ env.VERSION }} + + - name: Deply zeva-frontend on Prod + shell: bash {0} + run: | + cd charts/zeva-apps/charts/zeva-frontend + helm status -n ${{ env.PROD_NAMESPACE }} zeva-frontend-prod + if [ $? -eq 0 ]; then + echo "zeva-frontend-prod release exists already" + helm upgrade --set frontendImageTagname=prod-${{ env.VERSION }},openshiftLicensePlate=${{ secrets.OPENSHIFT_NAMESPACE_PLATE }} -n ${{ env.PROD_NAMESPACE }} -f ./values-prod.yaml zeva-frontend-prod . + else + echo "zeva-frontend-prod release does not exist" + helm install --set frontendImageTagname=prod-${{ env.VERSION }},openshiftLicensePlate=${{ secrets.OPENSHIFT_NAMESPACE_PLATE }} -n ${{ env.PROD_NAMESPACE }} -f ./values-prod.yaml zeva-frontend-prod . + fi + + - name: Deply zeva-backend on Prod + shell: bash {0} + run: | + cd charts/zeva-apps/charts/zeva-backend + helm status -n ${{ env.PROD_NAMESPACE }} zeva-backend-prod + if [ $? -eq 0 ]; then + echo "zeva-backend-prod release exists already" + helm upgrade --set backendImageTagname=prod-${{ env.VERSION }} -n ${{ env.PROD_NAMESPACE }} -f ./values-prod.yaml zeva-backend-prod . + else + echo "zeva-backend-prod release does not exist" + helm install --set backendImageTagname=prod-${{ env.VERSION }} -n ${{ env.PROD_NAMESPACE }} -f ./values-prod.yaml zeva-backend-prod . + fi diff --git a/backend/api/serializers/credit_transfer.py b/backend/api/serializers/credit_transfer.py index bf1e742e1..f39250941 100644 --- a/backend/api/serializers/credit_transfer.py +++ b/backend/api/serializers/credit_transfer.py @@ -18,8 +18,8 @@ CreditTransferCommentSerializer from api.serializers.credit_transfer_content import \ CreditTransferContentSerializer, CreditTransferContentSaveSerializer -from api.serializers.user import MemberSerializer, UserSerializer -from api.serializers.organization import OrganizationSerializer +from api.serializers.user import UserBasicSerializer +from api.serializers.organization import OrganizationNameSerializer, OrganizationSerializer from api.services.credit_transaction import calculate_insufficient_credits from api.services.send_email import notifications_credit_transfers @@ -29,7 +29,7 @@ def get_update_user(self, obj): user_profile = UserProfile.objects.filter(username=obj.update_user) if user_profile.exists(): - serializer = MemberSerializer(user_profile.first(), read_only=True) + serializer = UserBasicSerializer(user_profile.first(), read_only=True) return serializer.data return obj.update_user @@ -37,7 +37,7 @@ def get_update_user(self, obj): def get_create_user(self, obj): user_profile = UserProfile.objects.filter(username=obj.create_user) if user_profile.exists(): - serializer = UserSerializer(user_profile.first(), read_only=True) + serializer = UserBasicSerializer(user_profile.first(), read_only=True) return serializer.data return obj.create_user @@ -47,6 +47,8 @@ def get_history(self, obj): history = CreditTransferHistory.objects.filter( transfer_id=obj.id) else: + create_user_subquery = UserProfile.objects.filter(organization__is_government=True).values_list('username', flat=True) + history = CreditTransferHistory.objects.filter( transfer_id=obj.id, status__in=[ @@ -58,8 +60,8 @@ def get_history(self, obj): CreditTransferStatuses.RESCIND_PRE_APPROVAL, CreditTransferStatuses.REJECTED, CreditTransferStatuses.VALIDATED - ]) - serializer = CreditTransferHistorySerializer(history, many=True, read_only=True) + ]).exclude(create_user__in=create_user_subquery, status__in=[CreditTransferStatuses.APPROVED, CreditTransferStatuses.DISAPPROVED,]) + serializer = CreditTransferHistorySerializer(history, many=True, read_only=True, context={'request': request}) return serializer.data @@ -97,11 +99,11 @@ class CreditTransferListSerializer( CreditTransferBaseSerializer ): history = SerializerMethodField() - credit_to = OrganizationSerializer() + credit_to = OrganizationNameSerializer() credit_transfer_content = CreditTransferContentSerializer( many=True, read_only=True ) - debit_from = OrganizationSerializer() + debit_from = OrganizationNameSerializer() status = SerializerMethodField() update_user = SerializerMethodField() @@ -128,11 +130,11 @@ class CreditTransferSerializer( CreditTransferBaseSerializer ): history = SerializerMethodField() - credit_to = OrganizationSerializer() + credit_to = OrganizationNameSerializer() credit_transfer_content = CreditTransferContentSerializer( many=True, read_only=True ) - debit_from = OrganizationSerializer() + debit_from = OrganizationNameSerializer() status = SerializerMethodField() update_user = SerializerMethodField() sufficient_credits = SerializerMethodField() @@ -198,6 +200,15 @@ class Meta: ) +class CreditTransferOrganizationBalancesSerializer(ModelSerializer): + credit_to = OrganizationSerializer() + debit_from = OrganizationSerializer() + + class Meta: + model = CreditTransfer + fields = ('credit_to', 'debit_from') + + class CreditTransferSaveSerializer(ModelSerializer): """ Serializer to create a transfer diff --git a/backend/api/serializers/organization.py b/backend/api/serializers/organization.py index 9ffb49a88..eb17e53de 100644 --- a/backend/api/serializers/organization.py +++ b/backend/api/serializers/organization.py @@ -9,6 +9,16 @@ OrganizationLDVSalesSerializer from api.models.model_year import ModelYear +class OrganizationNameSerializer(serializers.ModelSerializer): + """ + Serializer for passing just the necessary info for credit transfers etc + """ + class Meta: + model = Organization + fields = ( + 'id', 'name', 'short_name', 'is_government' + ) + class OrganizationSerializer(serializers.ModelSerializer): """ diff --git a/backend/api/serializers/user.py b/backend/api/serializers/user.py index ce23c64c2..a5c6ec3b3 100644 --- a/backend/api/serializers/user.py +++ b/backend/api/serializers/user.py @@ -5,7 +5,7 @@ from api.models.role import Role from api.models.user_profile import UserProfile from api.services.user import update_roles, create_default_user_notification_settings -from .organization import OrganizationSerializer +from .organization import OrganizationSerializer, OrganizationNameSerializer from .permission import PermissionSerializer from .role import RoleSerializer @@ -30,6 +30,17 @@ class Meta: ) +class UserBasicSerializer(serializers.ModelSerializer): + """ + Serializer for the basic details of a user + """ + organization = OrganizationNameSerializer(read_only=True) + class Meta: + model = UserProfile + fields = ( + 'display_name', 'organization' + ) + class UserSerializer(serializers.ModelSerializer): """ Serializer for the full details of the User diff --git a/backend/api/tests/test_credit_transfers.py b/backend/api/tests/test_credit_transfers.py index 26f463507..f25acb89b 100644 --- a/backend/api/tests/test_credit_transfers.py +++ b/backend/api/tests/test_credit_transfers.py @@ -14,6 +14,7 @@ from ..models.organization import Organization from ..models.signing_authority_confirmation import SigningAuthorityConfirmation from ..models.signing_authority_assertion import SigningAuthorityAssertion +from ..models.credit_transfer_statuses import CreditTransferStatuses from unittest.mock import patch @@ -26,19 +27,19 @@ def setUp(self): gov_user = self.users['RTAN'].organization - transfer = CreditTransfer.objects.create( + self.transfer = CreditTransfer.objects.create( status='SUBMITTED', credit_to=org1, debit_from=org2, ) - transfer2 = CreditTransfer.objects.create( + self.transfer2 = CreditTransfer.objects.create( status='DRAFT', credit_to=org1, debit_from=org2, ) - transfer3 = CreditTransfer.objects.create( + self.transfer3 = CreditTransfer.objects.create( status='APPROVED', credit_to=org1, debit_from=org2, @@ -180,3 +181,47 @@ def test_credit_transfer_create(self): # Test that email method is called properly mock_send_credit_transfer_emails.assert_called() + + + def test_get_transfer(self): + transfer = self.transfer + transfer_initial_status = transfer.status + transfer_id = transfer.id + users = ["EMHILLIE_BCEID", "RTAN"] + for status in CreditTransferStatuses: + transfer.status = status + transfer.save() + for user in users: + response = self.clients[user].get("/api/credit-transfers/" + str(transfer_id)) + data = response.data + credit_to = data.get("credit_to") + debit_from = data.get("debit_from") + if credit_to is not None: + self.assertEqual(len(credit_to), 4) + self.assertFalse("balance" in credit_to or "ldv_sales" in credit_to or "avg_ldv_sales" in credit_to) + if debit_from is not None: + self.assertEqual(len(debit_from), 4) + self.assertFalse("balance" in debit_from or "ldv_sales" in debit_from or "avg_ldv_sales" in debit_from) + transfer.status = transfer_initial_status + transfer.save() + + + def test_get_org_balances(self): + gov_user = "RTAN" + non_gov_user = "EMHILLIE_BCEID" + transfer = self.transfer + transfer_initial_status = transfer.status + transfer_id = transfer.id + for user in (gov_user, non_gov_user): + for status in CreditTransferStatuses: + transfer.status = status + transfer.save() + response = self.clients[user].get("/api/credit-transfers/" + str(transfer_id) + "/org_balances") + response_status = response.status_code + data = response.data + if user == gov_user and status == CreditTransferStatuses.APPROVED: + self.assertEqual(response_status, 200) + else: + self.assertTrue(response_status == 403 or not data) + transfer.status = transfer_initial_status + transfer.save() diff --git a/backend/api/viewsets/credit_transfer.py b/backend/api/viewsets/credit_transfer.py index 474fe3b1e..878419e73 100644 --- a/backend/api/viewsets/credit_transfer.py +++ b/backend/api/viewsets/credit_transfer.py @@ -8,7 +8,7 @@ from api.models.credit_transfer_statuses import CreditTransferStatuses from api.permissions.credit_transfer import CreditTransferPermissions from api.serializers.credit_transfer import CreditTransferSerializer, \ - CreditTransferSaveSerializer, CreditTransferListSerializer + CreditTransferSaveSerializer, CreditTransferListSerializer, CreditTransferOrganizationBalancesSerializer from api.serializers.credit_transfer_comment import CreditTransferCommentSerializer from auditable.views import AuditableMixin from api.services.send_email import notifications_credit_transfers @@ -125,3 +125,13 @@ def delete_comment(self, request, pk): delete_comment(comment_id) return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_403_FORBIDDEN) + + @action(detail=True, methods=["GET"]) + def org_balances(self, request, pk): + transfer = self.get_queryset().filter(pk=pk).first() + if transfer is None: + return Response({}) + if request.user.is_government and transfer.status == CreditTransferStatuses.APPROVED: + serializer = CreditTransferOrganizationBalancesSerializer(transfer) + return Response(serializer.data) + return Response(status=status.HTTP_403_FORBIDDEN) diff --git a/frontend/package.json b/frontend/package.json index 9c975f353..43e5ea96d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "zeva-frontend", - "version": "1.59.0", + "version": "1.59.1", "private": true, "dependencies": { "@babel/eslint-parser": "^7.19.1", diff --git a/frontend/src/app/routes/CreditTransfers.js b/frontend/src/app/routes/CreditTransfers.js index 22f3ab11f..874b0811e 100644 --- a/frontend/src/app/routes/CreditTransfers.js +++ b/frontend/src/app/routes/CreditTransfers.js @@ -7,6 +7,7 @@ const CREDIT_REQUESTS = { EDIT: `${API_BASE_PATH}/:id/edit`, UPDATE_COMMENT: `${API_BASE_PATH}/:id/update_comment`, DELETE_COMMENT: `${API_BASE_PATH}/:id/delete_comment`, + ORG_BALANCES: `${API_BASE_PATH}/:id/org_balances`, } export default CREDIT_REQUESTS diff --git a/frontend/src/app/utilities/getSupplierSummary.js b/frontend/src/app/utilities/getSupplierSummary.js index 9b0b075c2..125026907 100644 --- a/frontend/src/app/utilities/getSupplierSummary.js +++ b/frontend/src/app/utilities/getSupplierSummary.js @@ -1,17 +1,17 @@ -const getSupplierSummary = (submission) => { +const getSupplierSummary = (submission, orgBalances) => { const initiatingSupplier = { - currentBalanceA: parseFloat(submission.debitFrom.balance.A), - currentBalanceB: parseFloat(submission.debitFrom.balance.B), - newBalanceA: parseFloat(submission.debitFrom.balance.A), - newBalanceB: parseFloat(submission.debitFrom.balance.B), - supplierLabel: submission.debitFrom.name + currentBalanceA: parseFloat(orgBalances.debitFrom.balance.A), + currentBalanceB: parseFloat(orgBalances.debitFrom.balance.B), + newBalanceA: parseFloat(orgBalances.debitFrom.balance.A), + newBalanceB: parseFloat(orgBalances.debitFrom.balance.B), + supplierLabel: orgBalances.debitFrom.name } const receivingSupplier = { - currentBalanceA: parseFloat(submission.creditTo.balance.A), - currentBalanceB: parseFloat(submission.creditTo.balance.B), - newBalanceA: parseFloat(submission.creditTo.balance.A), - newBalanceB: parseFloat(submission.creditTo.balance.B), - supplierLabel: submission.creditTo.name + currentBalanceA: parseFloat(orgBalances.creditTo.balance.A), + currentBalanceB: parseFloat(orgBalances.creditTo.balance.B), + newBalanceA: parseFloat(orgBalances.creditTo.balance.A), + newBalanceB: parseFloat(orgBalances.creditTo.balance.B), + supplierLabel: orgBalances.creditTo.name } submission.creditTransferContent.forEach((item) => { if (item.creditClass.creditClass === 'A') { diff --git a/frontend/src/credits/CreditTransfersDetailsContainer.js b/frontend/src/credits/CreditTransfersDetailsContainer.js index e25c1423c..f19320539 100644 --- a/frontend/src/credits/CreditTransfersDetailsContainer.js +++ b/frontend/src/credits/CreditTransfersDetailsContainer.js @@ -23,6 +23,7 @@ const CreditTransfersDetailsContainer = (props) => { const [sufficientCredit, setSufficientCredit] = useState(true) const { id } = match.params const [submission, setSubmission] = useState({}) + const [orgBalances, setOrgBalances] = useState({}) const [loading, setLoading] = useState(true) const refreshDetails = () => { @@ -49,6 +50,14 @@ const CreditTransfersDetailsContainer = (props) => { refreshDetails() }, [id]) + useEffect(() => { + if (user.isGovernment && submission.status === 'APPROVED') { + axios.get(ROUTES_CREDIT_TRANSFERS.ORG_BALANCES.replace(':id', id)).then((response) => { + setOrgBalances(response.data) + }) + } + }, [id, user, submission]) + const handleCheckboxClick = (event) => { if (!event.target.checked) { const checked = checkboxes.filter( @@ -170,6 +179,7 @@ const CreditTransfersDetailsContainer = (props) => { submission={submission} user={user} errorMessage={errorMessage} + orgBalances={orgBalances} /> ] } diff --git a/frontend/src/credits/components/CreditTransfersDetailsPage.js b/frontend/src/credits/components/CreditTransfersDetailsPage.js index 39b853e5a..5a749d11e 100644 --- a/frontend/src/credits/components/CreditTransfersDetailsPage.js +++ b/frontend/src/credits/components/CreditTransfersDetailsPage.js @@ -32,7 +32,8 @@ const CreditTransfersDetailsPage = (props) => { sufficientCredit, submission, user, - errorMessage + errorMessage, + orgBalances } = props const { id } = useParams() const [comment, setComment] = useState('') @@ -501,9 +502,10 @@ const CreditTransfersDetailsPage = (props) => { )} - {transferRole.governmentAnalyst && ( + {transferRole.governmentAnalyst && Object.keys(orgBalances).length !== 0 && ( )} @@ -556,7 +558,8 @@ CreditTransfersDetailsPage.propTypes = { sufficientCredit: PropTypes.bool.isRequired, user: CustomPropTypes.user.isRequired, submission: PropTypes.shape().isRequired, - errorMessage: PropTypes.arrayOf(PropTypes.string) + errorMessage: PropTypes.arrayOf(PropTypes.string), + orgBalances: PropTypes.shape().isRequired } export default CreditTransfersDetailsPage diff --git a/frontend/src/credits/components/CreditTransfersDetailsSupplierTable.js b/frontend/src/credits/components/CreditTransfersDetailsSupplierTable.js index e7fbfe168..ecb8d05ec 100644 --- a/frontend/src/credits/components/CreditTransfersDetailsSupplierTable.js +++ b/frontend/src/credits/components/CreditTransfersDetailsSupplierTable.js @@ -6,7 +6,7 @@ import formatNumeric from '../../app/utilities/formatNumeric' import getSupplierSummary from '../../app/utilities/getSupplierSummary' const CreditTransfersDetailsSupplierTable = (props) => { - const { submission } = props + const { submission, orgBalances } = props const tableText = (
@@ -15,7 +15,7 @@ const CreditTransfersDetailsSupplierTable = (props) => {
) - const supplierBalanceData = getSupplierSummary(submission) + const supplierBalanceData = getSupplierSummary(submission, orgBalances) const supplierBalanceColumns = [ { Header: 'Supplier', @@ -99,6 +99,7 @@ const CreditTransfersDetailsSupplierTable = (props) => { ) } CreditTransfersDetailsSupplierTable.propTypes = { - submission: PropTypes.shape().isRequired + submission: PropTypes.shape().isRequired, + orgBalances: PropTypes.shape().isRequired } export default CreditTransfersDetailsSupplierTable