Ver Fonte

完成入库任务详细记录

flower_mr há 2 meses atrás
pai
commit
e999415f4b

BIN
container/__pycache__/filter.cpython-38.pyc


BIN
container/__pycache__/models.cpython-38.pyc


BIN
container/__pycache__/serializers.cpython-38.pyc


BIN
container/__pycache__/views.cpython-38.pyc


+ 9 - 2
container/filter.py

@@ -1,5 +1,5 @@
 from django_filters import FilterSet
-from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel
+from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,TaskModel
 
 class ContainerListFilter(FilterSet):
 
@@ -53,4 +53,11 @@ class ContainerOperationFilter(FilterSet):
             "memo": ['exact', 'icontains'],
         }
 
-    
+class TaskFilter(FilterSet):
+     class Meta:
+        model = TaskModel
+        fields = {
+            "id": ['exact', 'gt', 'gte', 'lt', 'lte', 'isnull', 'in', 'range'],
+            "task_wcs" : ['exact'],
+            "container_detail" : ['exact'],
+            }

+ 46 - 25
container/migrations/0001_initial.py

@@ -1,4 +1,4 @@
-# Generated by Django 4.1.2 on 2025-03-30 13:24
+# Generated by Django 4.1.2 on 2025-04-09 15:56
 
 from django.db import migrations, models
 import django.db.models.deletion
@@ -9,10 +9,33 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ('bound', '0002_bounddetailmodel_status'),
+        ('bound', '0003_boundbatchmodel_goods_std'),
     ]
 
     operations = [
+        migrations.CreateModel(
+            name='ContainerDetailModel',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('month', models.IntegerField(verbose_name='月份')),
+                ('goods_code', models.CharField(max_length=50, verbose_name='货品编码')),
+                ('goods_desc', models.CharField(max_length=100, verbose_name='货品描述')),
+                ('goods_qty', models.IntegerField(verbose_name='数量')),
+                ('goods_weight', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='重量')),
+                ('status', models.IntegerField(choices=[(0, '空盘'), (1, '组盘'), (2, '已出库')], default=0, verbose_name='状态')),
+                ('creater', models.CharField(max_length=50, verbose_name='创建人')),
+                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
+                ('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
+                ('is_delete', models.BooleanField(default=False, verbose_name='是否删除')),
+                ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bound.boundbatchmodel', verbose_name='批次')),
+            ],
+            options={
+                'verbose_name': 'ContainerDetail',
+                'verbose_name_plural': 'ContainerDetail',
+                'db_table': 'container_detail',
+                'ordering': ['-id'],
+            },
+        ),
         migrations.CreateModel(
             name='ContainerListModel',
             fields=[
@@ -52,12 +75,27 @@ class Migration(migrations.Migration):
                 'ordering': ['-create_time'],
             },
         ),
+        migrations.CreateModel(
+            name='TaskModel',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('bound_detail', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bound.bounddetailmodel', verbose_name='绑定明细')),
+                ('container_detail', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='container.containerdetailmodel', verbose_name='托盘明细')),
+                ('task_wcs', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='container.containerwcsmodel')),
+            ],
+            options={
+                'verbose_name': 'Task',
+                'verbose_name_plural': 'Task',
+                'db_table': 'task',
+                'ordering': ['-id'],
+            },
+        ),
         migrations.CreateModel(
             name='ContainerOperationModel',
             fields=[
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('month', models.IntegerField(verbose_name='月份')),
-                ('operation_type', models.CharField(choices=[('inbound', '入库'), ('outbound', '出库')], max_length=20, verbose_name='操作类型')),
+                ('operation_type', models.CharField(choices=[('container', '组盘'), ('inbound', '入库'), ('outbound', '出库'), ('adjust', '调整')], max_length=20, verbose_name='操作类型')),
                 ('goods_code', models.CharField(max_length=50, verbose_name='货品编码')),
                 ('goods_desc', models.CharField(max_length=100, verbose_name='货品描述')),
                 ('goods_qty', models.IntegerField(verbose_name='数量')),
@@ -67,6 +105,7 @@ class Migration(migrations.Migration):
                 ('from_location', models.CharField(max_length=50, null=True, verbose_name='原库位')),
                 ('to_location', models.CharField(max_length=50, null=True, verbose_name='目标库位')),
                 ('memo', models.TextField(null=True, verbose_name='备注')),
+                ('is_delete', models.BooleanField(default=False, verbose_name='是否删除')),
                 ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bound.boundbatchmodel', verbose_name='批次')),
                 ('container', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='operations', to='container.containerlistmodel')),
             ],
@@ -77,27 +116,9 @@ class Migration(migrations.Migration):
                 'ordering': ['-timestamp'],
             },
         ),
-        migrations.CreateModel(
-            name='ContainerDetailModel',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('month', models.IntegerField(verbose_name='月份')),
-                ('goods_code', models.CharField(max_length=50, verbose_name='货品编码')),
-                ('goods_desc', models.CharField(max_length=100, verbose_name='货品描述')),
-                ('goods_qty', models.IntegerField(verbose_name='数量')),
-                ('goods_weight', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='重量')),
-                ('status', models.IntegerField(default=1, verbose_name='状态')),
-                ('creater', models.CharField(max_length=50, verbose_name='创建人')),
-                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
-                ('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
-                ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bound.boundbatchmodel', verbose_name='批次')),
-                ('container', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='details', to='container.containerlistmodel')),
-            ],
-            options={
-                'verbose_name': 'ContainerDetail',
-                'verbose_name_plural': 'ContainerDetail',
-                'db_table': 'container_detail',
-                'ordering': ['-id'],
-            },
+        migrations.AddField(
+            model_name='containerdetailmodel',
+            name='container',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='details', to='container.containerlistmodel'),
         ),
     ]

+ 0 - 23
container/migrations/0002_alter_containerdetailmodel_status_and_more.py

@@ -1,23 +0,0 @@
-# Generated by Django 4.1.2 on 2025-03-31 20:51
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('container', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='containerdetailmodel',
-            name='status',
-            field=models.IntegerField(choices=[(0, '空盘'), (1, '组盘'), (2, '已出库')], default=0, verbose_name='状态'),
-        ),
-        migrations.AlterField(
-            model_name='containeroperationmodel',
-            name='operation_type',
-            field=models.CharField(choices=[('container', '组盘'), ('inbound', '入库'), ('outbound', '出库'), ('adjust', '调整')], max_length=20, verbose_name='操作类型'),
-        ),
-    ]

+ 20 - 0
container/migrations/0002_alter_taskmodel_bound_detail.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.2 on 2025-04-09 16:27
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bound', '0003_boundbatchmodel_goods_std'),
+        ('container', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='taskmodel',
+            name='bound_detail',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bound.bounddetailmodel', verbose_name='批次明细'),
+        ),
+    ]

+ 20 - 0
container/migrations/0003_alter_taskmodel_bound_detail.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.2 on 2025-04-09 16:57
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bound', '0003_boundbatchmodel_goods_std'),
+        ('container', '0002_alter_taskmodel_bound_detail'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='taskmodel',
+            name='bound_detail',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bound.boundbatchmodel', verbose_name='批次明细'),
+        ),
+    ]

+ 0 - 18
container/migrations/0003_containerdetailmodel_is_delete.py

@@ -1,18 +0,0 @@
-# Generated by Django 4.1.2 on 2025-04-03 10:30
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('container', '0002_alter_containerdetailmodel_status_and_more'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='containerdetailmodel',
-            name='is_delete',
-            field=models.BooleanField(default=False, verbose_name='是否删除'),
-        ),
-    ]

+ 0 - 18
container/migrations/0004_containeroperationmodel_is_delete.py

@@ -1,18 +0,0 @@
-# Generated by Django 4.1.2 on 2025-04-06 13:35
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('container', '0003_containerdetailmodel_is_delete'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='containeroperationmodel',
-            name='is_delete',
-            field=models.BooleanField(default=False, verbose_name='是否删除'),
-        ),
-    ]

+ 17 - 0
container/migrations/0004_remove_taskmodel_bound_detail.py

@@ -0,0 +1,17 @@
+# Generated by Django 4.1.2 on 2025-04-09 17:10
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('container', '0003_alter_taskmodel_bound_detail'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='taskmodel',
+            name='bound_detail',
+        ),
+    ]

BIN
container/migrations/__pycache__/0001_initial.cpython-38.pyc


BIN
container/migrations/__pycache__/0002_alter_taskmodel_bound_detail.cpython-38.pyc


BIN
container/migrations/__pycache__/0003_alter_taskmodel_bound_detail.cpython-38.pyc


BIN
container/migrations/__pycache__/0004_remove_taskmodel_bound_detail.cpython-38.pyc


BIN
container/migrations/__pycache__/0005_taskmodel.cpython-38.pyc


+ 10 - 5
container/models.py

@@ -1,6 +1,6 @@
 from django.db import models
 from bound.models import BoundBatchModel
-from bound.models import BoundDetailModel
+
 # Create your models here.
 # 主表:托盘数据
 class ContainerListModel(models.Model):
@@ -114,8 +114,13 @@ class ContainerWCSModel(models.Model):
             'status': self.status
         }
 
-# class TaskModel(models.Model):
+class TaskModel(models.Model):
     
-#     task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, related_name='tasks')
-#     batch = models.ForeignKey(BoundBatchModel, on_delete=models.CASCADE, verbose_name='批次')
-#     bound_detail = models.ForeignKey(BoundDetailModel, on_delete=models.CASCADE, verbose_name='绑定明细')
+    task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, related_name='tasks')
+    container_detail = models.ForeignKey(ContainerDetailModel, on_delete=models.CASCADE, verbose_name='托盘明细')
+    class Meta:
+        db_table = 'task'
+        verbose_name = 'Task'
+        verbose_name_plural = "Task"
+        ordering = ['-id']
+

+ 47 - 3
container/serializers.py

@@ -1,8 +1,7 @@
 from rest_framework import serializers
 
-from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel
-from bound.models import BoundBatchModel
-
+from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,TaskModel,ContainerWCSModel
+from bound.models import BoundBatchModel,BoundDetailModel
 
 from utils import datasolve
 
@@ -171,4 +170,49 @@ class ContainerOperationPostSerializer(serializers.ModelSerializer):
         fields= '__all__'
         read_only_fields = ['id']
 
+class TaskGetSerializer(serializers.ModelSerializer):
+    # 定义任务记录的序列化器,用于获取操作,字段只读
+    task_wcs = serializers.SerializerMethodField()
+    container_detail = serializers.SerializerMethodField()
+
+
+    def get_task_wcs(self, obj):
+        """ 动态序列化关联的WCS任务数据 """
+        from .models import ContainerWCSModel
+        return ContainerWCSModel.objects.filter(id=obj.task_wcs_id).first().to_dict()
+
+    def get_container_detail(self, obj):
+        """ 动态序列化关联的主单数据 """
+        from .serializers import ContainerDetailGetSerializer
+        return ContainerDetailGetSerializer(obj.container_detail).data
+
+    class Meta:
+        # 指定模型和排除字段
+        model = TaskModel
+        fields= '__all__'
+        read_only_fields = ['id']
 
+class TaskPostSerializer(serializers.ModelSerializer):
+    # 定义任务记录的序列化器,用于获取操作,字段只读
+    task_wcs = serializers.PrimaryKeyRelatedField(queryset=ContainerWCSModel.objects.all(),
+    help_text='关联的WCS任务',
+    error_messages = {
+        'null': '请选择关联的WCS任务',
+        'does_not_exist': '关联的WCS任务不存在',
+        'incorrect_type': '关联的WCS任务格式错误'
+    },
+    required=False, validators=[datasolve.data_validate])
+    bound_detail = serializers.PrimaryKeyRelatedField(queryset=BoundDetailModel.objects.all(),
+    help_text='关联的明细单',
+    error_messages = {
+        'null': '请选择关联的明细单',
+        'does_not_exist': '关联的明细单不存在',
+        'incorrect_type': '关联的明细单格式错误'
+    },
+    required=False, validators=[datasolve.data_validate])
+    class Meta:
+        # 指定模型和排除字段
+        model = TaskModel
+        fields= '__all__'
+        read_only_fields = ['id']
+        

+ 138 - 70
container/views.py

@@ -8,8 +8,10 @@ from rest_framework.response import Response
 from rest_framework.exceptions import APIException
 from django.utils import timezone
 
-
-from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,ContainerWCSModel
+from django.db import transaction
+import logging
+from rest_framework import status
+from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,ContainerWCSModel,TaskModel
 from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel
 
 # from .files import FileListRenderCN, FileDetailRenderCN
@@ -17,12 +19,14 @@ from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel
 from .serializers import ContainerDetailGetSerializer,ContainerDetailPostSerializer
 from .serializers import ContainerListGetSerializer,ContainerListPostSerializer
 from .serializers import ContainerOperationGetSerializer,ContainerOperationPostSerializer
-from .filter import ContainerDetailFilter,ContainerListFilter,ContainerOperationFilter
+from .serializers import TaskGetSerializer,TaskPostSerializer
+from .filter import ContainerDetailFilter,ContainerListFilter,ContainerOperationFilter,TaskFilter
 # 以后添加模
 from warehouse.models import ListModel as warehouse
 from staff.models import ListModel as staff
 from rest_framework.permissions import AllowAny
 
+logger = logging.getLogger(__name__)
 class ContainerListViewSet(viewsets.ModelViewSet):
     """
         retrieve:
@@ -108,7 +112,7 @@ class TaskViewSet(viewsets.ModelViewSet):
     pagination_class = MyPageNumberPagination   
     filter_backends = [DjangoFilterBackend, OrderingFilter, ]
     ordering_fields = ['id', "create_time", "update_time", ]
-    filter_class = ContainerListFilter
+    filter_class = TaskFilter
 
     def get_project(self):
         try:
@@ -121,33 +125,25 @@ class TaskViewSet(viewsets.ModelViewSet):
         id = self.get_project()
         if self.request.user:
             if id is None:
-                return ContainerListModel.objects.filter()
+                return TaskModel.objects.filter()
             else:
-                return ContainerListModel.objects.filter( id=id)
+                return TaskModel.objects.filter( id=id)
         else:
-            return ContainerListModel.objects.none()
+            return TaskModel.objects.none()
 
 
     def get_serializer_class(self):
         if self.action in ['list', 'destroy','retrieve']:
-            return ContainerListGetSerializer
+            return TaskGetSerializer
         elif self.action in ['create', 'update']:
-            return ContainerListPostSerializer
+            return TaskPostSerializer
         else:
             return self.http_method_not_allowed(request=self.request)
 
     def create(self, request, *args, **kwargs):
         data = self.request.data
-        order_month = str(timezone.now().strftime('%Y%m'))
-        data['month'] = order_month
-        data['last_operate'] = str(timezone.now())
-        
-        serializer = self.get_serializer(data=data)
-        serializer.is_valid(raise_exception=True)
-        serializer.save()
 
-        headers = self.get_success_headers(serializer.data)
-        return Response(serializer.data, status=200, headers=headers)
+        return Response(data, status=200, headers=headers)
     
     def update(self, request, pk):
         qs = self.get_object()
@@ -158,6 +154,7 @@ class TaskViewSet(viewsets.ModelViewSet):
         headers = self.get_success_headers(serializer.data)
         return Response(serializer.data, status=200, headers=headers)
 
+
 class ContainerWCSViewSet(viewsets.ModelViewSet):
     """
         retrieve:
@@ -178,66 +175,136 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
         data = self.request.data
         container = data.get('container_number')
         current_location = data.get('current_location')
-        container_obj = ContainerListModel.objects.filter(container_code=container).first()
-        data_tosave = {}
-        data_return={}
-        if container_obj:
-            data['container_code'] = container
-            serializer = ContainerListPostSerializer(container_obj, data=data)
+        data_return = {}
+
+        try:
+            container_obj = ContainerListModel.objects.filter(container_code=container).first()
+            if not container_obj:
+                data_return = {
+                    'code': '400',
+                    'message': '托盘编码不存在',
+                    'data': data
+                }
+                return Response(data_return, status=status.HTTP_400_BAD_REQUEST)
+
+            # 更新容器数据(部分更新)
+            serializer = ContainerListPostSerializer(
+                container_obj, 
+                data=data, 
+                partial=True  # 允许部分字段更新
+            )
             serializer.is_valid(raise_exception=True)
             serializer.save()
 
-            if current_location == container_obj.target_location:
-                print('当前位置已是目标位置')
-                data['message'] = '当前位置已是目标位置'
-                data_return={
-                    'code':'200',
-                    'message':data['message'],
-                    'data':data
+            # 检查是否已在目标位置
+            if current_location == str(container_obj.target_location):
+                logger.info(f"托盘 {container} 已在目标位置")
+                data_return = {
+                    'code': '200',
+                    'message': '当前位置已是目标位置',
+                    'data': data
                 }
             else:
-                print('当前位置不是目标位置')
-                current_task = ContainerWCSModel.objects.filter(container=container, tasktype='inbound').first()
+                current_task = ContainerWCSModel.objects.filter(
+                    container=container, 
+                    tasktype='inbound'
+                ).first()
+
                 if current_task:
-                    data['message'] = '当前任务已存在,再次下发'
-                    data_return={
-                        'code':'200',
-                        'message':data['message'],
-                        'data':current_task.to_dict()
+                    
+                    data_return = {
+                        'code': '200',
+                        'message': '任务已存在,重新下发',
+                        'data': current_task.to_dict()
                     }
                 else:
-                    print('生成入库任务')
-                    data_tosave['container'] = container
-                    data_tosave['current_location'] = current_location
-                    data_tosave['month'] = str(timezone.now().strftime('%Y%m'))
-                    data_tosave['target_location']=container_obj.target_location
-                    data_tosave['tasktype'] = 'inbound'
-                    container_obj_month = ContainerWCSModel.objects.filter( month=data_tosave['month']).all()
-                    if container_obj_month:
-                        data_tosave['taskid'] = data_tosave['tasktype']+'-'+data_tosave['month']+'-'+str(container_obj_month.count()+1).zfill(4)
-                    else:
-                        data_tosave['taskid'] = data_tosave['tasktype']+'-'+data_tosave['month']+'-0001'
-                    data_tosave['message'] = '生成入库任务'
-                    data_tosave['container'] = container
-                    data_tosave['status'] = 103
-                    data_tosave['is_delete'] = False
-                    data_return={
-                        'code':'200',
-                        'message':data_tosave['message'],
-                        'data':data_tosave
+                    self.generate_task(container, current_location, container_obj.target_location)
+                    current_task = ContainerWCSModel.objects.get(
+                        container=container, 
+                        tasktype='inbound'
+                    )
+                  
+                    data_return = {
+                        'code': '200',
+                        'message': '任务下发成功',
+                        'data': current_task.to_dict()
                     }
-                    ContainerWCSModel.objects.create(**data_tosave)
-                    print('入库任务创建成功', data_tosave['taskid']) 
+                    self.inport_update_task(current_task.id, container_obj.id)
+
+
+            http_status = status.HTTP_200_OK if data_return['code'] == '200' else status.HTTP_400_BAD_REQUEST
+            return Response(data_return, status=http_status)
+
+        except Exception as e:
+            logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
+            return Response(
+                {'code': '500', 'message': '服务器内部错误', 'data': None},
+                status=status.HTTP_500_INTERNAL_SERVER_ERROR
+            )
+
+    @transaction.atomic
+    def generate_task(self, container, current_location, target_location):
+        data_tosave = {
+            'container': container,
+            'current_location': current_location,
+            'month': timezone.now().strftime('%Y%m'),
+            'target_location': target_location,  
+            'tasktype': 'inbound',
+            'status': 103,
+            'is_delete': False
+        }
+
+        # 生成唯一递增的 taskid
+        last_task = ContainerWCSModel.objects.filter(
+            month=data_tosave['month'], 
+            tasktype='inbound'
+        ).order_by('-taskid').first()
+
+        if last_task:
+            last_id = int(last_task.taskid.split('-')[-1])
+            new_id = f"{last_id + 1:04}"
         else:
-            print('托盘编码不存在')
-            data_return={
-                'code':'400',
-                'message':'托盘编码不存在',
-                'data':data
-            }
-        
-        return Response(data_return)
+            new_id = "0001"
+
+        data_tosave['taskid'] = f"inbound-{data_tosave['month']}-{new_id}"
+        logger.info(f"生成入库任务: {data_tosave['taskid']}")
+        ContainerWCSModel.objects.create(**data_tosave)
 
+    @transaction.atomic
+    def inport_update_task(self, wcs_id,container_id):
+        try:
+            task_obj = ContainerWCSModel.objects.filter(id=wcs_id).first()
+            if task_obj:
+                container_detail_obj = ContainerDetailModel.objects.filter(container=container_id).all()
+                if container_detail_obj:
+                    for detail in container_detail_obj:
+                        # 保存到数据库
+                        batch = BoundBatchModel.objects.filter(id=detail.batch.id).first()
+                        TaskModel.objects.create(
+                            task_wcs = task_obj,
+                            container_detail = detail,
+
+                        )
+                        logger.info(f"入库任务 {wcs_id} 已更新")
+                else:
+                    logger.info(f"入库任务 {container_id} 批次不存在")
+            else:
+                logger.info(f"入库任务 {wcs_id} 不存在")
+        except Exception as e:     
+            logger.error(f"处理入库任务时发生错误: {str(e)}", exc_info=True)
+            return Response(
+                {'code': '500', 'message': '服务器内部错误', 'data': None},
+                status=status.HTTP_500_INTERNAL_SERVER_ERROR
+            )
+         
+
+
+# PDA组盘入库 将扫描到的托盘编码和批次信息保存到数据库
+# 1. 先查询托盘对象,如果不存在,则创建托盘对象
+# 2. 循环处理每个批次,查询批次对象,
+# 3. 更新批次数据(根据业务规则)
+# 4. 保存到数据库
+# 5. 保存操作记录到数据库
 class ContainerDetailViewSet(viewsets.ModelViewSet):
     """
         retrieve:
@@ -297,9 +364,10 @@ class ContainerDetailViewSet(viewsets.ModelViewSet):
         container_obj = ContainerListModel.objects.filter(container_code=container_code).first()
         if container_obj:
             data['container'] = container_obj.id
-            print('托盘编码存在', data['container'])
+            logger.info(f"托盘 {container_code} 已存在")
+    
         else:
-            print('托盘编码不存在')
+            logger.info(f"托盘 {container_code} 不存在,创建托盘对象")
             serializer_list = ContainerListPostSerializer(data={'container_code': container_code})
             serializer_list.is_valid(raise_exception=True)
             serializer_list.save()
@@ -315,7 +383,7 @@ class ContainerDetailViewSet(viewsets.ModelViewSet):
 
             if not bound_obj:
                 # 如果商品不存在,返回错误,这里暂时在程序中进行提醒,后续需要改为前端弹窗提醒
-                print(f"商品编码 {bound_number} 不存在")
+                logger.error(f"批次 {bound_number} 不存在")
                 # 跳出此次循环
                 continue
                 # return Response({"error": f"商品编码 {bound_number} 不存在"}, status=400)

BIN
db.sqlite3


+ 193 - 0
logs/error.log

@@ -2023,3 +2023,196 @@ Traceback (most recent call last):
   File "D:\Document\code\vue\greater_wms\.\container\views.py", line 163, in get_container_wcs
     return Response(data_return)
 UnboundLocalError: local variable 'data_return' referenced before assignment
+[2025-04-09 15:57:40,419][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 201, in get_container_wcs
+    generate_task(container, current_location, container_obj.target_location)
+NameError: name 'generate_task' is not defined
+[2025-04-09 16:05:39,930][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 197, in get_container_wcs
+    if current_location == str(container_obj.target_location.id):
+AttributeError: 'str' object has no attribute 'id'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 234, in get_container_wcs
+    logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
+NameError: name 'logger' is not defined
+[2025-04-09 16:07:08,036][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 198, in get_container_wcs
+    if current_location == str(container_obj.target_location.id):
+AttributeError: 'str' object has no attribute 'id'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 235, in get_container_wcs
+    logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
+NameError: name 'logger' is not defined
+[2025-04-09 16:09:03,176][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 199, in get_container_wcs
+    if current_location == str(container_obj.target_location.id):
+AttributeError: 'str' object has no attribute 'id'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 239, in get_container_wcs
+    status=status.HTTP_500_INTERNAL_SERVER_ERROR
+NameError: name 'status' is not defined
+[2025-04-09 16:11:10,421][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-09 16:12:01,800][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-09 16:12:40,458][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-09 17:00:03,451][django.request.log_response():241] [ERROR] Internal Server Error: /container/task/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\mixins.py", line 43, in list
+    return self.get_paginated_response(serializer.data)
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 768, in data
+    ret = super().data
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 253, in data
+    self._data = self.to_representation(self.instance)
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 686, in to_representation
+    return [
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 687, in <listcomp>
+    self.child.to_representation(item) for item in iterable
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
+    ret[field.field_name] = field.to_representation(attribute)
+  File "d:\language\python38\lib\site-packages\rest_framework\fields.py", line 1838, in to_representation
+    return method(value)
+  File "D:\Document\code\vue\greater_wms\.\container\serializers.py", line 180, in get_task_wcs
+    from wcs.serializers import TaskGetSerializer
+ModuleNotFoundError: No module named 'wcs'

+ 200 - 0
logs/server.log

@@ -2136,3 +2136,203 @@ UnboundLocalError: local variable 'data_return' referenced before assignment
 [2025-04-07 17:46:21,331][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
 [2025-04-08 10:35:46,701][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
 [2025-04-08 10:35:51,969][django.request.log_response():241] [WARNING] Not Found: /asn/detail/
+[2025-04-08 21:02:25,183][django.request.log_response():241] [WARNING] Not Found: /asn/detail/
+[2025-04-08 22:10:26,682][django.request.log_response():241] [WARNING] Not Found: /dn/list/
+[2025-04-08 22:10:28,277][django.request.log_response():241] [WARNING] Not Found: /goods/
+[2025-04-08 22:10:42,906][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-04-08 22:17:02,149][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-04-08 22:17:07,594][django.request.log_response():241] [WARNING] Not Found: /asn/detail/
+[2025-04-09 15:57:40,419][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 201, in get_container_wcs
+    generate_task(container, current_location, container_obj.target_location)
+NameError: name 'generate_task' is not defined
+[2025-04-09 16:05:39,930][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 197, in get_container_wcs
+    if current_location == str(container_obj.target_location.id):
+AttributeError: 'str' object has no attribute 'id'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 234, in get_container_wcs
+    logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
+NameError: name 'logger' is not defined
+[2025-04-09 16:07:08,036][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 198, in get_container_wcs
+    if current_location == str(container_obj.target_location.id):
+AttributeError: 'str' object has no attribute 'id'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 235, in get_container_wcs
+    logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
+NameError: name 'logger' is not defined
+[2025-04-09 16:09:03,176][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 199, in get_container_wcs
+    if current_location == str(container_obj.target_location.id):
+AttributeError: 'str' object has no attribute 'id'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\container\views.py", line 239, in get_container_wcs
+    status=status.HTTP_500_INTERNAL_SERVER_ERROR
+NameError: name 'status' is not defined
+[2025-04-09 16:11:10,421][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-09 16:12:01,800][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-09 16:12:40,458][django.request.log_response():241] [ERROR] Internal Server Error: /container/container_wcs/
+[2025-04-09 16:44:29,802][django.request.log_response():241] [WARNING] Bad Request: /container/container_wcs/
+[2025-04-09 17:00:03,451][django.request.log_response():241] [ERROR] Internal Server Error: /container/task/
+Traceback (most recent call last):
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "d:\language\python38\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "d:\language\python38\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 435, in __call__
+    ret = await asyncio.wait_for(future, timeout=None)
+  File "d:\language\python38\lib\asyncio\tasks.py", line 455, in wait_for
+    return await fut
+  File "d:\language\python38\lib\concurrent\futures\thread.py", line 57, in run
+    result = self.fn(*self.args, **self.kwargs)
+  File "d:\language\python38\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\language\python38\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "d:\language\python38\lib\site-packages\rest_framework\mixins.py", line 43, in list
+    return self.get_paginated_response(serializer.data)
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 768, in data
+    ret = super().data
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 253, in data
+    self._data = self.to_representation(self.instance)
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 686, in to_representation
+    return [
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 687, in <listcomp>
+    self.child.to_representation(item) for item in iterable
+  File "d:\language\python38\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
+    ret[field.field_name] = field.to_representation(attribute)
+  File "d:\language\python38\lib\site-packages\rest_framework\fields.py", line 1838, in to_representation
+    return method(value)
+  File "D:\Document\code\vue\greater_wms\.\container\serializers.py", line 180, in get_task_wcs
+    from wcs.serializers import TaskGetSerializer
+ModuleNotFoundError: No module named 'wcs'