From f1a209a166f0454f0f8dff6f8329b1833aeb2d6a Mon Sep 17 00:00:00 2001 From: Mojtaba-z Date: Wed, 8 Oct 2025 11:13:01 +0330 Subject: [PATCH] import changes in notification --- Rasaddam_Backend/settings.py | 18 +++++++++- .../0003_notification_delivering_type.py | 18 ++++++++++ ...0004_alter_notification_delivering_type.py | 18 ++++++++++ apps/notification/models.py | 4 +++ apps/notification/pos/api/v1/api.py | 27 ++++++++++---- apps/pos_device/models.py | 2 +- apps/pos_device/services/services.py | 36 +++++++++++-------- apps/product/services/services.py | 2 +- requirements.txt | 4 ++- 9 files changed, 104 insertions(+), 25 deletions(-) create mode 100644 apps/notification/migrations/0003_notification_delivering_type.py create mode 100644 apps/notification/migrations/0004_alter_notification_delivering_type.py diff --git a/Rasaddam_Backend/settings.py b/Rasaddam_Backend/settings.py index 8d17d48..31e92c1 100644 --- a/Rasaddam_Backend/settings.py +++ b/Rasaddam_Backend/settings.py @@ -76,10 +76,12 @@ INSTALLED_APPS = [ 'drf_yasg', "django_celery_results", "django_celery_beat", + "elasticapm.contrib.django", ] MIDDLEWARE = [ + 'elasticapm.contrib.django.middleware.TracingMiddleware', 'apps.core.middlewares.Json500Middleware', 'corsheaders.middleware.CorsMiddleware', # noqa 'django.middleware.security.SecurityMiddleware', @@ -92,7 +94,7 @@ MIDDLEWARE = [ 'apps.authentication.middlewares.BlockedTokenMiddleware', 'crum.CurrentRequestUserMiddleware', # noqa 'apps.log.middlewares.SaveLog', - 'apps.pos_device.middlewares.PosDeviceValidationMiddleware' + 'apps.pos_device.middlewares.PosDeviceValidationMiddleware', ] ROOT_URLCONF = 'Rasaddam_Backend.urls' # noqa @@ -276,6 +278,20 @@ ELASTICSEARCH_DSL = { } } +ELASTIC_APM = { + 'SERVICE_NAME': 'rasaddam-backend', # noqa + + 'SECRET_TOKEN': 'T1hTTnZwa0JJbFhUVTBsQVRnbTc6cHpWVUloSklUaXViYllCdE9IQkFYQQ==', # noqa + + 'SERVER_URL': 'http://apm.rasadyar.com', # noqa + + 'ENVIRONMENT': 'production', # noqa + + 'DEBUG': True, + + 'ELASTIC_APM_LOG_LEVEL': 'trace' +} + # Password validation # https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators diff --git a/apps/notification/migrations/0003_notification_delivering_type.py b/apps/notification/migrations/0003_notification_delivering_type.py new file mode 100644 index 0000000..eb98d52 --- /dev/null +++ b/apps/notification/migrations/0003_notification_delivering_type.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0 on 2025-10-08 07:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notification', '0002_notification_device'), + ] + + operations = [ + migrations.AddField( + model_name='notification', + name='delivering_type', + field=models.CharField(choices=[('general', 'GENERAL'), ('private', 'PRIVATE')], max_length=150, null=True), + ), + ] diff --git a/apps/notification/migrations/0004_alter_notification_delivering_type.py b/apps/notification/migrations/0004_alter_notification_delivering_type.py new file mode 100644 index 0000000..50c9f46 --- /dev/null +++ b/apps/notification/migrations/0004_alter_notification_delivering_type.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0 on 2025-10-08 07:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notification', '0003_notification_delivering_type'), + ] + + operations = [ + migrations.AlterField( + model_name='notification', + name='delivering_type', + field=models.CharField(choices=[('general', 'GENERAL'), ('private', 'PRIVATE')], default='private', max_length=150, null=True), + ), + ] diff --git a/apps/notification/models.py b/apps/notification/models.py index 81568be..893252d 100644 --- a/apps/notification/models.py +++ b/apps/notification/models.py @@ -31,6 +31,10 @@ class Notification(BaseModel): choices=NOTIFICATION_TYPES, default='system' ) + delivering_type = models.CharField(max_length=150, null=True, choices=( + ('general', 'GENERAL'), + ('private', 'PRIVATE'), + ), default='private') is_read = models.BooleanField(default=False) delivered = models.BooleanField(default=False) diff --git a/apps/notification/pos/api/v1/api.py b/apps/notification/pos/api/v1/api.py index 3d97ebd..a122930 100644 --- a/apps/notification/pos/api/v1/api.py +++ b/apps/notification/pos/api/v1/api.py @@ -9,6 +9,7 @@ from rest_framework.response import Response from rest_framework import viewsets from rest_framework import status from django.db import transaction +from django.db.models import Q class NotificationViewSet(SoftDeleteMixin, POSDeviceMixin, DynamicSearchMixin, viewsets.ModelViewSet): @@ -22,12 +23,26 @@ class NotificationViewSet(SoftDeleteMixin, POSDeviceMixin, DynamicSearchMixin, v organization = self.get_device_organization() device = self.get_pos_device() - queryset = self.queryset.filter( - device=device, - organization=organization, - delivered=False, - is_read=False - ) + show_type = self.request.query_params.get('show') + + if show_type == 'undelivered': + queryset = self.queryset.filter( + Q(delivering_type='general') | Q(delivering_type='private'), + device=device, + organization=organization, + delivered=False, + is_read=False, + ) + elif show_type == 'unread': + queryset = self.queryset.filter( + Q(delivering_type='general') | Q(delivering_type='private'), + device=device, + organization=organization, + delivered=True, + is_read=False + ) + else: + queryset = self.queryset # paginate & response page = self.paginate_queryset(queryset) diff --git a/apps/pos_device/models.py b/apps/pos_device/models.py index 8bcf708..7048847 100644 --- a/apps/pos_device/models.py +++ b/apps/pos_device/models.py @@ -275,7 +275,7 @@ class StakeHolders(BaseModel): default = models.BooleanField(default=False) def __str__(self): - return f'Device: {self.assignment.device.serial}-organization: {self.organization.name}' + return f'ID: {self.id}-Device: {self.assignment.device.serial}-organization: {self.organization.name}' def save(self, *args, **kwargs): return super(StakeHolders, self).save(*args, **kwargs) diff --git a/apps/pos_device/services/services.py b/apps/pos_device/services/services.py index e39cdba..b84f5f0 100644 --- a/apps/pos_device/services/services.py +++ b/apps/pos_device/services/services.py @@ -47,20 +47,26 @@ def pos_organizations_sharing_information( }) # if device owner is an agency organization - if owner_org.type.name == 'AGC': - sharing_information_list.append({ - "organization_name": owner_org.parent_organization.name, - "bank_account": { - "credit_card": owner_org.parent_organization.bank_information.first().card, - "sheba": owner_org.parent_organization.bank_information.first().sheba, - "account": owner_org.parent_organization.bank_information.first().account, - } if owner_org.parent_organization.bank_information.exists() else {}, - "amount": quota.pricing_items.get( - name='base_price' - ) if quota.pricing_items.filter( - name='base_price' - ) else None, - "default_account": True - }) + # if owner_org.type.name == 'AGC': + agc_share_amount = owner_org.pos_stake_holders.filter( + device=device, + ).first().holders_share_amount.filter( + quota_distribution=distribution + ) + sharing_information_list.append({ + "organization_name": owner_org.parent_organization.name, + "bank_account": { + "credit_card": owner_org.parent_organization.bank_information.first().card, + "sheba": owner_org.parent_organization.bank_information.first().sheba, + "account": owner_org.parent_organization.bank_information.first().account, + } if owner_org.parent_organization.bank_information.exists() else {}, + # "amount": quota.pricing_items.get(name='base_price').value if quota.pricing_items.filter( + # name='base_price' + # ) else None, + # "agency_amount": agc_share_amount.first().share_amount if agc_share_amount else None, + "amount": 5000, + "agency_amount": 2000, + "default_account": True + }) return sharing_information_list diff --git a/apps/product/services/services.py b/apps/product/services/services.py index e79963b..0521601 100644 --- a/apps/product/services/services.py +++ b/apps/product/services/services.py @@ -104,7 +104,7 @@ def quota_pricing_items_by_type(quota: Quota, sharing: list) -> typing.Any: # calculate pos sharing accounts total price # summation with bellow price items and set final total price in output - calculate_sharing_total_price = sum(item['amount'] for item in sharing) + calculate_sharing_total_price = sum(item['amount'] for item in sharing if item['amount'] is not None) items = ( QuotaPriceCalculationItems.objects.filter(quota=quota).select_related( diff --git a/requirements.txt b/requirements.txt index f9d3854..d122ae2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -84,4 +84,6 @@ django-celery-results channels channels_redis daphne -django-jazzmin \ No newline at end of file +django-jazzmin +elastic-apm +psutil-7.1.0 \ No newline at end of file