Files
customerTicket/apps/payments/policies.py
T
2026-10-06 15:06:35 +03:30

87 lines
3.7 KiB
Python

from django.db.models import Q
from .models import PaymentAccessConfiguration, PaymentNotice
def is_staff(user):
profile = getattr(user, 'staff_profile', None)
return bool(user.is_authenticated and user.is_active and user.account_type == 'STAFF' and (profile is None or profile.is_active))
def has_permission(user, codename, unit=None):
if not is_staff(user):
return False
if user.has_perm(f'payments.{codename}'):
return True
if unit is None or not unit.is_active:
return False
return user.unit_memberships.filter(is_active=True, unit=unit).filter(
Q(permissions__content_type__app_label='payments', permissions__codename=codename) |
Q(unit__permissions__content_type__app_label='payments', unit__permissions__codename=codename)
).exists()
def config():
# No get_or_create on a read request; defaults keep initial view/create open only.
return PaymentAccessConfiguration.objects.first() or PaymentAccessConfiguration()
def can_create(user, unit=None):
if unit is None and is_staff(user):
from apps.tickets.policies import TicketPolicy
unit = TicketPolicy.primary_unit(user)
return is_staff(user) and (config().open_create or has_permission(user, 'add_paymentnotice', unit))
def can_manage_banks(user):
profile = getattr(user, 'staff_profile', None)
return is_staff(user) and (user.is_superuser or getattr(profile, 'role', '') == 'CEO' or has_permission(user, 'manage_company_bankaccounts'))
def may_delete_notice(user, notice):
role = getattr(getattr(user, 'staff_profile', None), 'role', '')
return is_staff(user) and (notice.created_by_id == user.pk or user.is_superuser or role in {'CEO', 'GENERAL_ADMIN'})
def can_delete_notice(user, notice):
return may_delete_notice(user, notice) and not notice.deleted_at and not notice.receipts.exists()
def notice_actions(queryset, user):
"""Allow deletion actors to reach this notice without broadening other lists."""
queryset = queryset.filter(deleted_at__isnull=True)
if not is_staff(user):
return queryset.none()
role = getattr(getattr(user, 'staff_profile', None), 'role', '')
if user.is_superuser or role in {'CEO', 'GENERAL_ADMIN'}:
return queryset
return queryset.filter(Q(created_by=user) | Q(pk__in=visible(queryset, user).values('pk')))
def visible(queryset, user):
if queryset.model == PaymentNotice:
queryset = queryset.filter(deleted_at__isnull=True)
if not user.is_authenticated or not user.is_active:
return queryset.none()
if user.account_type == 'CUSTOMER':
return queryset.filter(customer=user)
if not is_staff(user):
return queryset.none()
if config().open_view or user.has_perm('payments.view_all_payments') or user.is_superuser:
return queryset
permission = f'view_{queryset.model._meta.model_name}'
if user.has_perm(f'payments.{permission}'):
return queryset
units = user.unit_memberships.filter(is_active=True, unit__is_active=True).filter(
Q(permissions__content_type__app_label='payments', permissions__codename=permission) |
Q(unit__permissions__content_type__app_label='payments', unit__permissions__codename=permission)
).values_list('unit_id', flat=True)
return queryset.filter(owning_unit_id__in=units).distinct()
def can_decide(user, receipt, cycle, senior=False):
# Selection in the approval policy grants the role for this cycle. Requiring
# an additional Django permission made selected non-admin staff unable to vote.
return (is_staff(user) and receipt.submitted_by_id != user.pk and
visible(type(receipt).objects.filter(pk=receipt.pk), user).exists() and
cycle.assignments.filter(user=user, is_senior=senior).exists())