From c8e77273edb0180fae397a980a1c5db2ea181871 Mon Sep 17 00:00:00 2001 From: Domenico DiNicola Date: Wed, 19 Feb 2025 16:54:07 +0100 Subject: [PATCH] office --- src/hope_payment_gateway/api/fsp/views.py | 12 ++- .../apps/gateway/admin.py | 14 ++- .../0031_office_paymentinstruction_office.py | 93 +++++++++++++++++++ .../apps/gateway/models.py | 16 ++++ 4 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 src/hope_payment_gateway/apps/gateway/migrations/0031_office_paymentinstruction_office.py diff --git a/src/hope_payment_gateway/api/fsp/views.py b/src/hope_payment_gateway/api/fsp/views.py index 9eafa70..846a96a 100644 --- a/src/hope_payment_gateway/api/fsp/views.py +++ b/src/hope_payment_gateway/api/fsp/views.py @@ -34,6 +34,7 @@ PaymentInstruction, PaymentInstructionState, PaymentRecord, + Office, ) @@ -75,9 +76,16 @@ class PaymentInstructionViewSet(ProtectedMixin, LoggingAPIViewSet): search_fields = ["external_code", "remote_id"] def perform_create(self, serializer) -> None: - owner = get_user_model().objects.get(apitoken=self.request.auth) + owner = get_user_model().objects.filter(apitoken=self.request.auth).first() system = System.objects.get(owner=owner) - serializer.save(system=system) + obj = serializer.save(system=system) + config_key = obj.extra.get("config_key", None) + if config_key: + office, _ = Office.objects.get_or_create( + code=config_key, defaults={"name": config_key, "slug": config_key, "supervised": True} + ) + obj.office = office + obj.save() def _change_status(self, status): instruction = self.get_object() diff --git a/src/hope_payment_gateway/apps/gateway/admin.py b/src/hope_payment_gateway/apps/gateway/admin.py index ee87046..2362890 100644 --- a/src/hope_payment_gateway/apps/gateway/admin.py +++ b/src/hope_payment_gateway/apps/gateway/admin.py @@ -39,6 +39,7 @@ FinancialServiceProviderConfig, PaymentInstruction, PaymentRecord, + Office, ) if TYPE_CHECKING: @@ -386,13 +387,13 @@ def handle_error(self, resp) -> tuple: @admin.register(PaymentInstruction) class PaymentInstructionAdmin(ExtraButtonsMixin, admin.ModelAdmin): - list_display = ("external_code", "remote_id", "fsp", "status", "tag") + list_display = ("external_code", "office", "remote_id", "fsp", "status", "tag") list_filter = ("fsp", "status") search_fields = ("external_code", "remote_id", "fsp__name", "tag") formfield_overrides = { JSONField: {"widget": JSONEditor}, } - raw_id_fields = ("fsp", "system") + raw_id_fields = ("fsp", "system", "office") @button(permission="gateway.can_export_records") def export_records(self, request: HttpRequest, pk: int) -> TemplateResponse: @@ -484,6 +485,15 @@ class FinancialServiceProviderConfigInline(TabularInline): extra = 1 +@admin.register(Office) +class OfficeAdmin(ExtraButtonsMixin, admin.ModelAdmin): + list_display = ("name", "long_name", "slug", "code", "active") + search_fields = ("name", "slug", "code") + list_filter = ("active",) + readonly_fields = ("remote_id", "slug") + ordering = ("name",) + + @admin.register(FinancialServiceProvider) class FinancialServiceProviderAdmin(ExtraButtonsMixin, admin.ModelAdmin): list_display = ( diff --git a/src/hope_payment_gateway/apps/gateway/migrations/0031_office_paymentinstruction_office.py b/src/hope_payment_gateway/apps/gateway/migrations/0031_office_paymentinstruction_office.py new file mode 100644 index 0000000..9c6e3bc --- /dev/null +++ b/src/hope_payment_gateway/apps/gateway/migrations/0031_office_paymentinstruction_office.py @@ -0,0 +1,93 @@ +# Generated by Django 5.1.6 on 2025-02-19 15:49 + +import django.db.models.deletion +import django.utils.timezone +import model_utils.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("gateway", "0030_remove_paymentrecord_marked_for_payment"), + ] + + operations = [ + migrations.CreateModel( + name="Office", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "created", + model_utils.fields.AutoCreatedField( + default=django.utils.timezone.now, + editable=False, + verbose_name="created", + ), + ), + ( + "modified", + model_utils.fields.AutoLastModifiedField( + default=django.utils.timezone.now, + editable=False, + verbose_name="modified", + ), + ), + ( + "remote_id", + models.CharField(blank=True, max_length=100, null=True, unique=True), + ), + ( + "long_name", + models.CharField(blank=True, db_index=True, max_length=100, null=True), + ), + ( + "name", + models.CharField(blank=True, db_index=True, max_length=100, null=True), + ), + ( + "code", + models.CharField( + blank=True, + db_index=True, + max_length=100, + null=True, + unique=True, + ), + ), + ( + "slug", + models.SlugField(blank=True, max_length=100, null=True, unique=True), + ), + ("active", models.BooleanField(default=False)), + ( + "supervised", + models.BooleanField( + default=False, + help_text="Flag to enable/disable offices, which need manual check", + ), + ), + ("extra_fields", models.JSONField(blank=True, default=dict)), + ], + options={ + "abstract": False, + }, + ), + migrations.AddField( + model_name="paymentinstruction", + name="office", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="gateway.office", + ), + ), + ] diff --git a/src/hope_payment_gateway/apps/gateway/models.py b/src/hope_payment_gateway/apps/gateway/models.py index 2cc8bbc..ae4292d 100644 --- a/src/hope_payment_gateway/apps/gateway/models.py +++ b/src/hope_payment_gateway/apps/gateway/models.py @@ -37,6 +37,21 @@ def __str__(self) -> str: return f"{self.name} [{self.code}]" +class Office(TimeStampedModel): + remote_id = models.CharField(max_length=100, blank=True, null=True, unique=True) + long_name = models.CharField(max_length=100, blank=True, null=True, db_index=True) + name = models.CharField(max_length=100, blank=True, null=True, db_index=True) + code = models.CharField(max_length=100, blank=True, null=True, db_index=True, unique=True) + slug = models.SlugField(max_length=100, blank=True, null=True, db_index=True, unique=True) + active = models.BooleanField(default=False) + supervised = models.BooleanField(default=False, help_text="Flag to enable/disable offices, which need manual check") + + extra_fields = models.JSONField(default=dict, blank=True, null=False) + + def __str__(self) -> str: + return str(self.name) + + class FinancialServiceProvider(TimeStampedModel): remote_id = models.CharField(max_length=255, db_index=True, null=True, blank=True) name = models.CharField(max_length=64, unique=True) @@ -85,6 +100,7 @@ class PaymentInstruction(TimeStampedModel): choices=PaymentInstructionState.choices, db_index=True, ) + office = models.ForeignKey(Office, on_delete=models.SET_NULL, null=True, blank=True) tag = models.CharField(null=True, blank=True) payload = models.JSONField(default=dict, null=True, blank=True)