123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- 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
|