Repository: saleor/saleor
Pull request: Add missing currency in action for transaction requests
I want to merge this change because it resolves #13725

<!-- Please mention all relevant issue numbers. -->

# Impact

- [ ] New migrations
- [ ] New/Updated API fields or mutations
- [ ] Deprecated API fields or mutations
- [ ] Removed API types, fields, or mutations

# Docs

<!-- Docs are stored in a separate repository: https://github.com/saleor/saleor-docs/. -->
<!-- Please provide a link to the PR that updates documentation for your changes. -->
<!-- If changes in docs are not required, please mention that in the description. -->

- [ ] Link to documentation:

# Pull Request Checklist

<!-- Please keep this section. It will make the maintainer's life easier. -->

- [ ] Privileged queries and mutations are either absent or guarded by proper permission checks
- [ ] Database queries are optimized and the number of queries is constant
- [ ] Database migrations are either absent or optimized for zero downtime
- [ ] The changes are covered by test cases


Problem statement:
Missing `currency` in action for transaction requests
## Problem

I want to easily fetch the currency when processing the webhooks like `TransactionChargeRequested`. Currently `action` doesn't have a ` currency` field. It means that I need to additionally fetch `transactions` to get a correct `currency`.

<!-- Describe what you are trying to achive. You can include proposed solution.  -->

---

## 1. General Assumptions
We will extend the `action` type to contain `currency` field. The same as we have for webhooks like  `TransactionInitializeSession` or `TransactionProcessSession`
<!--   -->

### Acceptance Criteria

<!-- Conditions that a feature must satisfy to be approved by QA
- Functional use case:
  - Permissions: As USER/APP with permision `XYZ' I should be able to 'action"
  - Webhooks: Webhook `name` event should be sent for every updated `instance name`
  - Support for old versions: After updating, it is possible to retrieve data created in older (3.1, 3.5, 3.7) Saleor versions.
  - Error handling: Should be handled according to 'policy_name'
  - Other use-cases: ID or externalReference can be used to identify object
- Non-functional use case
  - X objects can be updated in one mutation
-->

- [ ] `TransactionChargeRequested` has `action.currency` field 
- [ ] `TransactionRefundRequested` has `action.currency` field
- [ ] `TransactionCancelationRequested` has `action.currency` field

## 2. API changes

### Subscriptions
 `TransactionChargeRequested`, `TransactionRefundRequested`, `TransactionCancelationRequested` should receive a new field `currency` in `action` structure. 

```graphql
subscription {
  event{
    ... on TransactionChargeRequested{
      action{
        actionType
        amount
        # currency <-- missing
      }
    }
  }
}
```

Hints from issue discussion:

Commit message: Add missing currency in action for transaction requests

Patch to review:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3565acbe5c..dc29ef6d185 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ in 3.17. Use `PaymentSettings.defaultTransactionFlowStrategy` instead.
 
 ### Other changes
 - Fix error in variant available stock calculation - 13593 by @awaisdar001
+- Add missing currency in action for transaction requests - 13786 by @AjmalPonneth
 
 # 3.15.0 [Unreleased]
 
diff --git a/saleor/graphql/schema.graphql b/saleor/graphql/schema.graphql
index ea66941b3c1..448d89cd2ab 100644
--- a/saleor/graphql/schema.graphql
+++ b/saleor/graphql/schema.graphql
@@ -32724,6 +32724,9 @@ type TransactionAction @doc(category: "Payments") {
 
   """Transaction request amount. Null when action type is VOID."""
   amount: PositiveDecimal
+
+  """Currency code."""
+  currency: String
 }
 
 """
diff --git a/saleor/graphql/webhook/subscription_types.py b/saleor/graphql/webhook/subscription_types.py
index c6bae03da0a..3221b14b46b 100644
--- a/saleor/graphql/webhook/subscription_types.py
+++ b/saleor/graphql/webhook/subscription_types.py
@@ -1599,6 +1599,7 @@ class TransactionAction(SubscriptionObjectType, AbstractType):
     amount = PositiveDecimal(
         description="Transaction request amount. Null when action type is VOID.",
     )
+    currency = graphene.String(description="Currency code.")
 
     class Meta:
         doc_category = DOC_CATEGORY_PAYMENTS
@@ -1609,6 +1610,10 @@ def resolve_amount(root: TransactionActionData, _info: ResolveInfo):
             return quantize_price(root.action_value, root.transaction.currency)
         return None
 
+    @staticmethod
+    def resolve_currency(root: TransactionActionData, _info: ResolveInfo):
+        return root.transaction.currency
+
 
 class TransactionActionBase(AbstractType):
     transaction = graphene.Field(
diff --git a/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_cancelation_requested.py b/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_cancelation_requested.py
index b75760de261..f94296af8c8 100644
--- a/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_cancelation_requested.py
+++ b/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_cancelation_requested.py
@@ -25,6 +25,7 @@
       action {
         actionType
         amount
+        currency
       }
     }
   }
@@ -93,5 +94,5 @@ def test_transaction_cancel_request(order, webhook_app, permission_manage_paymen
             "pspReference": "PSP ref",
             "order": {"id": graphene.Node.to_global_id("Order", order.id)},
         },
-        "action": {"actionType": "CANCEL", "amount": None},
+        "action": {"actionType": "CANCEL", "amount": None, "currency": "USD"},
     }
diff --git a/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_charge_requested.py b/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_charge_requested.py
index 07ef57b81a3..13436c2d816 100644
--- a/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_charge_requested.py
+++ b/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_charge_requested.py
@@ -25,6 +25,7 @@
       action {
         actionType
         amount
+        currency
       }
     }
   }
@@ -98,5 +99,6 @@ def test_transaction_charge_request(order, webhook_app, permission_manage_paymen
         "action": {
             "actionType": "CHARGE",
             "amount": quantize_price(action_value, "USD"),
+            "currency": "USD",
         },
     }
diff --git a/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_refund_requested.py b/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_refund_requested.py
index ff1e491ccad..c83841f87bd 100644
--- a/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_refund_requested.py
+++ b/saleor/plugins/webhook/tests/subscription_webhooks/test_create_deliveries_for_transaction_refund_requested.py
@@ -25,6 +25,7 @@
       action {
         actionType
         amount
+        currency
       }
     }
   }
@@ -60,6 +61,7 @@
       action {
         actionType
         amount
+        currency
       }
     }
   }
@@ -133,6 +135,7 @@ def test_transaction_refund_request(order, webhook_app, permission_manage_paymen
         "action": {
             "actionType": "REFUND",
             "amount": quantize_price(action_value, "USD"),
+            "currency": "USD",
         },
     }
 
@@ -231,5 +234,6 @@ def test_transaction_refund_request_with_granted_refund(
         "action": {
             "actionType": "REFUND",
             "amount": 12.3,
+            "currency": "USD",
         },
     }


Code review comments:
diff_hunk: @@ -1599,6 +1599,7 @@ class TransactionAction(SubscriptionObjectType, AbstractType):
     amount = PositiveDecimal(
         description="Transaction request amount. Null when action type is VOID.",
     )
+    currency = graphene.String(description="Currency code.")
path: saleor/graphql/webhook/subscription_types.py
text: @user1:
Can you add `required=True` and label `ADDED_IN_316` to the description?
Something like:
`currency = graphene.String(description="Currency code." + ADDED_IN_316, required=True)`


@author:
Ok. I just forgot about that. Will add and update the PR ASAP.