Правки логики
This commit is contained in:
@@ -69,7 +69,7 @@ class PortalPharmacyEditForm(forms.ModelForm):
|
||||
'curator': forms.Select(attrs={'class': 'input'}),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args, user=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
from apps.employees.models import Employee
|
||||
|
||||
@@ -98,3 +98,7 @@ class PortalPharmacyEditForm(forms.ModelForm):
|
||||
self.fields['building'].required = False
|
||||
self.fields['apartment'].required = False
|
||||
self.fields['location'].required = False
|
||||
|
||||
if user is not None and not user.has_perm('locations.manage_location_access'):
|
||||
for field in ('head_pharmacist', 'responsible_manager', 'curator'):
|
||||
self.fields.pop(field, None)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from .access import GroupLocationAccess
|
||||
from .base import Location, LocationManager
|
||||
from .pharmacies import Pharmacy, PharmacyManager, PharmacyPhone, PharmacyHistory
|
||||
from .dislocation import DislocationColumnPreset
|
||||
@@ -9,7 +10,7 @@ from .pharmacy_visibility import (
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'Location', 'LocationManager',
|
||||
'GroupLocationAccess', 'Location', 'LocationManager',
|
||||
'Pharmacy', 'PharmacyManager', 'PharmacyPhone', 'PharmacyHistory',
|
||||
'DislocationColumnPreset',
|
||||
'PharmacyCardVisibility', 'pharmacy_card_flags',
|
||||
|
||||
@@ -128,6 +128,7 @@ class Location(BaseModel):
|
||||
objects = LocationManager()
|
||||
|
||||
class Meta:
|
||||
permissions = [('view_all_locations', 'Доступ к данным всех локаций портала'), ('manage_location_access', 'Назначение ответственных за локации')]
|
||||
verbose_name = _('Локация')
|
||||
verbose_name_plural = _('Локации')
|
||||
indexes = [
|
||||
|
||||
@@ -104,6 +104,9 @@ def user_can_view_pharmacy_section(user, pharmacy, level: str) -> bool:
|
||||
"""Проверка уровня видимости для user × pharmacy."""
|
||||
if not user or not getattr(user, 'is_authenticated', False):
|
||||
return False
|
||||
from core.location_access import accessible_pharmacies
|
||||
if not accessible_pharmacies(user).filter(pk=pharmacy.pk).exists():
|
||||
return False
|
||||
if getattr(user, 'is_superuser', False):
|
||||
return True
|
||||
|
||||
@@ -116,7 +119,7 @@ def user_can_view_pharmacy_section(user, pharmacy, level: str) -> bool:
|
||||
if level == PharmacyCardVisibility.Level.OWN_OR_STAFF:
|
||||
if getattr(user, 'is_staff', False):
|
||||
return True
|
||||
return getattr(user, 'user_pharmacy_id', None) == getattr(pharmacy, 'pk', None)
|
||||
return True # область уже проверена: своя или закреплённая аптека
|
||||
if level == PharmacyCardVisibility.Level.IT:
|
||||
from core.portal_access import user_can_access
|
||||
if user_can_access(user, 'it_manager'):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from core.test_utils import grant_all_locations
|
||||
from unittest import mock
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
@@ -355,6 +356,8 @@ class PharmacyCardVisibilityTests(TestCase):
|
||||
cls.it_user = Employee.objects.create_user(username='vis.it', **common)
|
||||
it_group, _ = Group.objects.get_or_create(name='IT')
|
||||
cls.it_user.groups.add(it_group)
|
||||
grant_all_locations(cls.it_user)
|
||||
grant_all_locations(cls.staff)
|
||||
PharmacyCardVisibility.load()
|
||||
|
||||
def _set_level(self, section, level):
|
||||
@@ -464,7 +467,7 @@ class PharmacyCardVisibilityTests(TestCase):
|
||||
|
||||
everyone = PharmacyCardVisibility.Level.EVERYONE
|
||||
hidden = PharmacyCardVisibility.Level.HIDDEN
|
||||
self.assertTrue(user_can_view_pharmacy_section(self.stranger, self.pharmacy, everyone))
|
||||
self.assertFalse(user_can_view_pharmacy_section(self.stranger, self.pharmacy, everyone))
|
||||
self.assertFalse(user_can_view_pharmacy_section(self.staff, self.pharmacy, hidden))
|
||||
self.assertTrue(user_can_view_pharmacy_section(self.superuser, self.pharmacy, hidden))
|
||||
|
||||
@@ -489,7 +492,7 @@ class PharmacyCardVisibilityTests(TestCase):
|
||||
self._set_level('rro', PharmacyCardVisibility.Level.EVERYONE)
|
||||
self._set_level('equipment', PharmacyCardVisibility.Level.HIDDEN)
|
||||
flags = pharmacy_card_flags(self.stranger, self.pharmacy)
|
||||
self.assertTrue(flags['can_view_rro'])
|
||||
self.assertFalse(flags['can_view_rro'])
|
||||
self.assertFalse(flags['can_view_equipment'])
|
||||
|
||||
def test_detail_view_hides_tab_when_section_staff_only(self):
|
||||
|
||||
@@ -8,6 +8,8 @@ from django.views.decorators.http import require_POST
|
||||
|
||||
from core.utils.htmx import render_page
|
||||
|
||||
from core.location_access import accessible_pharmacies
|
||||
|
||||
from .forms import PortalPharmacyEditForm
|
||||
from .models import Pharmacy, pharmacy_card_flags, user_can_edit_pharmacy
|
||||
|
||||
@@ -68,7 +70,7 @@ def _pharmacy_detail_context(request, pharmacy, *, form=None, edit_mode=False,
|
||||
|
||||
can_edit = flags['can_edit']
|
||||
if edit_mode and can_edit and form is None:
|
||||
form = PortalPharmacyEditForm(instance=pharmacy)
|
||||
form = PortalPharmacyEditForm(instance=pharmacy, user=request.user)
|
||||
|
||||
return {
|
||||
'pharmacy': pharmacy,
|
||||
@@ -94,7 +96,7 @@ def _pharmacy_detail_context(request, pharmacy, *, form=None, edit_mode=False,
|
||||
@require_POST
|
||||
def pharmacy_update_view(request, pk):
|
||||
pharmacy = get_object_or_404(
|
||||
Pharmacy.objects.select_related(
|
||||
accessible_pharmacies(request.user).select_related(
|
||||
'organization', 'location_region', 'head_pharmacist__post',
|
||||
'responsible_manager', 'curator',
|
||||
).prefetch_related('phones'),
|
||||
@@ -103,7 +105,7 @@ def pharmacy_update_view(request, pk):
|
||||
if not user_can_edit_pharmacy(request.user, pharmacy):
|
||||
return HttpResponseForbidden()
|
||||
|
||||
form = PortalPharmacyEditForm(request.POST, instance=pharmacy)
|
||||
form = PortalPharmacyEditForm(request.POST, instance=pharmacy, user=request.user)
|
||||
if form.is_valid():
|
||||
pharmacy = form.save(commit=False)
|
||||
pharmacy._history_user = request.user
|
||||
|
||||
Reference in New Issue
Block a user