Доработали фильт в реестре заданий
All checks were successful
Deploy MES Core / deploy (push) Successful in 10s

This commit is contained in:
2026-03-29 20:29:05 +03:00
parent 7ef7409c7a
commit 6013d5854b
22 changed files with 431 additions and 63 deletions

View File

@@ -2,7 +2,8 @@ from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.views.generic import TemplateView, ListView, UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Item # Проверь, как точно называется твоя модель деталей/заказов
from django.utils import timezone
from .models import Item, Machine
# Класс главной страницы (роутер)
class IndexView(TemplateView):
@@ -22,22 +23,84 @@ class RegistryView(LoginRequiredMixin, ListView):
context_object_name = 'items'
def get_queryset(self):
# Оптимизируем запросы, подгружая связанные данные сразу
queryset = Item.objects.select_related('task', 'task__deal', 'task__material', 'machine').all()
# Если это оператор, показываем только задания для его станков
if hasattr(self.request.user, 'profile') and self.request.user.profile.role == 'operator':
user_machines = self.request.user.profile.machines.all()
if user_machines.exists():
queryset = queryset.filter(machine__in=user_machines)
queryset = Item.objects.select_related('task', 'task__deal', 'task__material', 'machine')
user = self.request.user
profile = getattr(user, 'profile', None)
role = profile.role if profile else 'operator'
filtered = self.request.GET.get('filtered')
# Станки
m_ids = self.request.GET.getlist('m_ids')
if filtered and role != 'operator' and not m_ids:
return queryset.none()
if m_ids:
queryset = queryset.filter(machine_id__in=m_ids)
# Статусы (+ агрегат "closed" = done+partial)
statuses = self.request.GET.getlist('statuses')
if filtered and not statuses:
return queryset.none()
if statuses:
expanded = []
for s in statuses:
if s == 'closed':
expanded += ['done', 'partial']
else:
expanded.append(s)
queryset = queryset.filter(status__in=expanded)
# Даты
start_date = self.request.GET.get('start_date')
end_date = self.request.GET.get('end_date')
if not filtered:
today = timezone.now().date()
queryset = queryset.filter(date=today, status__in=['work', 'leftover'])
else:
if start_date:
queryset = queryset.filter(date__gte=start_date)
if end_date:
queryset = queryset.filter(date__lte=end_date)
# Списание (1С)
is_synced = self.request.GET.get('is_synced')
if is_synced in ['0', '1']:
queryset = queryset.filter(is_synced_1c=bool(int(is_synced)))
# Ограничения по ролям
if role == 'operator':
user_machines = profile.machines.all() if profile else Machine.objects.none()
queryset = queryset.filter(machine__in=user_machines, status='work')
elif role == 'master' and not filtered:
queryset = queryset.filter(status='work')
return queryset.order_by('status', '-date', 'machine__name', 'task__deal__number')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Передаем роль в шаблон, чтобы скрывать/показывать кнопки
if hasattr(self.request.user, 'profile'):
context['user_role'] = self.request.user.profile.role
user = self.request.user
profile = getattr(user, 'profile', None)
role = profile.role if profile else 'operator'
context['user_role'] = role
machines = Machine.objects.all()
context['machines'] = machines
filtered = self.request.GET.get('filtered')
if not filtered:
today_str = timezone.now().date().strftime('%Y-%m-%d')
context['start_date'] = today_str
context['end_date'] = today_str
context['selected_statuses'] = ['work', 'leftover']
context['selected_machines'] = [m.id for m in machines]
context['all_selected_machines'] = True
else:
context['selected_machines'] = [int(i) for i in self.request.GET.getlist('m_ids') if i.isdigit()]
context['selected_statuses'] = self.request.GET.getlist('statuses')
context['start_date'] = self.request.GET.get('start_date', '')
context['end_date'] = self.request.GET.get('end_date', '')
context['is_synced'] = self.request.GET.get('is_synced', '')
context['all_selected_machines'] = False
return context
# Вьюха детального вида и редактирования
@@ -59,6 +122,54 @@ class ItemUpdateView(LoginRequiredMixin, UpdateView):
context['user_role'] = self.request.user.profile.role
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
profile = getattr(request.user, 'profile', None)
role = profile.role if profile else 'operator'
# Общие поля
self.object.material_taken = request.POST.get('material_taken', self.object.material_taken)
self.object.usable_waste = request.POST.get('usable_waste', self.object.usable_waste)
self.object.scrap_weight = request.POST.get('scrap_weight', self.object.scrap_weight or 0)
status = request.POST.get('status', self.object.status)
if role in ['operator', 'master']:
if status == 'done':
self.object.quantity_fact = self.object.quantity_plan
self.object.status = 'done'
self.object.save()
elif status == 'partial':
try:
fact = int(request.POST.get('quantity_fact', '0'))
except ValueError:
fact = 0
fact = max(0, min(fact, self.object.quantity_plan))
residual = self.object.quantity_plan - fact
self.object.quantity_fact = fact
self.object.status = 'partial'
self.object.save()
if residual > 0:
Item.objects.create(
task=self.object.task,
date=self.object.date,
machine=self.object.machine,
quantity_plan=residual,
quantity_fact=0,
status='leftover',
is_synced_1c=False,
)
else:
# Просто сохранить без спец-логики
return super().post(request, *args, **kwargs)
elif role == 'clerk':
# Учетчик может отмечать списание 1С
self.object.is_synced_1c = bool(request.POST.get('is_synced_1c'))
self.object.save()
else:
return super().post(request, *args, **kwargs)
return redirect('registry')
def get_success_url(self):
# После сохранения возвращаемся в реестр
return reverse_lazy('registry')