Доработал закрытие, техоперации автоматом переключаются, добавил выгрузку сменных заданий
All checks were successful
Deploy MES Core / deploy (push) Successful in 14s

This commit is contained in:
2026-04-25 11:58:11 +03:00
parent 6fd01c9a6e
commit 909ba05b5d
14 changed files with 998 additions and 74 deletions

View File

@@ -1,12 +1,22 @@
import logging
from django.db import transaction
from django.db.models import Q, Case, When, Value, IntegerField
from django.db.models import Q, Case, When, Value, IntegerField, Sum
from django.db.models.functions import Coalesce
from django.utils import timezone
from warehouse.models import StockItem
from shiftflow.models import WorkItem, CuttingSession, ProductionReportConsumption, ProductionReportStockResult
from shiftflow.models import (
DealEntityProgress,
DealItem,
ProductionTask,
WorkItem,
CuttingSession,
ProductionReportConsumption,
ProductionReportStockResult,
)
from shiftflow.services.bom_explosion import _build_bom_graph
from shiftflow.services.kitting import get_work_location_for_workitem
from manufacturing.models import EntityOperation
from shiftflow.services.route_flow import advance_progress_and_generate_next_workitem
from manufacturing.models import EntityOperation, Operation
def get_first_operation_id(entity_id: int) -> int | None:
@@ -189,6 +199,59 @@ def apply_assembly_closing(workitem_id: int, fact_qty: int, user_id: int) -> boo
if workitem.quantity_done >= workitem.quantity_plan:
workitem.status = 'done'
workitem.save(update_fields=['quantity_done', 'quantity_reported', 'status'])
advance_progress_and_generate_next_workitem(workitem_id=int(workitem.id))
target_qty = None
if getattr(workitem, 'delivery_batch_id', None):
target_qty = ProductionTask.objects.filter(
deal_id=workitem.deal_id,
delivery_batch_id=workitem.delivery_batch_id,
entity_id=workitem.entity_id,
).values_list('quantity_ordered', flat=True).first()
else:
di = DealItem.objects.filter(deal_id=workitem.deal_id, entity_id=workitem.entity_id).first()
target_qty = int(di.quantity) if di else None
if target_qty is not None:
op_code = ''
if getattr(workitem, 'operation_id', None):
op_code = (Operation.objects.filter(pk=workitem.operation_id).values_list('code', flat=True).first() or '').strip()
if not op_code:
op_code = (workitem.stage or '').strip()
if op_code:
progress = (
DealEntityProgress.objects.select_for_update(of=('self',))
.filter(
deal_id=workitem.deal_id,
delivery_batch_id=(int(workitem.delivery_batch_id) if getattr(workitem, 'delivery_batch_id', None) else None),
entity_id=workitem.entity_id,
)
.first()
)
if not progress:
progress = DealEntityProgress.objects.create(
deal_id=workitem.deal_id,
delivery_batch_id=(int(workitem.delivery_batch_id) if getattr(workitem, 'delivery_batch_id', None) else None),
entity_id=workitem.entity_id,
current_seq=1,
)
cur = int(progress.current_seq or 1)
cur_eo = EntityOperation.objects.select_related('operation').filter(entity_id=workitem.entity_id, seq=cur).first()
if cur_eo and cur_eo.operation and (cur_eo.operation.code or '').strip() == op_code:
wi_qs = WorkItem.objects.filter(deal_id=workitem.deal_id, entity_id=workitem.entity_id).filter(
Q(operation__code=op_code) | Q(stage=op_code)
)
if getattr(workitem, 'delivery_batch_id', None):
wi_qs = wi_qs.filter(delivery_batch_id=workitem.delivery_batch_id)
else:
wi_qs = wi_qs.filter(delivery_batch_id__isnull=True)
total_done = wi_qs.aggregate(s=Coalesce(Sum('quantity_done'), 0))['s']
if int(total_done or 0) >= int(target_qty):
progress.current_seq = cur + 1
progress.save(update_fields=['current_seq'])
logger.info(
'assembly_closing:done workitem_id=%s qty=%s deal_id=%s location_id=%s user_id=%s report_id=%s',