diff --git a/apps/authentication/mixins/region_filter.py b/apps/authentication/mixins/region_filter.py index 58e5d8f..4fb69cc 100644 --- a/apps/authentication/mixins/region_filter.py +++ b/apps/authentication/mixins/region_filter.py @@ -33,13 +33,14 @@ class RegionFilterMixin: scope = organization.field_of_activity print(scope) if scope == 'CI': - if hasattr(queryset.model, 'city_id'): + if hasattr(queryset.model, 'city'): queryset = queryset.filter(city=organization.city) + print(queryset) elif hasattr(queryset.model, 'user'): queryset = queryset.filter(user__city=organization.city) elif scope == 'PR': - if hasattr(queryset.model, 'province_id'): + if hasattr(queryset.model, 'province'): queryset = queryset.filter(province=organization.province) elif hasattr(queryset.model, 'user'): queryset = queryset.filter(user__province=organization.province) diff --git a/apps/core/services/visibility_service.py b/apps/core/services/visibility_service.py new file mode 100644 index 0000000..f43f059 --- /dev/null +++ b/apps/core/services/visibility_service.py @@ -0,0 +1,24 @@ +from apps.core.visibility_registry import VISIBILITY_MAP_BY_ORG_KEY + + +def apply_visibility_filter_by_org_type(queryset, org): + """ + Dynamically filter queryset based on user's organization type and model. + """ + + if not org: + return queryset.none() + + model_name = queryset.model.__name__.lower() + + if model_name not in VISIBILITY_MAP_BY_ORG_KEY: + return queryset + + org_type_key = getattr(org.type, 'key', None) + visibility_field = VISIBILITY_MAP_BY_ORG_KEY[model_name].get(org_type_key) + + if visibility_field is None: + return queryset + + filter_kwargs = {f"{visibility_field}": org} + return queryset.filter(**filter_kwargs) diff --git a/apps/core/visibility_registry.py b/apps/core/visibility_registry.py index b0f1889..86f5cf6 100644 --- a/apps/core/visibility_registry.py +++ b/apps/core/visibility_registry.py @@ -17,3 +17,10 @@ VISIBILITY_MAP = { # 'stakeholdershareamount': 'registering_organization', # 'posfreeproducts': 'organization', } + +VISIBILITY_MAP_BY_ORG_KEY = { + 'device': { + 'PSP': 'organization', + 'CO': 'assignment__client__organization' + }, +} diff --git a/apps/pos_device/models.py b/apps/pos_device/models.py index 4fefe51..91c4c36 100644 --- a/apps/pos_device/models.py +++ b/apps/pos_device/models.py @@ -42,18 +42,6 @@ class Device(BaseModel): server_in = models.BooleanField(default=False) latitude = models.FloatField(default=0) longitude = models.FloatField(default=0) - city = models.ForeignKey( - City, - on_delete=models.CASCADE, - related_name='devices', - null=True - ) - province = models.ForeignKey( - Province, - on_delete=models.CASCADE, - related_name='devices', - null=True - ) is_activated = models.BooleanField(default=False) pre_registered = models.BooleanField(default=False) organization = models.ForeignKey( diff --git a/apps/pos_device/web/api/v1/viewsets/device.py b/apps/pos_device/web/api/v1/viewsets/device.py index 9de8244..4ca3d3e 100644 --- a/apps/pos_device/web/api/v1/viewsets/device.py +++ b/apps/pos_device/web/api/v1/viewsets/device.py @@ -22,6 +22,7 @@ from apps.core.api import BaseViewSet from apps.core.mixins.admin_mixin import AdminFilterMixin from apps.core.mixins.search_mixin import DynamicSearchMixin from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin +from apps.core.services.visibility_service import apply_visibility_filter_by_org_type from apps.pos_device import models as pos_models from apps.pos_device.web.api.v1.serilaizers import device as device_serializer from apps.pos_device.web.api.v1.viewsets.client import POSClientViewSet @@ -97,11 +98,12 @@ class DeviceViewSet(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet, AdminFi """ list of company devices """ organization = get_organization_by_user(request.user) # using admin filter mixin to get query - devices = self.get_query(self.get_queryset( + devices = self.get_queryset( visibility_by_org_scope=True - ) if organization.free_visibility_by_scope else self.get_queryset().filter( - organization=organization - )) + ) if organization.free_visibility_by_scope else self.get_queryset() + + queryset = apply_visibility_filter_by_org_type(devices, organization) + print(queryset) # paginate devices page = self.paginate_queryset(devices) diff --git a/logs/django_requests.log b/logs/django_requests.log index 522adc4..d5d0805 100644 --- a/logs/django_requests.log +++ b/logs/django_requests.log @@ -696,3 +696,79 @@ AssertionError: .validate() should return the validated data [2025-11-02 17:05:50,482] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. [2025-11-02 17:05:54,363] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader [2025-11-02 17:10:53,634] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-02 17:10:55,626] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 08:52:16,260] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 08:52:23,837] INFO django.server | IP: - | Path: - | "POST /captcha/ HTTP/1.1" 200 734 +[2025-11-03 09:07:33,780] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:07:49,882] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:07:55,940] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:08:02,031] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:08:12,068] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:08:15,778] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:08:19,504] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:13:48,820] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:13:51,341] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:14:16,256] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:14:38,098] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:14:40,731] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:17:55,232] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:27:52,355] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:27:54,826] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:32:52,586] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:32:55,429] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:32:59,518] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:39:56,705] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:39:59,060] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:40:03,346] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:40:07,392] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:56:52,184] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:56:56,070] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:57:00,425] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 09:57:22,204] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 09:57:25,042] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 09:57:29,259] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:01:29,908] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\core\api.py changed, reloading. +[2025-11-03 10:01:32,068] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:01:41,019] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\web\api\v1\viewsets\device.py changed, reloading. +[2025-11-03 10:01:42,739] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:01:50,750] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:01:55,789] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:02:19,493] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\core\api.py changed, reloading. +[2025-11-03 10:02:22,611] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:02:26,434] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:02:54,922] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\core\api.py changed, reloading. +[2025-11-03 10:02:58,180] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:03:02,201] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:03:45,668] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:03:47,551] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:03:52,775] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:04:18,466] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:04:20,166] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:04:26,951] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:04:28,586] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:04:34,599] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:04:49,020] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:04:50,814] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:04:56,534] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:05:04,838] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:05:07,420] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:05:11,911] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:05:21,965] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:05:23,732] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:05:30,474] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:05:42,120] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:05:44,538] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:05:48,590] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:06:03,496] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:06:05,325] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:06:16,023] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:06:17,711] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:06:25,696] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:06:28,132] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:07:16,489] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:07:27,192] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\authentication\mixins\region_filter.py changed, reloading. +[2025-11-03 10:07:29,063] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:07:33,174] INFO django.server | IP: - | Path: - | "GET /pos_device/web/v1/pos/device/my_devices/ HTTP/1.1" 200 67 +[2025-11-03 10:08:23,644] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\core\api.py changed, reloading. +[2025-11-03 10:08:25,957] INFO django.utils.autoreload | IP: - | Path: - | Watching for file changes with StatReloader +[2025-11-03 10:16:18,352] INFO django.utils.autoreload | IP: - | Path: - | D:\Project\Rasaddam_Backend\apps\pos_device\models.py changed, reloading.