diff --git a/src/apps/banking/admin/__init__.py b/src/apps/banking/admin/__init__.py new file mode 100644 index 00000000000..def9b299199 --- /dev/null +++ b/src/apps/banking/admin/__init__.py @@ -0,0 +1,5 @@ +from apps.banking.admin.currency_rate import CurrencyRateAdmin + +__all__ = [ + "CurrencyRateAdmin", +] diff --git a/src/apps/banking/admin/currency_rate.py b/src/apps/banking/admin/currency_rate.py new file mode 100644 index 00000000000..6b874938537 --- /dev/null +++ b/src/apps/banking/admin/currency_rate.py @@ -0,0 +1,31 @@ +from django.contrib.admin.models import CHANGE, LogEntry +from django.http import HttpRequest +from traitlets import Any + +from apps.banking.models import CurrencyRate +from core.admin import ModelAdmin, admin +from core.tasks import write_admin_log + + +@admin.register(CurrencyRate) +class CurrencyRateAdmin(ModelAdmin): + list_display = ["name", "rate"] + + def get_object(self, request: HttpRequest, object_id: str, from_field: str | None = None) -> CurrencyRate | None: + obj = super().get_object(request, object_id, from_field) + if obj: + obj.__original_rate = obj.rate + return obj + + def log_change(self, request: HttpRequest, obj: CurrencyRate, message: Any) -> LogEntry: + if obj.rate != obj.__original_rate: # type: ignore[attr-defined] + return write_admin_log( + action_flag=CHANGE, + app="banking", + change_message=f"Currency rate was changed from {obj.__original_rate} to {obj.rate}", # type: ignore[attr-defined] + model="CurrencyRate", + object_id=obj.id, + user_id=request.user.id, + ) + else: + return super().log_change(request, obj, message) diff --git a/src/apps/banking/migrations/0003_initial.py b/src/apps/banking/migrations/0003_initial.py new file mode 100644 index 00000000000..aad95de6b46 --- /dev/null +++ b/src/apps/banking/migrations/0003_initial.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.17 on 2024-12-24 10:08 + +from django.db import migrations, models + +import core.models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("banking", "0002_drop_recipient_model"), + ] + + operations = [ + migrations.CreateModel( + name="CurrencyRate", + fields=[ + ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(help_text="Currency name in ISO 4217 format. E.g. USD", max_length=4, unique=True)), + ("rate", models.DecimalField(decimal_places=2, max_digits=6, verbose_name="Rate")), + ], + options={ + "verbose_name": "Currency", + "verbose_name_plural": "Currencies", + }, + bases=(core.models.TestUtilsMixin, models.Model), + ), + ] diff --git a/src/apps/banking/models.py b/src/apps/banking/models.py new file mode 100644 index 00000000000..e6bc0165e33 --- /dev/null +++ b/src/apps/banking/models.py @@ -0,0 +1,13 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from core.models import DefaultModel + + +class CurrencyRate(DefaultModel): + name = models.CharField(max_length=4, unique=True, help_text=_("Currency name in ISO 4217 format. E.g. USD")) + rate = models.DecimalField(max_digits=6, decimal_places=2, verbose_name=_("Rate")) + + class Meta: + verbose_name = _("Currency") + verbose_name_plural = _("Currencies") diff --git a/src/apps/orders/migrations/0039_alter_order_ue_rate.py b/src/apps/orders/migrations/0039_alter_order_ue_rate.py new file mode 100644 index 00000000000..6050cd743f1 --- /dev/null +++ b/src/apps/orders/migrations/0039_alter_order_ue_rate.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.17 on 2024-12-24 11:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("orders", "0038_alter_order_bank_id_alter_refund_bank_id"), + ] + + operations = [ + migrations.AlterField( + model_name="order", + name="ue_rate", + field=models.DecimalField(decimal_places=2, max_digits=6, verbose_name="Purchase-time UE rate"), + ), + ] diff --git a/src/apps/orders/models/order.py b/src/apps/orders/models/order.py index cecdd6bacae..ec5011dc2c9 100644 --- a/src/apps/orders/models/order.py +++ b/src/apps/orders/models/order.py @@ -53,7 +53,7 @@ class Order(TimestampedModel): shipped = models.DateTimeField(_("Date when order was shipped"), null=True, blank=True) bank_id = models.CharField(_("User-requested bank string"), choices=BANK_CHOICES, blank=True, max_length=32) - ue_rate = models.IntegerField(_("Purchase-time UE rate")) + ue_rate = models.DecimalField(_("Purchase-time UE rate"), decimal_places=2, max_digits=6) acquiring_percent = models.DecimalField(default=0, max_digits=4, decimal_places=2) course = ItemField(to="products.Course", verbose_name=_("Course"), null=True, blank=True, on_delete=models.PROTECT) diff --git a/src/locale/ru/LC_MESSAGES/django.po b/src/locale/ru/LC_MESSAGES/django.po index 59fdbff7a6d..ab5f2717e04 100644 --- a/src/locale/ru/LC_MESSAGES/django.po +++ b/src/locale/ru/LC_MESSAGES/django.po @@ -967,6 +967,22 @@ msgstr "Да" msgid "No" msgstr "Нет" +#: apps/banking/models.py:7 +msgid "Currency name in ISO 4217 format. E.g. USD" +msgstr "Код валюты по ISO 4217. Например, USD" + +#: apps/banking/models.py:8 +msgid "Rate" +msgstr "Курс" + +#: apps/banking/models.py:11 +msgid "Currency" +msgstr "Курс валюты" + +#: apps/banking/models.py:12 +msgid "Currencies" +msgstr "Курсы валют" + #, python-brace-format #~ msgid "" #~ "Orders {non_refunded_orders_as_message} have not been refunded. Up to 5 "