add scope to filter data
This commit is contained in:
parent
394546dc67
commit
e9dec3292c
13 changed files with 386 additions and 36 deletions
|
@ -7,19 +7,62 @@ from django.http import JsonResponse
|
|||
from django.views.decorators.http import require_POST, require_GET
|
||||
from django.db import transaction
|
||||
from django.contrib.auth import get_user_model
|
||||
from .models import Process, ProcessInstance, StepInstance
|
||||
from .models import Process, ProcessInstance, StepInstance, ProcessStep
|
||||
from .utils import scope_instances_queryset, get_scoped_instance_or_404
|
||||
from installations.models import InstallationAssignment
|
||||
from wells.models import Well
|
||||
from accounts.models import Profile
|
||||
from accounts.models import Profile, Broker
|
||||
from locations.models import Affairs
|
||||
from accounts.forms import CustomerForm
|
||||
from wells.forms import WellForm
|
||||
from wells.models import WaterMeterManufacturer
|
||||
from common.consts import UserRoles
|
||||
|
||||
|
||||
@login_required
|
||||
def request_list(request):
|
||||
"""نمایش لیست درخواستها با جدول و مدال ایجاد"""
|
||||
instances = ProcessInstance.objects.select_related('well', 'representative', 'requester').prefetch_related('step_instances__step').filter(is_deleted=False).order_by('-created')
|
||||
instances = ProcessInstance.objects.select_related('well', 'representative', 'requester', 'broker', 'current_step', 'process').prefetch_related('step_instances__step').filter(is_deleted=False).order_by('-created')
|
||||
access_denied = False
|
||||
|
||||
# filter by roles (scoped queryset)
|
||||
try:
|
||||
instances = scope_instances_queryset(request.user, instances)
|
||||
if not instances.exists() and not getattr(request.user, 'profile', None):
|
||||
access_denied = True
|
||||
instances = instances.none()
|
||||
except Exception:
|
||||
access_denied = True
|
||||
instances = instances.none()
|
||||
|
||||
# Filters
|
||||
status_q = (request.GET.get('status') or '').strip()
|
||||
affairs_q = (request.GET.get('affairs') or '').strip()
|
||||
broker_q = (request.GET.get('broker') or '').strip()
|
||||
step_q = (request.GET.get('step') or '').strip()
|
||||
|
||||
if status_q:
|
||||
instances = instances.filter(status=status_q)
|
||||
if affairs_q:
|
||||
try:
|
||||
instances = instances.filter(well__affairs_id=int(affairs_q))
|
||||
except Exception:
|
||||
pass
|
||||
if broker_q:
|
||||
try:
|
||||
instances = instances.filter(broker_id=int(broker_q))
|
||||
except Exception:
|
||||
pass
|
||||
if step_q:
|
||||
try:
|
||||
instances = instances.filter(current_step_id=int(step_q))
|
||||
except Exception:
|
||||
pass
|
||||
processes = Process.objects.filter(is_active=True)
|
||||
status_choices = list(ProcessInstance.STATUS_CHOICES)
|
||||
affairs_list = Affairs.objects.all().order_by('name')
|
||||
brokers_list = Broker.objects.all().order_by('name')
|
||||
steps_list = ProcessStep.objects.select_related('process').all().order_by('process__name', 'order')
|
||||
manufacturers = WaterMeterManufacturer.objects.all().order_by('name')
|
||||
|
||||
# Calculate progress for each instance
|
||||
|
@ -52,6 +95,16 @@ def request_list(request):
|
|||
'completed_count': completed_count,
|
||||
'in_progress_count': in_progress_count,
|
||||
'pending_count': pending_count,
|
||||
# filter context
|
||||
'status_choices': status_choices,
|
||||
'affairs_list': affairs_list,
|
||||
'brokers_list': brokers_list,
|
||||
'steps_list': steps_list,
|
||||
'filter_status': status_q,
|
||||
'filter_affairs': affairs_q,
|
||||
'filter_broker': broker_q,
|
||||
'filter_step': step_q,
|
||||
'access_denied': access_denied,
|
||||
})
|
||||
|
||||
|
||||
|
@ -125,6 +178,13 @@ def lookup_representative_by_national_code(request):
|
|||
def create_request_with_entities(request):
|
||||
"""ایجاد/بهروزرسانی چاه و نماینده و سپس ایجاد درخواست"""
|
||||
User = get_user_model()
|
||||
# Only BROKER can create requests
|
||||
try:
|
||||
if not (hasattr(request.user, 'profile') and request.user.profile.has_role(UserRoles.BROKER)):
|
||||
return JsonResponse({'ok': False, 'error': 'فقط کارگزار مجاز به ایجاد درخواست است'}, status=403)
|
||||
except Exception:
|
||||
return JsonResponse({'ok': False, 'error': 'فقط کارگزار مجاز به ایجاد درخواست است'}, status=403)
|
||||
|
||||
process_id = request.POST.get('process')
|
||||
process = Process.objects.get(id=process_id)
|
||||
description = request.POST.get('description', '')
|
||||
|
@ -230,6 +290,14 @@ def create_request_with_entities(request):
|
|||
well.broker = current_profile.broker
|
||||
well.save()
|
||||
|
||||
# Ensure no active (non-deleted, non-completed) request exists for this well
|
||||
try:
|
||||
active_exists = ProcessInstance.objects.filter(well=well, is_deleted=False).exclude(status='completed').exists()
|
||||
if active_exists:
|
||||
return JsonResponse({'ok': False, 'error': 'برای این چاه یک درخواست جاری وجود دارد. ابتدا آن را تکمیل یا حذف کنید.'}, status=400)
|
||||
except Exception:
|
||||
return JsonResponse({'ok': False, 'error': 'خطا در بررسی وضعیت درخواستهای قبلی این چاه'}, status=400)
|
||||
|
||||
# Create request instance
|
||||
instance = ProcessInstance.objects.create(
|
||||
process=process,
|
||||
|
@ -261,7 +329,17 @@ def create_request_with_entities(request):
|
|||
@login_required
|
||||
def delete_request(request, instance_id):
|
||||
"""حذف درخواست"""
|
||||
instance = get_object_or_404(ProcessInstance, id=instance_id)
|
||||
instance = get_scoped_instance_or_404(request, instance_id)
|
||||
# Only BROKER can delete requests and only within their scope
|
||||
try:
|
||||
profile = getattr(request.user, 'profile', None)
|
||||
if not (profile and profile.has_role(UserRoles.BROKER)):
|
||||
return JsonResponse({'success': False, 'message': 'فقط کارگزار مجاز به حذف درخواست است'}, status=403)
|
||||
# Enforce ownership by broker (prevent deleting others' requests)
|
||||
if instance.broker_id and profile.broker and instance.broker_id != profile.broker.id:
|
||||
return JsonResponse({'success': False, 'message': 'شما مجاز به حذف این درخواست نیستید'}, status=403)
|
||||
except Exception:
|
||||
return JsonResponse({'success': False, 'message': 'فقط کارگزار مجاز به حذف درخواست است'}, status=403)
|
||||
code = instance.code
|
||||
if instance.status == 'completed':
|
||||
return JsonResponse({
|
||||
|
@ -278,10 +356,10 @@ def delete_request(request, instance_id):
|
|||
@login_required
|
||||
def step_detail(request, instance_id, step_id):
|
||||
"""نمایش جزئیات مرحله خاص"""
|
||||
instance = get_object_or_404(
|
||||
ProcessInstance.objects.select_related('process', 'well', 'requester', 'representative', 'representative__profile'),
|
||||
id=instance_id
|
||||
)
|
||||
# Enforce scoped access to prevent URL tampering
|
||||
instance = get_scoped_instance_or_404(request, instance_id)
|
||||
# Prefetch for performance
|
||||
instance = ProcessInstance.objects.select_related('process', 'well', 'requester', 'representative', 'representative__profile').get(id=instance.id)
|
||||
step = get_object_or_404(instance.process.steps, id=step_id)
|
||||
# If the request is already completed, redirect to read-only summary page
|
||||
if instance.status == 'completed':
|
||||
|
@ -339,7 +417,8 @@ def step_detail(request, instance_id, step_id):
|
|||
@login_required
|
||||
def instance_steps(request, instance_id):
|
||||
"""هدایت به مرحله فعلی instance"""
|
||||
instance = get_object_or_404(ProcessInstance, id=instance_id)
|
||||
# Enforce scoped access to prevent URL tampering
|
||||
instance = get_scoped_instance_or_404(request, instance_id)
|
||||
|
||||
if not instance.current_step:
|
||||
# اگر مرحله فعلی تعریف نشده، به اولین مرحله برو
|
||||
|
@ -361,6 +440,9 @@ def instance_steps(request, instance_id):
|
|||
@login_required
|
||||
def instance_summary(request, instance_id):
|
||||
"""نمای خلاصهٔ فقطخواندنی برای درخواستهای تکمیلشده."""
|
||||
# Enforce scoped access to prevent URL tampering
|
||||
instance = get_scoped_instance_or_404(request, instance_id)
|
||||
|
||||
instance = get_object_or_404(ProcessInstance.objects.select_related('well', 'representative'), id=instance_id)
|
||||
# Only show for completed requests; otherwise route to steps
|
||||
if instance.status != 'completed':
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue