from django.db.models import Sum, F from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,TaskModel,ContainerWCSModel from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel from .serializers import * from rest_framework.response import Response from rest_framework.views import APIView from django.utils import timezone from decimal import Decimal import logging logger = logging.getLogger(__name__) def update_container_category_for_container(container_id): """ 按需更新单个托盘的分类和批次信息 """ try: container = ContainerListModel.objects.get(id=container_id) # 获取托盘所有有效物料详情 details = container.details.filter( is_delete=False ).exclude(status=3).annotate( available_qty=F('goods_qty') - F('goods_out_qty') ).filter(available_qty__gt=0) # 计算总物料量 total_qty = details.aggregate(total=Sum('available_qty'))['total'] or 0 # 收集批次信息 batch_info = [] for detail in details: batch = detail.batch if batch: batch_info.append({ "batch_id": batch.id, "check_status": batch.check_status, "bound_number": batch.bound_number, "qty": float(detail.available_qty) # 转换为 float }) # 确定托盘分类 if total_qty == 0: # 空盘 category = 2 if container.status == 2 else 3 # 2=在库, 3=不在库 else: # 有物料 batch_count = details.values('batch').distinct().count() category = 0 if batch_count == 1 else 1 # 0=整盘, 1=散盘 # 更新 container.category = category container.batch_info = batch_info container.save(update_fields=['category', 'batch_info']) return True except Exception as e: logger.error(f"更新托盘分类时出错: {e}", exc_info=True) return False def batch_update_container_categories(container_ids): """ 批量更新多个托盘的分类和批次信息 """ updated_count = 0 error_ids = [] for container_id in container_ids: try: container = ContainerListModel.objects.get(id=container_id) # 获取托盘所有有效物料详情 details = container.details.filter( is_delete=False ).exclude(status=3).annotate( available_qty=F('goods_qty') - F('goods_out_qty') ).filter(available_qty__gt=0) # 计算总物料量 total_qty = details.aggregate(total=Sum('available_qty'))['total'] or 0 # 收集批次信息,合并批次数量 batch_info = [] batch_map = {} for detail in details: batch = detail.batch if batch: if batch.id in batch_map: batch_map[batch.id]['qty'] += float(detail.available_qty) # 转换为 float else: batch_map[batch.id] = { "batch_id": batch.id, "check_status": batch.check_status, "bound_number": batch.bound_number, "qty": float(detail.available_qty) # 转换为 float } batch_info = list(batch_map.values()) # 确定托盘分类 if total_qty == 0: # 空盘 category = 2 if container.current_location not in ['N/A', '103','203'] else 3 # 2=在库, 3=不在库 else: # 有物料 batch_count = details.values('batch').distinct().count() category = 0 if batch_count == 1 else 1 # 0=整盘, 1=散盘 # 更新 container.category = category container.batch_info = batch_info container.save(update_fields=['category', 'batch_info']) updated_count += 1 except Exception as e: logger.error(f"更新托盘 {container_id} 分类时出错: {e}", exc_info=True) error_ids.append(container_id) return { "updated": updated_count, "errors": error_ids, "total": len(container_ids) } def update_container_categories_task(): """后台任务:更新所有托盘的分类和批次信息""" container_ids = ContainerListModel.objects.values_list('id', flat=True) result = batch_update_container_categories(list(container_ids)) print(f"后台任务更新托盘分类: 成功 {result['updated']}, 失败 {len(result['errors'])}") logger.info(f"后台任务更新托盘分类: 成功 {result['updated']}, 失败 {len(result['errors'])}") return result