Переезд на схему нового доступа
All checks were successful
Deploy MES Core / deploy (push) Successful in 11s
All checks were successful
Deploy MES Core / deploy (push) Successful in 11s
This commit is contained in:
@@ -90,7 +90,8 @@ TEMPLATES = [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'shiftflow.context_processors.env_info', # Правильный путь
|
||||
'shiftflow.context_processors.env_info',
|
||||
'shiftflow.context_processors.authz_info',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
from django.conf import settings
|
||||
|
||||
from shiftflow.authz import get_user_roles, primary_role
|
||||
|
||||
|
||||
def env_info(request):
|
||||
"""
|
||||
Прокидываем ENV_TYPE во все шаблоны.
|
||||
"""
|
||||
return {
|
||||
'ENV_TYPE': getattr(settings, 'ENV_TYPE', 'local')
|
||||
}
|
||||
|
||||
|
||||
def authz_info(request):
|
||||
roles = get_user_roles(getattr(request, 'user', None))
|
||||
profile = getattr(getattr(request, 'user', None), 'profile', None)
|
||||
return {
|
||||
'user_roles': sorted(roles),
|
||||
'user_role': primary_role(roles),
|
||||
'is_readonly': bool(getattr(profile, 'is_readonly', False)) if profile else False,
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="card shadow border-secondary">
|
||||
<div class="card-header border-secondary py-3 d-flex justify-content-between align-items-center">
|
||||
<h3 class="text-accent mb-0"><i class="bi bi-building me-2"></i>Заказчики</h3>
|
||||
{% if user_role in 'admin,technologist' %}
|
||||
{% if user_role in 'admin,technologist,clerk,manager' %}
|
||||
<button type="button" class="btn btn-outline-accent btn-sm" data-bs-toggle="modal" data-bs-target="#companyModal">
|
||||
<i class="bi bi-plus-lg me-1"></i>Добавить заказчика
|
||||
</button>
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Склад</label>
|
||||
<select class="form-select" name="location_id" required>
|
||||
{% for loc in transfer_locations %}
|
||||
{% for loc in receipt_locations %}
|
||||
<option value="{{ loc.id }}">{{ loc }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
@@ -2938,9 +2938,8 @@ class MaterialUpsertView(LoginRequiredMixin, View):
|
||||
|
||||
class CompanyUpsertView(LoginRequiredMixin, View):
|
||||
def post(self, request, *args, **kwargs):
|
||||
profile = getattr(request.user, 'profile', None)
|
||||
role = profile.role if profile else ('admin' if request.user.is_superuser else 'operator')
|
||||
if role not in ['admin', 'technologist']:
|
||||
roles = get_user_roles(request.user)
|
||||
if not has_any_role(roles, ['admin', 'clerk', 'manager', 'technologist']):
|
||||
return JsonResponse({'error': 'forbidden'}, status=403)
|
||||
|
||||
company_id = request.POST.get('id')
|
||||
@@ -3991,6 +3990,7 @@ class WarehouseStocksView(LoginRequiredMixin, TemplateView):
|
||||
allowed_transfer_locations = list(Location.objects.filter(id__in=allowed_loc_ids).order_by('name'))
|
||||
|
||||
ctx['transfer_locations'] = allowed_transfer_locations if allowed_transfer_locations is not None else locations
|
||||
ctx['receipt_locations'] = allowed_transfer_locations if allowed_transfer_locations is not None else locations
|
||||
|
||||
ctx['materials'] = Material.objects.select_related('category').all().order_by('full_name')
|
||||
ctx['entities'] = ProductEntity.objects.all().order_by('drawing_number', 'name')
|
||||
@@ -4087,6 +4087,19 @@ class WarehouseReceiptCreateView(LoginRequiredMixin, View):
|
||||
messages.error(request, 'Выбери склад.')
|
||||
return redirect(next_url)
|
||||
|
||||
profile = getattr(request.user, 'profile', None)
|
||||
role = primary_role(roles)
|
||||
if role == 'master' and not has_any_role(roles, ['admin', 'technologist', 'clerk', 'prod_head', 'director']):
|
||||
allowed_ws_ids = list(profile.allowed_workshops.values_list('id', flat=True)) if profile else []
|
||||
if not allowed_ws_ids and profile:
|
||||
user_machine_ids = list(profile.machines.values_list('id', flat=True))
|
||||
allowed_ws_ids = list(Machine.objects.filter(id__in=user_machine_ids).exclude(workshop_id__isnull=True).values_list('workshop_id', flat=True))
|
||||
|
||||
allowed_loc_ids = list(Workshop.objects.filter(id__in=allowed_ws_ids).exclude(location_id__isnull=True).values_list('location_id', flat=True))
|
||||
if not allowed_loc_ids or int(location_id) not in {int(x) for x in allowed_loc_ids}:
|
||||
messages.error(request, 'Мастер может делать приход только на склад своего цеха.')
|
||||
return redirect(next_url)
|
||||
|
||||
try:
|
||||
qty = float(quantity_raw)
|
||||
except ValueError:
|
||||
|
||||
Reference in New Issue
Block a user