Огромная замена логики
All checks were successful
Deploy MES Core / deploy (push) Successful in 11s

This commit is contained in:
2026-04-06 08:06:37 +03:00
parent 0e8497ab1f
commit e88b861f68
48 changed files with 3833 additions and 175 deletions

View File

@@ -0,0 +1,120 @@
from django.db import transaction
from django.utils import timezone
from shiftflow.models import (
CuttingSession,
Item,
ProductionReportConsumption,
ProductionReportRemnant,
ShiftItem,
)
from shiftflow.services.sessions import close_cutting_session
from warehouse.models import StockItem
@transaction.atomic
def apply_closing(
*,
user_id: int,
machine_id: int,
material_id: int,
item_actions: dict[int, dict],
consumptions: dict[int, float],
remnants: list[dict],
) -> None:
items = list(
Item.objects.select_for_update(of=('self',))
.select_related('task', 'task__deal', 'task__material', 'machine')
.filter(id__in=list(item_actions.keys()), machine_id=machine_id, status='work', task__material_id=material_id)
)
if not items:
raise RuntimeError('Не найдено пунктов сменки для закрытия.')
report = CuttingSession.objects.create(
operator_id=user_id,
machine_id=machine_id,
used_stock_item=None,
date=timezone.localdate(),
is_closed=False,
)
for it in items:
spec = item_actions.get(it.id) or {}
action = (spec.get('action') or '').strip()
fact = int(spec.get('fact') or 0)
if action not in ['done', 'partial']:
continue
plan = int(it.quantity_plan or 0)
if plan <= 0:
continue
if action == 'done':
fact = plan
else:
fact = max(0, min(fact, plan))
if fact <= 0:
raise RuntimeError('При частичном закрытии факт должен быть больше 0.')
ShiftItem.objects.create(session=report, task=it.task, quantity_fact=fact)
for stock_item_id, qty in consumptions.items():
if qty <= 0:
continue
ProductionReportConsumption.objects.create(
report=report,
stock_item_id=stock_item_id,
material_id=None,
quantity=float(qty),
)
for r in remnants:
qty = float(r.get('quantity') or 0)
if qty <= 0:
continue
ProductionReportRemnant.objects.create(
report=report,
material_id=material_id,
quantity=qty,
current_length=r.get('current_length'),
current_width=r.get('current_width'),
unique_id=None,
)
close_cutting_session(report.id)
for it in items:
spec = item_actions.get(it.id) or {}
action = (spec.get('action') or '').strip()
fact = int(spec.get('fact') or 0)
if action not in ['done', 'partial']:
continue
plan = int(it.quantity_plan or 0)
if plan <= 0:
continue
if action == 'done':
it.quantity_fact = plan
it.status = 'done'
it.save(update_fields=['quantity_fact', 'status'])
continue
fact = max(0, min(fact, plan))
residual = plan - fact
it.quantity_fact = fact
it.status = 'partial'
it.save(update_fields=['quantity_fact', 'status'])
if residual > 0:
Item.objects.create(
task=it.task,
date=it.date,
machine=it.machine,
quantity_plan=residual,
quantity_fact=0,
status='leftover',
is_synced_1c=False,
)