Repository: dj-stripe/dj-stripe

Issue:
PaymentIntent.human_readable_amount returns €1990.00 EUR instead of €19.90 EUR
I am encountering the same issue on dj-stripe 2.6.1 for a PaymentIntent:

>>> t.payment_intent
<PaymentIntent: €1990.00 EUR by Mxxxx Kxxxxx. The funds are in your account.>
>>> t.payment_intent.amount
1990
It should say: €19.90 EUR. Additionally it should either have the €-symbol or "EUR".


Discussion:

Resolving patch:
diff --git a/djstripe/models/connect.py b/djstripe/models/connect.py
--- a/djstripe/models/connect.py
+++ b/djstripe/models/connect.py
@@ -1,6 +1,8 @@
 import stripe
 from django.db import models
 
+from djstripe.utils import get_friendly_currency_amount
+
 from .. import enums
 from ..fields import (
     JSONField,
@@ -249,6 +251,10 @@ def __str__(self):
         # No Reversal
         return f"{self.human_readable_amount}"
 
+    @property
+    def human_readable_amount(self) -> str:
+        return get_friendly_currency_amount(self.amount / 100, self.currency)
+
     def _attach_objects_post_save_hook(
         self,
         cls,
diff --git a/djstripe/models/core.py b/djstripe/models/core.py
--- a/djstripe/models/core.py
+++ b/djstripe/models/core.py
@@ -106,6 +106,10 @@ def get_source_instance(self):
     def get_stripe_dashboard_url(self):
         return self.get_source_instance().get_stripe_dashboard_url()
 
+    @property
+    def human_readable_amount(self) -> str:
+        return get_friendly_currency_amount(self.amount / 100, self.currency)
+
 
 class Charge(StripeModel):
     """
@@ -1499,6 +1503,10 @@ def _attach_objects_post_save_hook(
                 stripe_balance_transaction, api_key=api_key
             )
 
+    @property
+    def human_readable_amount(self) -> str:
+        return get_friendly_currency_amount(self.amount / 100, self.currency)
+
 
 class Event(StripeModel):
     """
@@ -1906,6 +1914,10 @@ def _api_confirm(self, api_key=None, **kwargs):
 
         return self.api_retrieve(api_key=api_key).confirm(**kwargs)
 
+    @property
+    def human_readable_amount(self) -> str:
+        return get_friendly_currency_amount(self.amount / 100, self.currency)
+
 
 class SetupIntent(StripeModel):
     """
@@ -2407,3 +2419,7 @@ def __str__(self):
         return (
             f"{self.human_readable_amount} ({enums.RefundStatus.humanize(self.status)})"
         )
+
+    @property
+    def human_readable_amount(self) -> str:
+        return get_friendly_currency_amount(self.amount / 100, self.currency)


Test patch:
diff --git a/tests/test_balance_transaction.py b/tests/test_balance_transaction.py
--- a/tests/test_balance_transaction.py
+++ b/tests/test_balance_transaction.py
@@ -9,7 +9,6 @@
 
 from djstripe import models
 from djstripe.enums import BalanceTransactionStatus
-from djstripe.utils import get_friendly_currency_amount
 
 from . import (
     FAKE_BALANCE_TRANSACTION,
@@ -37,9 +36,9 @@ def test___str__(self, transaction_status):
             modified_balance_transaction
         )
         assert (
-            f"{get_friendly_currency_amount(modified_balance_transaction['amount'], modified_balance_transaction['currency'])}"
-            f" ({BalanceTransactionStatus.humanize(modified_balance_transaction['status'])})"
-        ) == str(balance_transaction)
+            str(balance_transaction)
+            == f"$20.00 USD ({BalanceTransactionStatus.humanize(modified_balance_transaction['status'])})"
+        )
 
 
 class TestBalanceTransactionSourceClass:
diff --git a/tests/test_dispute.py b/tests/test_dispute.py
--- a/tests/test_dispute.py
+++ b/tests/test_dispute.py
@@ -8,7 +8,6 @@
 from django.contrib.auth import get_user_model
 from django.test.testcases import TestCase
 
-from djstripe import enums
 from djstripe.models import Dispute
 from djstripe.settings import djstripe_settings
 
@@ -72,10 +71,7 @@ def test___str__(
     ):
 
         dispute = Dispute.sync_from_stripe_data(FAKE_DISPUTE_I)
-        self.assertEqual(
-            str(dispute),
-            f"{dispute.human_readable_amount} ({enums.DisputeStatus.humanize(FAKE_DISPUTE_I['status'])}) ",
-        )
+        self.assertEqual(str(dispute), "$1000.00 USD (Needs response) ")
 
     @patch(
         "stripe.PaymentMethod.retrieve",
diff --git a/tests/test_payment_intent.py b/tests/test_payment_intent.py
--- a/tests/test_payment_intent.py
+++ b/tests/test_payment_intent.py
@@ -10,6 +10,7 @@
 
 from djstripe.enums import PaymentIntentStatus
 from djstripe.models import Account, Customer, PaymentIntent
+from djstripe.utils import get_friendly_currency_amount
 
 from . import (
     FAKE_ACCOUNT,
@@ -112,32 +113,27 @@ def mock_charge_get(*args, **kwargs):
         if fake_intent_data.get("invoice"):
             assert pi.invoice is not None
 
-        account = Account.objects.filter(id=fake_intent_data["on_behalf_of"]).first()
-        customer = Customer.objects.filter(id=fake_intent_data["customer"]).first()
-
         if has_account and has_customer:
 
             assert (
-                f"{pi.human_readable_amount} ({PaymentIntentStatus.humanize(fake_intent_data['status'])}) "
-                f"for {account} "
-                f"by {customer}"
-            ) == str(pi)
+                str(pi)
+                == "$1902.00 USD (The funds are in your account.) for dj-stripe by Michael Smith"
+            )
 
         elif has_account and not has_customer:
 
             assert (
-                f"{pi.human_readable_amount} for {account}. {PaymentIntentStatus.humanize(fake_intent_data['status'])}"
-            ) == str(pi)
+                str(pi)
+            ) == "$1902.00 USD for dj-stripe. The funds are in your account."
 
         elif has_customer and not has_account:
 
             assert (
-                f"{pi.human_readable_amount} by {customer}. {PaymentIntentStatus.humanize(fake_intent_data['status'])}"
-            ) == str(pi)
+                str(pi)
+            ) == "$20.00 USD by Michael Smith. The funds are in your account."
         elif not has_customer and not has_account:
-            f"{pi.human_readable_amount} ({PaymentIntentStatus.humanize(fake_intent_data['status'])})" == str(
-                pi
-            )
+
+            assert str(pi) == "$20.00 USD (The funds are in your account.)"
 
 
 class PaymentIntentTest(AssertStripeFksMixin, TestCase):
diff --git a/tests/test_refund.py b/tests/test_refund.py
--- a/tests/test_refund.py
+++ b/tests/test_refund.py
@@ -164,10 +164,7 @@ def test___str__(
 
         refund = Refund.sync_from_stripe_data(fake_refund)
 
-        self.assertEqual(
-            f"{refund.human_readable_amount} ({enums.RefundStatus.humanize(fake_refund['status'])})",
-            str(refund),
-        )
+        self.assertEqual(str(refund), "$20.00 USD (Succeeded)")
 
         self.assert_fks(refund, expected_blank_fks=self.default_expected_blank_fks)
 
diff --git a/tests/test_transfer.py b/tests/test_transfer.py
--- a/tests/test_transfer.py
+++ b/tests/test_transfer.py
@@ -66,15 +66,13 @@ def test___str__(
         transfer = Transfer.sync_from_stripe_data(fake_transfer_data)
 
         if fake_transfer_data["reversed"]:
-            assert f"{transfer.human_readable_amount} Reversed" == str(transfer)
+            assert "$0.01 USD Reversed" == str(transfer)
 
         elif fake_transfer_data["amount_reversed"]:
-            assert f"{transfer.human_readable_amount} Partially Reversed" == str(
-                transfer
-            )
+            assert "$0.01 USD Partially Reversed" == str(transfer)
 
         else:
-            assert f"{transfer.human_readable_amount}" == str(transfer)
+            assert "$0.01 USD" == str(transfer)
 
 
 class TestTransfer(AssertStripeFksMixin, TestCase):