flower_mr 2 주 전
부모
커밋
e67cf8795a

+ 20 - 0
bin/migrations/0003_alter_locationcontainerlink_container.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.2 on 2025-05-20 04:34
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('container', '0018_alter_containerwcsmodel_options'),
+        ('bin', '0002_devicemodel_mode_devicemodel_warehouse_code'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='locationcontainerlink',
+            name='container',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='location_links', to='container.containerlistmodel'),
+        ),
+    ]

+ 20 - 0
bin/migrations/0004_alter_locationcontainerlink_container.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.2 on 2025-05-20 05:21
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('container', '0018_alter_containerwcsmodel_options'),
+        ('bin', '0003_alter_locationcontainerlink_container'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='locationcontainerlink',
+            name='container',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='container.containerlistmodel'),
+        ),
+    ]

+ 20 - 0
bin/migrations/0005_alter_locationcontainerlink_container.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.2 on 2025-05-20 05:28
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('container', '0018_alter_containerwcsmodel_options'),
+        ('bin', '0004_alter_locationcontainerlink_container'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='locationcontainerlink',
+            name='container',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='location_links', to='container.containerlistmodel'),
+        ),
+    ]

+ 25 - 0
bin/migrations/0006_alter_locationcontainerlink_container_and_more.py

@@ -0,0 +1,25 @@
+# Generated by Django 4.1.2 on 2025-05-20 05:33
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('container', '0018_alter_containerwcsmodel_options'),
+        ('bin', '0005_alter_locationcontainerlink_container'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='locationcontainerlink',
+            name='container',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='location_links', to='container.containerlistmodel', verbose_name='关联容器'),
+        ),
+        migrations.AlterField(
+            model_name='locationcontainerlink',
+            name='location',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='container_links', to='bin.locationmodel', verbose_name='库位'),
+        ),
+    ]

+ 17 - 2
bin/models.py

@@ -863,8 +863,23 @@ class LocationGroupModel(models.Model):
         
 # 库位-托盘关联表(记录实时存放关系)
 class LocationContainerLink(models.Model):
-    location = models.ForeignKey(LocationModel, on_delete=models.CASCADE, verbose_name='库位')
-    container = models.ForeignKey(ContainerListModel,on_delete=models.CASCADE)
+    location = models.ForeignKey(
+            LocationModel, 
+            on_delete=models.CASCADE,
+            related_name='container_links',  # 关键修复点
+            verbose_name='库位'
+        )
+    
+    container = models.ForeignKey(
+        ContainerListModel,
+        on_delete=models.CASCADE,
+        related_name='location_links',   # 容器到链接的反向关联
+        verbose_name='关联容器'
+    )
+    task_wcs = models.ForeignKey(
+        ContainerWCSModel,
+        on_delete=models.CASCADE,
+    )
     task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True)
     task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True)
     put_time = models.DateTimeField(auto_now_add=True, verbose_name='上架时间')

+ 6 - 7
bin/views.py

@@ -61,14 +61,13 @@ class locationViewSet(viewsets.ModelViewSet):
             return None
     def get_queryset(self):
         id = self.get_project()
-        # 预取激活的关联托盘(通过中间模型过滤)
         prefetch_containers = Prefetch(
-            'current_containers',
-            queryset=ContainerListModel.objects.filter(
-                locationcontainerlink__is_active=True  # 确保中间模型字段名正确
-            ).distinct(),
-            to_attr='active_containers'  # 将结果存储到模型的 active_containers 属性
-        )
+        'container_links', 
+        queryset=LocationContainerLink.objects.filter(
+            is_active=True
+        ).select_related('container'),  # 加载关联的容器对象
+        to_attr='active_links'  # 新的属性名称
+    )
 
         if self.request.user:
             if id is None:

+ 35 - 1
bound/filter.py

@@ -1,5 +1,39 @@
 from django_filters import FilterSet
-from .models import BoundListModel, BoundDetailModel,BoundBatchModel,OutBatchModel,BatchLogModel,OutBoundDetailModel,MaterialStatistics
+from .models import BoundListModel, BoundDetailModel,BoundBatchModel,OutBatchModel,BatchLogModel,OutBoundDetailModel,MaterialStatistics,OutBoundDemandModel
+
+class OutBoundDemandFilter(FilterSet):
+    class Meta:
+        model = OutBoundDemandModel
+        fields = {
+            "id": ['exact', 'gt', 'gte', 'lt', 'lte', 'isnull', 'in', 'range'],
+            'goods_code': ['exact', 'icontains'],
+            'goods_desc': ['exact', 'icontains'],
+            'goods_std': ['exact', 'icontains'],
+            'goods_unit': ['exact', 'icontains'],
+            'goods_qty': ['exact', 'gt', 'gte', 'lt', 'lte', 'range'],
+            'working': ['exact'],
+            'creater': ['exact', 'icontains'],
+            'create_time': ['exact', 'gt', 'gte', 'lt', 'lte',
+             'year', 'year__gt', 'year__gte', 'year__lt', 'year__lte', 'year__range', 'year__in', 
+             'month','month__gt','month__gte','month__lt','month__lte','month__range','month__in', 
+             'day', 'day__gt', 'day__gte', 'day__lt', 'day__lte', 'day__range', 'day__in',
+              'week_day', 'week_day__gt', 'week_day__gte', 'week_day__lt', 'week_day__lte', 'week_day__range', 'week_day__in', 
+              'hour', 'hour__gt', 'hour__gte', 'hour__lt', 'hour__lte', 'hour__range', 'hour__in',
+
+              'date', 'date__gt', 'date__gte', 'date__lt', 'date__lte', 'date__range', 'date__in', 
+              'time', 'time__gt', 'time__gte', 'time__lt', 'time__lte', 'time__range', 'time__in', 'isnull', 'in', 'range'],
+            'update_time':
+             ['exact', 'gt', 'gte', 'lt', 'lte',
+             'year', 'year__gt', 'year__gte', 'year__lt', 'year__lte', 'year__range', 'year__in', 
+             'month','month__gt','month__gte','month__lt','month__lte','month__range','month__in', 
+             'day', 'day__gt', 'day__gte', 'day__lt', 'day__lte', 'day__range', 'day__in',
+              'week_day', 'week_day__gt', 'week_day__gte', 'week_day__lt', 'week_day__lte', 'week_day__range', 'week_day__in', 
+              'hour', 'hour__gt', 'hour__gte', 'hour__lt', 'hour__lte', 'hour__range', 'hour__in',
+
+              'date', 'date__gt', 'date__gte', 'date__lt', 'date__lte', 'date__range', 'date__in', 
+              'time', 'time__gt', 'time__gte', 'time__lt', 'time__lte', 'time__range', 'time__in', 'isnull', 'in', 'range'],
+            'is_delete': ['exact'],
+        }
 
 class MaterialStatisticsFilter(FilterSet):
     class Meta:

+ 42 - 0
bound/migrations/0016_materialstatistics_total_demanded_quantity_and_more.py

@@ -0,0 +1,42 @@
+# Generated by Django 4.1.2 on 2025-05-19 21:37
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bound', '0015_rename_goods_out_location_qty_boundbatchmodel_goods_actual_qty'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='materialstatistics',
+            name='total_demanded_quantity',
+            field=models.BigIntegerField(default=0, verbose_name='需求数量'),
+        ),
+        migrations.CreateModel(
+            name='OutBoundDemandModel',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('goods_code', models.CharField(max_length=255, verbose_name='商品编码')),
+                ('goods_desc', models.CharField(max_length=255, verbose_name='商品描述')),
+                ('goods_std', models.CharField(blank=True, default='待填写', max_length=255, null=True, verbose_name='商品标准')),
+                ('goods_unit', models.CharField(default='待填写', max_length=255, verbose_name='商品单位')),
+                ('goods_qty', models.BigIntegerField(default=0, verbose_name='计划数量')),
+                ('working', models.BooleanField(default=False, verbose_name='是否在工作')),
+                ('creater', models.CharField(default='uesr', max_length=255, verbose_name='Who Created')),
+                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='Create Time')),
+                ('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='Update Time')),
+                ('is_delete', models.BooleanField(default=False, verbose_name='Delete Label')),
+                ('bound_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='out_demand', to='bound.boundlistmodel', verbose_name='Bound List')),
+            ],
+            options={
+                'verbose_name': '出库需求',
+                'verbose_name_plural': '出库需求',
+                'db_table': 'outbounddemand',
+                'ordering': ['-id'],
+            },
+        ),
+    ]

+ 18 - 0
bound/migrations/0017_outbounddemandmodel_out_type.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2025-05-19 22:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bound', '0016_materialstatistics_total_demanded_quantity_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='outbounddemandmodel',
+            name='out_type',
+            field=models.IntegerField(choices=[(0, '发货出库'), (4, '其他出库')], default=4, verbose_name='出库类型'),
+        ),
+    ]

+ 19 - 0
bound/migrations/0018_outbatchmodel_bound_list.py

@@ -0,0 +1,19 @@
+# Generated by Django 4.1.2 on 2025-05-20 02:28
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bound', '0017_outbounddemandmodel_out_type'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='outbatchmodel',
+            name='bound_list',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='out_batch_list', to='bound.boundlistmodel', verbose_name='Bound List'),
+        ),
+    ]

+ 55 - 0
bound/models.py

@@ -102,12 +102,37 @@ class BoundBatchModel(models.Model):
         self.goods_actual_qty = self.goods_in_location_qty
         super().save(*args, **kwargs)
 
+class OutBoundDemandModel(models.Model):
+    OUT_TYPE = (
+        (0, '发货出库'),
+        (4, '其他出库'),
+    )
+    bound_list = models.ForeignKey(BoundListModel, on_delete=models.CASCADE, verbose_name="Bound List", related_name='out_demand')
+    goods_code = models.CharField(max_length=255, verbose_name="商品编码")
+    goods_desc = models.CharField(max_length=255, verbose_name="商品描述")
+    goods_std = models.CharField(default='待填写', max_length=255, verbose_name="商品标准",blank=True, null=True)
+    goods_unit = models.CharField(default='待填写', max_length=255, verbose_name="商品单位")
+    goods_qty = models.BigIntegerField(default=0, verbose_name="计划数量")
+    working = models.BooleanField(default=False, verbose_name="是否在工作")
+    creater = models.CharField(default='uesr', max_length=255, verbose_name="Who Created")
+    create_time = models.DateTimeField(auto_now_add=True, verbose_name="Create Time")
+    update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time")
+    is_delete = models.BooleanField(default=False, verbose_name='Delete Label')
+    out_type = models.IntegerField(choices=OUT_TYPE, default=4,  verbose_name="出库类型")
+
+    class Meta:
+        db_table = 'outbounddemand'
+        verbose_name = '出库需求'
+        verbose_name_plural = "出库需求"
+        ordering = ['-id']
+
 class MaterialStatistics(models.Model):
     goods_code = models.CharField(max_length=255, verbose_name="商品编码", unique=True)
     goods_desc = models.CharField(max_length=255, verbose_name="商品描述")
     goods_std = models.CharField(default='待填写', max_length=255, verbose_name="商品标准", blank=True, null=True)
     goods_unit = models.CharField(default='待填写', max_length=255, verbose_name="商品单位")
     total_quantity = models.BigIntegerField(default=0, verbose_name="计划数量")
+    total_demanded_quantity = models.BigIntegerField(default=0, verbose_name="需求数量")
 
     def __str__(self):
         return f"{self.goods_code} - {self.goods_desc}"
@@ -149,6 +174,32 @@ def update_material_statistics(sender, instance, **kwargs):
     stats.total_quantity = total
     stats.save()
 
+@receiver([post_save, post_delete], sender=OutBoundDemandModel)
+def update_material_demanded(sender, instance, **kwargs):
+    goods_code = instance.goods_code
+    stats, created = MaterialStatistics.objects.get_or_create(
+        goods_code=goods_code,
+        defaults={
+            'goods_desc': instance.goods_desc,
+            'goods_std': instance.goods_std or '待填写',
+            'goods_unit': instance.goods_unit or '待填写',
+        }
+    )
+    
+    # 更新物料信息为最新批次的信息(可选)
+    stats.goods_desc = instance.goods_desc
+    if instance.goods_std and instance.goods_std != '待填写':
+        stats.goods_std = instance.goods_std
+    if instance.goods_unit and instance.goods_unit != '待填写':
+        stats.goods_unit = instance.goods_unit
+    stats.save()
+
+    # 计算总数量
+    total = OutBoundDemandModel.objects.filter(goods_code=goods_code,working=True).aggregate(
+        total=Sum('goods_qty')
+    )['total'] or 0
+    stats.total_demanded_quantity = total
+    stats.save()
 
 class OutBatchModel(models.Model):
     CONTAINER_STATUS = (
@@ -160,6 +211,8 @@ class OutBatchModel(models.Model):
         (0, '发货出库'),
         (4, '其他出库'),
     )
+    bound_list = models.ForeignKey(BoundListModel, on_delete=models.CASCADE, verbose_name="Bound List", related_name='out_batch_list',blank=True, null=True)
+
     out_number = models.CharField(max_length=255, verbose_name="出库批次号",blank=False, null=False)
 
     batch_number = models.ForeignKey(BoundBatchModel, on_delete=models.CASCADE, verbose_name="批次号", related_name='out_batch')
@@ -198,6 +251,8 @@ class OutBatchModel(models.Model):
         verbose_name_plural = "Out Batch"
         ordering = ['-id']
 
+
+
 # 利用创建好的批次来与申请单相对应       
 class OutBoundDetailModel(models.Model):
     CONTAINER_STATUS = (

+ 13 - 1
bound/serializers.py

@@ -1,8 +1,14 @@
 from rest_framework import serializers
-from .models import BoundListModel, BoundDetailModel, BoundBatchModel,OutBatchModel,BatchLogModel,OutBoundDetailModel,MaterialStatistics
+from .models import BoundListModel, BoundDetailModel, BoundBatchModel,OutBatchModel,BatchLogModel,OutBoundDetailModel,MaterialStatistics,OutBoundDemandModel
 from utils import datasolve
 
+class OutBoundDemandModelSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = OutBoundDemandModel
+        fields = '__all__'
+        read_only_fields = ['id', 'create_time', 'update_time']
 
+            
     
 class BoundListGetSerializer(serializers.ModelSerializer):
     # 定义主单列表的序列化器,用于获取操作,字段只读
@@ -206,11 +212,17 @@ class BoundDetailPostSerializer(serializers.ModelSerializer):
         }
 
 class OutBatchGetSerializer(serializers.ModelSerializer):
+    batch_number = serializers.SerializerMethodField()
     class Meta:
         model = OutBatchModel
         fields = '__all__'
         read_only_fields = ['id', 'openid']
+    def get_batch_number(self, obj):
+        from .serializers import BoundBatchGetSerializer
+        return BoundBatchGetSerializer(obj.batch_number).data
+    
 class OutBatchPostSerializer(serializers.ModelSerializer):
+
     out_number = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate]) 
     out_type = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate]) 
     out_note = serializers.CharField(read_only=False, required=False, validators=[datasolve.data_validate]) 

+ 5 - 0
bound/urls.py

@@ -44,6 +44,11 @@ re_path(r'^batch/(?P<pk>\d+)/$', views.BoundBatchViewSet.as_view({
     'delete': 'destroy',
 }), name="boundbatch_1"),
 
+path(r'outdemand/', views.OutBoundDemandViewSet.as_view({"put": "batch_list", "post": "create", "get": "list" }), name="outboundbatchcontainer"), 
+path(r'batchdemand/', views.OutBoundDemandViewSet.as_view({ "post": "distribute", "put": "batch_demanded_list" }), name="outboundbatchcontainer"), 
+
+
+
 path(r'outbatch/', views.OutBoundBatchViewSet.as_view({"get": "list", "post": "create" }), name="outboundbatch"), 
 
 re_path(r'^outbatch/(?P<pk>\d+)/$', views.OutBoundBatchViewSet.as_view({

+ 303 - 3
bound/views.py

@@ -4,26 +4,326 @@ from utils.datasolve import sumOfList, transportation_calculate
 from utils.md5 import Md5
 from rest_framework.filters import OrderingFilter
 from django_filters.rest_framework import DjangoFilterBackend
-
+from django.db import transaction
 from rest_framework.response import Response
 from rest_framework.exceptions import APIException
 from django.utils import timezone
-
-from .models import BoundListModel, BoundDetailModel,BoundBatchModel, BatchLogModel, OutBatchModel,OutBoundDetailModel,MaterialStatistics
+from django.db.models import Sum
+from .models import BoundListModel, BoundDetailModel,BoundBatchModel, BatchLogModel, OutBatchModel,OutBoundDetailModel,MaterialStatistics,OutBoundDemandModel
 # from .files import FileListRenderCN, FileDetailRenderCN
 
 from .serializers import BoundListGetSerializer,BoundListPostSerializer,BoundBatchGetSerializer,BoundBatchPostSerializer,BoundDetailGetSerializer,BoundDetailPostSerializer
 from .serializers import OutBoundDetailGetSerializer,OutBoundDetailPostSerializer,OutBatchGetSerializer,OutBatchPostSerializer,BatchLogGetSerializer
 from .serializers import MaterialStatisticsSerializer,MaterialStatisticsSerializer_items
+from .serializers import OutBoundDemandModelSerializer
 from .filter import BoundListFilter, BoundDetailFilter,BoundBatchFilter
 from .filter import OutBatchFilter,OutBoundDetailFilter,BatchlogFilter
 from .filter import MaterialStatisticsFilter
+from .filter import OutBoundDemandFilter
 # 以后添加模块检验
 from warehouse.models import ListModel as warehouse
 from staff.models import ListModel as staff
 from rest_framework.permissions import AllowAny
 from rest_framework.views import APIView
 
+class OutBoundDemandViewSet(viewsets.ModelViewSet):
+    """
+        retrieve:
+            Response a data list(get)
+        list:
+            Response a data list(all)
+        create:
+            Create a data line(post)
+
+        delete:
+            Delete a data line(delete)
+
+    """
+    # authentication_classes = []  # 禁用所有认证类
+    # permission_classes = [AllowAny]  # 允许任意访问
+    
+    pagination_class = MyPageNumberPagination
+    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
+    ordering_fields = ['id', "create_time", "update_time", ]
+    filter_class = OutBoundDemandFilter
+    def get_project(self):
+        try:
+            id = self.kwargs.get('pk')
+            return id
+        except:
+            return None
+
+    def get_queryset(self):
+        id = self.get_project()
+        if self.request.user:
+            if id is None:
+                return OutBoundDemandModel.objects.filter( is_delete=False)
+            else:
+                return OutBoundDemandModel.objects.filter( id=id, is_delete=False)
+        else:
+            return OutBoundDemandModel.objects.none()
+
+    def get_serializer_class(self):
+        if self.action in ['list' ]:
+            return OutBoundDemandModelSerializer
+        else:
+            return OutBoundDemandModelSerializer
+    
+    def batch_list(self, request):
+        data =self.request.data
+        OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+        data = OutBoundDemandModelSerializer(OutBoundDemand_all, many=True).data
+        return_data ={
+                "code": 200,
+                "msg": "Success Create",
+            	"data": data
+        }
+    
+        return Response(return_data,status=200,headers={})
+
+  
+    def create(self, request, *args, **kwargs):
+        data = self.request.data
+
+        data['openid'] = self.request.auth.openid
+        data['create_time'] = str(timezone.now().strftime('%Y-%m-%d %H:%M:%S'))
+        data['update_time'] = str(timezone.now().strftime('%Y-%m-%d %H:%M:%S'))
+        data['working'] = True
+        bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+
+        OutBoundDemand_obj =OutBoundDemandModel.objects.create(
+            bound_list=bound_list_obj, 
+            goods_code=data['goods_code'], 
+            goods_desc=data['goods_desc'], 
+            goods_std=data['goods_std'], 
+            goods_unit=data['goods_unit'], 
+            goods_qty=data['goods_out_qty'],
+            out_type = data['out_type'],
+            creater=data['creater'], 
+            create_time=data['create_time'],
+            update_time=data['update_time'], 
+            working=data['working']
+            )
+        return_data = OutBoundDemandModelSerializer(OutBoundDemand_obj).data
+        headers = self.get_success_headers(return_data)
+
+        return Response(return_data, status=200, headers=headers)
+    
+    def batch_demanded_list(self, request):
+        data =self.request.data
+        OutBoundDemand_all = OutBatchModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+        data = OutBatchGetSerializer(OutBoundDemand_all, many=True).data
+        return_data = {
+            "code": 200,
+            "msg": "Success Create",
+            "data": data
+        }
+
+        return Response(return_data,status=200,headers={})
+
+    def distribute(self, request):
+        """主分配入口"""
+        try:
+            with transaction.atomic():
+                bound_list_id, demands,out_type, creater= self.validate_distribute_request(request)
+
+                if OutBatchModel.objects.filter(bound_list_id=bound_list_id, is_delete=False).exists():
+                    return_data = {
+                        "code": 200,
+                        "msg": "Success Create",
+                        "data": {
+                            "msg": "该订单已分配,请勿重复分配"
+                        }
+                    }
+                    return Response(return_data, status=200, headers={})
+                aggregated_demands = self.aggregate_demands(demands)
+                result = self.process_all_goods(aggregated_demands, request, out_type, creater,bound_list_id)
+                return self.build_success_response(result)
+        except APIException as e:
+            return self.build_error_response(e.detail, 200)
+        except Exception as e:
+            return self.build_error_response(str(e), 200)
+
+    # 验证层方法
+    def validate_distribute_request(self, request):
+        """验证请求参数"""
+        bound_list_id = request.data.get('bound_list_id')
+        if not bound_list_id:
+            raise APIException({"detail": "Missing bound_list_id"})
+
+        demands = OutBoundDemandModel.objects.filter(
+            bound_list_id=bound_list_id,
+            is_delete=False
+        )
+        if not demands.exists():
+            raise APIException({"detail": "No demands found"})
+        base_info = OutBoundDemandModel.objects.filter(
+            bound_list_id=bound_list_id,
+            is_delete=False
+        ).first()
+        out_type = base_info.out_type
+        creater = base_info.creater
+
+        return bound_list_id, demands, out_type, creater
+
+    # 数据处理层方法
+    def aggregate_demands(self, demands):
+        """合并相同物料需求"""
+        return demands.values('goods_code').annotate(
+            total_demand=Sum('goods_qty')
+        )
+
+    # 核心分配逻辑
+    def process_all_goods(self, aggregated_demands, request, out_type, creater,bound_list_id):
+        """处理所有物料分配"""
+        return [
+            self.process_single_goods(
+                goods_code=item['goods_code'],
+                total_demand=item['total_demand'],
+                request=request,
+                out_type=out_type,
+                creater=creater,
+                bound_list_id=bound_list_id
+
+            )
+            for item in aggregated_demands
+        ]
+
+    def process_single_goods(self, goods_code, total_demand, request,out_type, creater,bound_list_id):
+        """处理单个物料分配"""
+        batches = self.get_available_batches(goods_code)
+        remaining, allocations = self.allocate_batches(total_demand, batches, request,out_type, creater,bound_list_id)
+        
+        if remaining > 0:
+            raise APIException({
+                "detail": f"Insufficient stock for {goods_code}",
+                "required": total_demand,
+                "allocated": total_demand - remaining
+            })
+        
+        return {
+            "goods_code": goods_code,
+            "total_demand": total_demand,
+            "allocations": allocations
+        }
+
+    def get_available_batches(self, goods_code):
+        """获取可用入库批次"""
+        return BoundBatchModel.objects.filter(
+            goods_code=goods_code,
+            is_delete=False
+        ).order_by('bound_batch_order')
+
+    # 批次分配逻辑
+    def allocate_batches(self, total_demand, batches, request,out_type, creater,bound_list_id):
+        """分配具体批次"""
+        remaining = total_demand
+        allocations = []
+        
+        for batch in batches:
+            if remaining <= 0:
+                break
+            
+            allocated = self.allocate_single_batch(
+                batch=batch,
+                remaining=remaining,
+                request=request,
+                out_type=out_type,
+                creater=creater,
+                bound_list_id=bound_list_id
+
+            )
+            
+            if allocated == 0:
+                continue
+                
+            allocations.append(allocated)
+            remaining -= allocated['allocated']
+        
+        return remaining, allocations
+
+    def allocate_single_batch(self, batch, remaining, request,out_type, creater,bound_list_id):
+        """单个批次分配逻辑"""
+        available = batch.goods_in_location_qty - batch.goods_out_qty
+        if available <= 0:
+            return 0
+
+        allocate_qty = min(remaining, available)
+        self.update_batch_status(batch, allocate_qty)
+        out_batch = self.create_out_batch(batch, allocate_qty, request,out_type, creater,bound_list_id)
+        
+        return {
+            "batch": batch.bound_number,
+            "allocated": allocate_qty,
+            "out_batch": out_batch.out_number
+        }
+
+    # 数据操作层方法
+    def update_batch_status(self, batch, allocate_qty):
+        """更新批次状态和数量"""
+        batch.goods_out_qty += allocate_qty
+        
+        if batch.goods_out_qty == batch.goods_in_location_qty:
+            batch.status = 6  # 已出库
+        elif batch.goods_out_qty > 0:
+            batch.status = 5  # 部分出库
+            
+        batch.save()
+
+    def create_out_batch(self, batch, allocate_qty, request,out_type, creater,bound_list_id):
+        """创建出库记录"""
+        out_data = {
+            'bound_list': bound_list_id,
+            'out_number': self.generate_out_number(batch.goods_code),
+            'batch_number': batch.id,
+            'out_date': timezone.now(),
+            'warehouse_code': batch.warehouse_code,
+            'warehouse_name': batch.warehouse_name,
+            'goods_code': batch.goods_code,
+            'goods_desc': batch.goods_desc,
+            'goods_out_qty': allocate_qty,
+            'status': 0,
+            'openid': request.auth.openid,
+            'out_type': out_type,
+            'creater': creater,
+
+
+        }
+        
+        serializer = OutBatchPostSerializer(data=out_data)
+        if not serializer.is_valid():
+            raise APIException({
+                "detail": f"Serialization error for {batch.goods_code}",
+                "errors": serializer.errors
+            })
+            
+        return serializer.save()
+
+    # 工具方法
+    def generate_out_number(self, goods_code):
+        """生成唯一出库单号"""
+        timestamp = timezone.now().strftime("%Y%m%d%H%M%S")
+        import uuid
+
+        return f"OUT-{goods_code}-{timestamp}-{uuid.uuid4().hex[:6]}"
+
+    def build_success_response(self, data):
+        """构建成功响应"""
+        return Response({
+            "code": 200,
+            "msg": "Distribution completed",
+            "data": data
+        })
+
+    def build_error_response(self, error, status_code):
+        """构建错误响应"""
+        return Response({
+            "code": status_code,
+            "msg": "Distribution failed" if status_code == 400 else "Server error",
+            "error": error
+        }, status=status_code)
+
+
 class MaterialStatisticsViewSet(viewsets.ModelViewSet):
     """
         retrieve:

+ 157 - 53
container/views.py

@@ -2,10 +2,11 @@ from wsgiref import headers
 from rest_framework.views import APIView
 from rest_framework import viewsets
 from utils.page import MyPageNumberPagination
-
+from django.db.models import Prefetch 
 from rest_framework.filters import OrderingFilter
 from django_filters.rest_framework import DjangoFilterBackend
 from rest_framework.response import Response
+from django.db.models import F, Case, When
 
 from django.utils import timezone
 import requests
@@ -14,10 +15,10 @@ 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,OutBoundDetailModel
+from bound.models import BoundDetailModel,BoundListModel,OutBoundDetailModel
 from bin.views import LocationAllocation,base_location
 from bin.models import LocationModel,LocationContainerLink,LocationGroupModel
-from bound.models import BoundBatchModel
+from bound.models import BoundBatchModel,OutBatchModel,BatchLogModel
 
 from .serializers import ContainerDetailGetSerializer,ContainerDetailPostSerializer
 from .serializers import ContainerListGetSerializer,ContainerListPostSerializer
@@ -30,6 +31,7 @@ from rest_framework.permissions import AllowAny
 import threading
 from django.db import close_old_connections
 from bin.services import AllocationService
+
 logger = logging.getLogger(__name__)
 class ContainerListViewSet(viewsets.ModelViewSet):
     """
@@ -1189,21 +1191,34 @@ class OutTaskViewSet(APIView):
             
             # 假设从请求中获取 bound_list_id
             bound_list_id = data.get('bound_list_id')
-            batch_count = self.get_batch_count_by_boundlist(bound_list_id)
+            # 获取关联的出库批次
+            out_batches = OutBatchModel.objects.filter(
+                bound_list_id=bound_list_id,
+                is_delete=False
+            ).select_related('batch_number')
+            
+            if not out_batches.exists():
+                return Response({"code": "404", "msg": "未找到相关出库批次"}, status=404)
+             # 构建批次需求字典
+            batch_demand = {
+                ob.batch_number_id: {
+                    'required': ob.goods_out_qty,
+                    'allocated': ob.goods_qty,
+                    'remaining': ob.goods_out_qty 
+                } for ob in out_batches
+            }
+            
+            # 生成出库任务
+            generate_result = self.generate_location_by_demand(
+                batch_demand=batch_demand,
+                bound_list_id=bound_list_id
+            )
             
-            logger.info(f"出库批次数量: {batch_count}")
-            # 获取需要出库的托盘列表
-            generate_result = self.generate_location_by_demand(batch_count,bound_list_id)
             if generate_result['code'] != '200':
-                current_WCS = ContainerWCSModel.objects.filter(tasktype='outbound',bound_list_id = bound_list_id).first()
-                if current_WCS:
-                    OutboundService.process_next_task()
-                    return Response({"code": "200", "msg": "Success 再次发送任务"}, status=200)
-
                 return Response(generate_result, status=500)
-            container_list = generate_result['data']
             
-            logger.info(f"生成出库任务: {container_list}")
+            # 创建并处理出库任务
+            container_list = generate_result['data']
 
             #  2. 生成初始任务
             OutboundService.create_initial_tasks(container_list,bound_list_id)
@@ -1289,51 +1304,140 @@ class OutTaskViewSet(APIView):
             logger.error(f"查询{status}状态的批次数量失败: {str(e)}")
             return {}
 
-    def generate_location_by_demand(self,demand_list,bound_list_id):
-        # demand_list {1: 25, 2: 17}
+    def get_container_allocation(self, batch_id):
+        """兼容所有数据库的去重方案"""
+        # 获取唯一容器ID列表
+        container_ids = (
+            ContainerDetailModel.objects
+            .filter(batch_id=batch_id, status=2)
+            .values_list('container_id', flat=True)
+            .distinct()
+        )
+
+        # 获取每个容器的最新明细(按id倒序)
+        return (
+            ContainerDetailModel.objects
+            .filter(container_id__in=container_ids, status=2)
+            .select_related('container')
+            .prefetch_related(
+                Prefetch('container__location_links', 
+                        queryset=LocationContainerLink.objects.select_related('location'),
+                        to_attr='active_location')
+            )
+            .order_by('container_id', '-id')
+        )
+        
+    def generate_location_by_demand(self, batch_demand, bound_list_id):
         try:
-            return_location =[]
-            for demand_id, demand_qty in demand_list.items():
-                container_list = self.get_location_by_status_and_batch(2, demand_id)
-                if not container_list:
-
-                    return {"code": "500", "msg": f"批次 {demand_id} 不存在"}
-                container_id_list = container_list.keys()
-                container_order = self.get_order_by_batch(container_id_list,demand_id) 
-                if not container_order:
-                    return {"code": "500", "msg": f"托盘 {container_id_list} 不存在"}
-                order = sorted(
-                        container_order.values(),
-                        key=lambda x: (
-                            int(x['location_type'][-1]),  # 提取最后一位数字并转为整数
-                            -x['location_c_number']       # 按location_c_number降序
-                        )
+            return_data = []
+            
+            for batch_id, demand in batch_demand.items():
+                # 获取已去重的容器列表
+                container_qs = self.get_container_allocation(batch_id)
+                
+                # 构建容器信息字典(自动去重)
+                container_map = {}
+                for cd in container_qs:
+                    if cd.container_id in container_map:
+                        continue  # 跳过已处理容器
+                    
+                    # 获取有效库位信息
+                    active_location = next(
+                        (link.location for link in cd.container.active_location 
+                        if link.is_active),
+                        None
                     )
-                current_qty = 0
-                for container in order:
-   
-                    container_detail_obj = ContainerDetailModel.objects.filter(container_id=container['container_number'],batch_id=demand_id,status=2).all()
-                    container_obj = ContainerListModel.objects.filter(id=container['container_number']).first()
-                    if not container_obj:
-                        return {"code": "500", "msg": f"托盘 {container['container_number']} 不存在"}
-                    if not container_detail_obj:
-                        return {"code": "500", "msg": f"托盘上无该批次,请检查{container['container_number']} 不存在"}
-                    goods_qty = 0 
-                    for obj in container_detail_obj:
-                        goods_qty += obj.goods_qty
-                    if current_qty < demand_qty:
-                        now_qty = current_qty
-                        current_qty += goods_qty
-                        return_location.append(container)
-                        logger.info(f"批次 {demand_id} 托盘 {container['container_number']} 当前数量 {current_qty}")
-                        self.create_or_update_container_operation(container_obj,demand_id,bound_list_id,203,min(demand_qty-now_qty,goods_qty),min(demand_qty-now_qty,goods_qty))
-                        self.update_container_detail_out_qty(container_obj,demand_id)
-                    else:
+                    
+                    container_map[cd.container_id] = {
+                        'detail': cd,
+                        'container': cd.container,
+                        'location': active_location
+                    }
+
+                # 转换为排序列表
+                container_list = list(container_map.values())
+                
+                # 多维度排序(优化性能版)
+                sorted_containers = sorted(
+                    container_list,
+                    key=lambda x: (
+                        self._get_goods_class_priority(x['detail'].goods_class),
+                        -(x['location'].c_number if x['location'] else 0),
+                        x['location'].warehouse_code if x['location'] else '',
+                        -(x['location'].layer if x['location'] else 0),
+                        x['location'].row if x['location'] else 0,
+                        x['location'].col if x['location'] else 0
+                    )
+                )
+                
+                # 分配逻辑
+                remaining = demand['remaining']
+                for item in sorted_containers:
+                    if remaining <= 0:
                         break
-            return {"code": "200", "msg": "Success", "data": return_location}
+                    
+                    # 获取可分配数量
+                    allocatable = item['detail'].goods_qty - item['detail'].goods_out_qty
+                    allocate_qty = min(remaining, allocatable)
+                    
+                    # 记录分配信息
+                    return_data.append({
+                        "container_number": item['container'].id,
+                        "batch_id": batch_id,
+                        "location_code": item['location'].location_code if item['location'] else 'N/A',
+                        "allocate_qty": allocate_qty,
+                        "c_number": item['location'].c_number if item['location'] else 0
+                    })
+                    
+                    remaining -= allocate_qty
+                    # 更新数据库状态(需要事务处理)
+                    self._update_allocation_status(item, allocate_qty)
+                    
+            return {"code": "200", "msg": "Success", "data": return_data}
+            
         except Exception as e:
+            logger.error(f"出库任务生成失败: {str(e)}", exc_info=True)
             return {"code": "500", "msg": str(e)}
+    
+    def _get_goods_class_priority(self, goods_class):
+        """货物类型优先级权重"""
+        return {
+            3: 0,  # 散盘最高
+            1: 1,  # 成品次之
+            2: 2   # 空盘最低
+        }.get(goods_class, 99)
 
+    @transaction.atomic
+    def _update_allocation_status(self, item, allocate_qty):
+        """事务化更新分配状态"""
+        try:
+            # 更新容器明细
+            ContainerDetailModel.objects.filter(
+                id=item['detail'].id
+            ).update(
+                goods_out_qty=F('goods_out_qty') + allocate_qty,
+                status=Case(
+                    When(goods_qty=F('goods_out_qty') + allocate_qty, then=3),
+                    default=2
+                )
+            )
+            
+            # 更新库位状态
+            if item['location']:
+                LocationModel.objects.filter(
+                    id=item['location'].id
+                ).update(
+                    current_quantity=F('current_quantity') - allocate_qty,
+                    status=Case(
+                        When(current_quantity=F('current_quantity') - allocate_qty, then='available'),
+                        default='occupied'
+                    )
+                )
+                
+            return True
+        except Exception as e:
+            logger.error(f"状态更新失败: {str(e)}")
+            return False
     def create_or_update_container_operation(self,container_obj,batch_id,bound_id,to_location,goods_qty,goods_weight):
         try:
             container_operation_obj = ContainerOperationModel.objects.filter(container=container_obj,batch_id=batch_id,bound_id=bound_id,operation_type="outbound").first()

+ 499 - 0
logs/error.log

@@ -8207,3 +8207,502 @@ Traceback (most recent call last):
   File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\serializers.py", line 1106, in get_field_names
     raise TypeError(
 TypeError: The `fields` option must be a list or tuple or "__all__". Got str.
+[2025-05-19 22:07:59,766][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 117, in view
+    handler = getattr(self, action)
+AttributeError: 'OutBoundDemandViewSet' object has no attribute 'fliter_list'
+[2025-05-19 22:08:52,989][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 117, in view
+    handler = getattr(self, action)
+AttributeError: 'OutBoundDemandViewSet' object has no attribute 'fliter_list'
+[2025-05-20 01:22:58,510][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 101, in create
+    out_type = data['out_type'],
+KeyError: 'out_type'
+[2025-05-20 01:26:18,883][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 74, in batch_list
+    OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+KeyError: 'bound_list_id'
+[2025-05-20 01:26:41,806][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 92, in create
+    bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+KeyError: 'bound_list_id'
+[2025-05-20 01:27:13,206][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 92, in create
+    bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+KeyError: 'bound_list_id'
+[2025-05-20 01:28:00,224][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 74, in batch_list
+    OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+KeyError: 'bound_list_id'
+[2025-05-20 01:28:05,446][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 92, in create
+    bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+KeyError: 'bound_list_id'
+[2025-05-20 01:28:42,370][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 74, in batch_list
+    OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+KeyError: 'bound_list_id'
+[2025-05-20 02:15:47,629][django.request.log_response():241] [ERROR] Internal Server Error: /bound/batchdemand/
+[2025-05-20 04:00:07,323][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:28:33,924][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:28:33,927][django.server.log_message():187] [ERROR] "POST /container/out_task/ HTTP/1.1" 500 83
+[2025-05-20 04:30:34,459][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:30:34,460][django.server.log_message():187] [ERROR] "POST /container/out_task/ HTTP/1.1" 500 186
+[2025-05-20 04:34:12,113][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:35:21,771][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 05:19:13,116][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
+    response = get_response(request)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:19:13,121][django.server.log_message():187] [ERROR] "GET /bin/?layer=1&warehouse_code=W01&max_page=1000&shelf_name=A%E5%8C%BA%E8%B4%A7%E6%9E%B6 HTTP/1.1" 500 162131
+[2025-05-20 05:19:21,555][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
+    response = get_response(request)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:19:21,558][django.server.log_message():187] [ERROR] "GET /bin/?layer=1&warehouse_code=W01&max_page=1000&shelf_name=A%E5%8C%BA%E8%B4%A7%E6%9E%B6 HTTP/1.1" 500 162131
+[2025-05-20 05:20:53,012][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\.\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:22:42,740][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 05:28:13,804][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\.\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:31:10,853][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 40, in list
+    page = self.paginate_queryset(queryset)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\generics.py", line 171, in paginate_queryset
+    return self.paginator.paginate_queryset(queryset, self.request, view=self)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\pagination.py", line 216, in paginate_queryset
+    return list(self.page)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\paginator.py", line 177, in __len__
+    return len(self.object_list)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 376, in __len__
+    self._fetch_all()
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1868, in _fetch_all
+    self._prefetch_related_objects()
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1257, in _prefetch_related_objects
+    prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 2272, in prefetch_related_objects
+    raise AttributeError(
+AttributeError: Cannot find 'container_links' on LocationModel object, 'container_links' is an invalid parameter to prefetch_related()

+ 588 - 0
logs/server.log

@@ -23849,3 +23849,591 @@ Traceback (most recent call last):
   File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\serializers.py", line 1106, in get_field_names
     raise TypeError(
 TypeError: The `fields` option must be a list or tuple or "__all__". Got str.
+[2025-05-19 22:07:59,766][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 117, in view
+    handler = getattr(self, action)
+AttributeError: 'OutBoundDemandViewSet' object has no attribute 'fliter_list'
+[2025-05-19 22:08:52,989][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 117, in view
+    handler = getattr(self, action)
+AttributeError: 'OutBoundDemandViewSet' object has no attribute 'fliter_list'
+[2025-05-20 00:35:22,116][django.request.log_response():241] [WARNING] Not Found: //bound/batch/count/
+[2025-05-20 01:22:58,510][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 101, in create
+    out_type = data['out_type'],
+KeyError: 'out_type'
+[2025-05-20 01:26:18,854][django.request.log_response():241] [WARNING] Not Found: /bound/list/undefined/
+[2025-05-20 01:26:18,883][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 74, in batch_list
+    OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+KeyError: 'bound_list_id'
+[2025-05-20 01:26:41,806][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 92, in create
+    bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+KeyError: 'bound_list_id'
+[2025-05-20 01:27:13,206][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 92, in create
+    bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+KeyError: 'bound_list_id'
+[2025-05-20 01:28:00,151][django.request.log_response():241] [WARNING] Not Found: /bound/list/undefined/
+[2025-05-20 01:28:00,224][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 74, in batch_list
+    OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+KeyError: 'bound_list_id'
+[2025-05-20 01:28:05,446][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 92, in create
+    bound_list_obj = BoundListModel.objects.get(id=data['bound_list_id'])
+KeyError: 'bound_list_id'
+[2025-05-20 01:28:42,321][django.request.log_response():241] [WARNING] Not Found: /bound/list/undefined/
+[2025-05-20 01:28:42,370][django.request.log_response():241] [ERROR] Internal Server Error: /bound/outdemand/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.\bound\views.py", line 74, in batch_list
+    OutBoundDemand_all = OutBoundDemandModel.objects.filter(bound_list_id=data['bound_list_id'], is_delete=False).all()
+KeyError: 'bound_list_id'
+[2025-05-20 02:15:47,629][django.request.log_response():241] [ERROR] Internal Server Error: /bound/batchdemand/
+[2025-05-20 02:16:50,949][django.request.log_response():241] [WARNING] Bad Request: /bound/batchdemand/
+[2025-05-20 02:37:57,974][django.request.log_response():241] [WARNING] Bad Request: /bound/batchdemand/
+[2025-05-20 02:44:18,648][django.request.log_response():241] [WARNING] Not Found: /dn/detail/
+[2025-05-20 02:44:19,462][django.request.log_response():241] [WARNING] Not Found: /dn/detail/
+[2025-05-20 02:44:19,991][django.request.log_response():241] [WARNING] Not Found: /dn/detail/
+[2025-05-20 02:44:20,449][django.request.log_response():241] [WARNING] Not Found: /dn/pickinglistfilter/
+[2025-05-20 02:44:20,844][django.request.log_response():241] [WARNING] Not Found: /dn/detail/
+[2025-05-20 02:44:31,555][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-05-20 02:45:05,878][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-05-20 02:45:09,942][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-05-20 02:45:14,655][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-05-20 02:45:20,027][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-05-20 02:45:34,504][django.request.log_response():241] [WARNING] Not Found: /cyclecount/qtyrecorviewset/
+[2025-05-20 03:34:54,362][django.request.log_response():241] [WARNING] Not Found: /bound/batchdemand/detailData
+[2025-05-20 04:00:07,323][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:05:31,791][django.server.log_message():187] [INFO] "POST /container/out_task/ HTTP/1.1" 200 30
+[2025-05-20 04:05:35,032][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=1&page_size=11 HTTP/1.1" 200 453
+[2025-05-20 04:05:44,758][django.server.log_message():187] [INFO] "POST /container/out_task/ HTTP/1.1" 200 30
+[2025-05-20 04:05:44,830][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=1&page_size=11 HTTP/1.1" 200 453
+[2025-05-20 04:05:53,193][django.server.log_message():187] [INFO] "GET /container/wcs_task/?page=1&page_size=11 HTTP/1.1" 200 1717
+[2025-05-20 04:06:34,074][django.server.log_message():187] [INFO] "GET /warehouse/department/ HTTP/1.1" 200 2858
+[2025-05-20 04:06:34,096][django.server.log_message():187] [INFO] "GET /warehouse/boundbusiness/ HTTP/1.1" 200 229
+[2025-05-20 04:06:34,172][django.server.log_message():187] [INFO] "GET /warehouse/boundtype/ HTTP/1.1" 200 233
+[2025-05-20 04:06:34,179][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=1&page_size=11 HTTP/1.1" 200 453
+[2025-05-20 04:06:34,191][django.server.log_message():187] [INFO] "GET /warehouse/status/ HTTP/1.1" 200 600
+[2025-05-20 04:06:34,194][django.server.log_message():187] [INFO] "GET /warehouse/boundcodetype/ HTTP/1.1" 200 250
+[2025-05-20 04:13:35,850][django.server.log_message():187] [INFO] "POST /container/out_task/ HTTP/1.1" 200 30
+[2025-05-20 04:13:35,942][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=1&page_size=11 HTTP/1.1" 200 453
+[2025-05-20 04:28:33,924][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:28:33,927][django.server.log_message():187] [ERROR] "POST /container/out_task/ HTTP/1.1" 500 83
+[2025-05-20 04:30:34,459][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:30:34,460][django.server.log_message():187] [ERROR] "POST /container/out_task/ HTTP/1.1" 500 186
+[2025-05-20 04:34:12,113][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:35:21,771][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 04:46:43,822][django.server.log_message():187] [INFO] "POST /container/out_task/ HTTP/1.1" 200 30
+[2025-05-20 04:46:43,877][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=1&page_size=11 HTTP/1.1" 200 453
+[2025-05-20 05:18:38,074][django.server.log_message():187] [INFO] "OPTIONS /bound/list/2/ HTTP/1.1" 200 0
+[2025-05-20 05:18:38,074][django.server.log_message():187] [INFO] "OPTIONS /bound/outdemand/ HTTP/1.1" 200 0
+[2025-05-20 05:18:38,145][django.server.log_message():187] [INFO] "GET /bound/list/2/ HTTP/1.1" 200 401
+[2025-05-20 05:18:38,159][django.server.log_message():187] [INFO] "PUT /bound/outdemand/ HTTP/1.1" 200 2747
+[2025-05-20 05:18:42,729][django.server.log_message():187] [INFO] "OPTIONS /bound/batchdemand/ HTTP/1.1" 200 0
+[2025-05-20 05:18:42,766][django.server.log_message():187] [INFO] "PUT /bound/batchdemand/ HTTP/1.1" 200 1258
+[2025-05-20 05:18:47,871][django.server.log_message():187] [INFO] "OPTIONS /warehouse/boundcodetype/ HTTP/1.1" 200 0
+[2025-05-20 05:18:47,872][django.server.log_message():187] [INFO] "OPTIONS /wms/inboundBills/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 0
+[2025-05-20 05:18:47,875][django.server.log_message():187] [INFO] "OPTIONS /warehouse/boundbusiness/ HTTP/1.1" 200 0
+[2025-05-20 05:18:47,876][django.server.log_message():187] [INFO] "OPTIONS /warehouse/boundtype/ HTTP/1.1" 200 0
+[2025-05-20 05:18:47,913][django.server.log_message():187] [INFO] "GET /warehouse/department/ HTTP/1.1" 200 2858
+[2025-05-20 05:18:47,932][django.server.log_message():187] [INFO] "GET /wms/inboundBills/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 52
+[2025-05-20 05:18:47,949][django.server.log_message():187] [INFO] "GET /warehouse/boundcodetype/ HTTP/1.1" 200 250
+[2025-05-20 05:18:47,970][django.server.log_message():187] [INFO] "GET /warehouse/boundbusiness/ HTTP/1.1" 200 229
+[2025-05-20 05:18:47,987][django.server.log_message():187] [INFO] "GET /warehouse/boundtype/ HTTP/1.1" 200 233
+[2025-05-20 05:18:49,392][django.server.log_message():187] [INFO] "OPTIONS /warehouse/department/?max_page=1000 HTTP/1.1" 200 0
+[2025-05-20 05:18:49,401][django.server.log_message():187] [INFO] "OPTIONS /warehouse/status/ HTTP/1.1" 200 0
+[2025-05-20 05:18:49,401][django.server.log_message():187] [INFO] "OPTIONS /bound/list/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 0
+[2025-05-20 05:18:49,472][django.server.log_message():187] [INFO] "GET /warehouse/boundbusiness/ HTTP/1.1" 200 229
+[2025-05-20 05:18:49,491][django.server.log_message():187] [INFO] "GET /warehouse/boundcodetype/ HTTP/1.1" 200 250
+[2025-05-20 05:18:49,598][django.server.log_message():187] [INFO] "GET /warehouse/department/?max_page=1000 HTTP/1.1" 200 9376
+[2025-05-20 05:18:49,598][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 452
+[2025-05-20 05:18:49,614][django.server.log_message():187] [INFO] "GET /warehouse/status/ HTTP/1.1" 200 600
+[2025-05-20 05:18:49,640][django.server.log_message():187] [INFO] "GET /warehouse/boundtype/ HTTP/1.1" 200 233
+[2025-05-20 05:18:52,256][django.server.log_message():187] [INFO] "OPTIONS /container/list/?page=1&page_size=11 HTTP/1.1" 200 0
+[2025-05-20 05:18:52,304][django.server.log_message():187] [INFO] "GET /container/list/?page=1&page_size=11 HTTP/1.1" 200 679
+[2025-05-20 05:18:56,751][django.server.log_message():187] [INFO] "OPTIONS /container/task/?page=1&page_size=11 HTTP/1.1" 200 0
+[2025-05-20 05:18:56,904][django.server.log_message():187] [INFO] "GET /container/task/?page=1&page_size=11 HTTP/1.1" 200 27570
+[2025-05-20 05:18:58,696][django.server.log_message():187] [INFO] "OPTIONS /container/detail/?page=1&page_size=11 HTTP/1.1" 200 0
+[2025-05-20 05:18:58,791][django.server.log_message():187] [INFO] "GET /container/detail/?page=1&page_size=11 HTTP/1.1" 200 11636
+[2025-05-20 05:19:00,975][django.server.log_message():187] [INFO] "GET /container/list/?page=1&page_size=11 HTTP/1.1" 200 679
+[2025-05-20 05:19:02,610][django.server.log_message():187] [INFO] "OPTIONS /container/detail/?status__lte=2&container=3 HTTP/1.1" 200 0
+[2025-05-20 05:19:02,611][django.server.log_message():187] [INFO] "OPTIONS /container/operate/?status=1&container=3 HTTP/1.1" 200 0
+[2025-05-20 05:19:02,706][django.server.log_message():187] [INFO] "GET /container/detail/?status__lte=2&container=3 HTTP/1.1" 200 1091
+[2025-05-20 05:19:02,710][django.server.log_message():187] [INFO] "GET /container/operate/?status=1&container=3 HTTP/1.1" 200 2329
+[2025-05-20 05:19:05,160][django.server.log_message():187] [INFO] "OPTIONS /container/detail/?status__lte=2&container=1 HTTP/1.1" 200 0
+[2025-05-20 05:19:05,161][django.server.log_message():187] [INFO] "OPTIONS /container/operate/?status=1&container=1 HTTP/1.1" 200 0
+[2025-05-20 05:19:05,250][django.server.log_message():187] [INFO] "GET /container/operate/?status=1&container=1 HTTP/1.1" 200 2360
+[2025-05-20 05:19:05,311][django.server.log_message():187] [INFO] "GET /container/detail/?status__lte=2&container=1 HTTP/1.1" 200 11683
+[2025-05-20 05:19:07,706][django.server.log_message():187] [INFO] "GET /warehouse/boundtype/ HTTP/1.1" 200 233
+[2025-05-20 05:19:07,761][django.server.log_message():187] [INFO] "GET /warehouse/boundbusiness/ HTTP/1.1" 200 229
+[2025-05-20 05:19:07,813][django.server.log_message():187] [INFO] "GET /warehouse/boundcodetype/ HTTP/1.1" 200 250
+[2025-05-20 05:19:07,848][django.server.log_message():187] [INFO] "GET /bound/list/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 452
+[2025-05-20 05:19:07,859][django.server.log_message():187] [INFO] "GET /warehouse/department/?max_page=1000 HTTP/1.1" 200 9376
+[2025-05-20 05:19:07,861][django.server.log_message():187] [INFO] "GET /warehouse/status/ HTTP/1.1" 200 600
+[2025-05-20 05:19:09,870][django.server.log_message():187] [INFO] "GET /warehouse/boundcodetype/ HTTP/1.1" 200 250
+[2025-05-20 05:19:09,916][django.server.log_message():187] [INFO] "GET /warehouse/department/ HTTP/1.1" 200 2858
+[2025-05-20 05:19:09,916][django.server.log_message():187] [INFO] "GET /warehouse/boundtype/ HTTP/1.1" 200 233
+[2025-05-20 05:19:09,961][django.server.log_message():187] [INFO] "GET /warehouse/boundbusiness/ HTTP/1.1" 200 229
+[2025-05-20 05:19:09,977][django.server.log_message():187] [INFO] "GET /wms/inboundBills/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 52
+[2025-05-20 05:19:12,992][django.server.log_message():187] [INFO] "OPTIONS /bin/?layer=1&warehouse_code=W01&max_page=1000&shelf_name=A%E5%8C%BA%E8%B4%A7%E6%9E%B6 HTTP/1.1" 200 0
+[2025-05-20 05:19:13,116][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
+    response = get_response(request)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:19:13,121][django.server.log_message():187] [ERROR] "GET /bin/?layer=1&warehouse_code=W01&max_page=1000&shelf_name=A%E5%8C%BA%E8%B4%A7%E6%9E%B6 HTTP/1.1" 500 162131
+[2025-05-20 05:19:20,097][django.server.log_message():187] [INFO] "GET /warehouse/boundbusiness/ HTTP/1.1" 200 229
+[2025-05-20 05:19:20,151][django.server.log_message():187] [INFO] "GET /warehouse/boundtype/ HTTP/1.1" 200 233
+[2025-05-20 05:19:20,161][django.server.log_message():187] [INFO] "GET /warehouse/department/ HTTP/1.1" 200 2858
+[2025-05-20 05:19:20,231][django.server.log_message():187] [INFO] "GET /wms/inboundBills/?page=1&base_type=0&page_size=11 HTTP/1.1" 200 52
+[2025-05-20 05:19:20,246][django.server.log_message():187] [INFO] "GET /warehouse/boundcodetype/ HTTP/1.1" 200 250
+[2025-05-20 05:19:21,555][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
+    response = get_response(request)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "d:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:19:21,558][django.server.log_message():187] [ERROR] "GET /bin/?layer=1&warehouse_code=W01&max_page=1000&shelf_name=A%E5%8C%BA%E8%B4%A7%E6%9E%B6 HTTP/1.1" 500 162131
+[2025-05-20 05:20:53,012][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\.\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:22:42,740][django.request.log_response():241] [ERROR] Internal Server Error: /container/out_task/
+[2025-05-20 05:28:13,804][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 38, in list
+    queryset = self.filter_queryset(self.get_queryset())
+  File "D:\Document\code\vue\greater_wms\.\bin\views.py", line 67, in get_queryset
+    queryset=ContainerListModel.objects.filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
+    return self._filter_or_exclude(False, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
+    clone._filter_or_exclude_inplace(negate, args, kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
+    self._query.add_q(Q(*args, **kwargs))
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
+    clause, _ = self._add_q(q_object, self.used_aliases)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
+    child_clause, needed_inner = self.build_filter(
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1407, in build_filter
+    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1217, in solve_lookup_type
+    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\sql\query.py", line 1709, in names_to_path
+    raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'locationcontainerlink' into field. Choices are: allocation_history, available, container_code, current_location, details, id, last_operation, location_links, locationchangelog, locationmodel, operations, status, target_location
+[2025-05-20 05:31:10,853][django.request.log_response():241] [ERROR] Internal Server Error: /bin/
+Traceback (most recent call last):
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 472, in thread_handler
+    raise exc_info[1]
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
+    response = await get_response(request)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async
+    response = await wrapped_callback(
+  File "D:\Document\code\vue\greater_wms\.venv\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:\Document\code\vue\greater_wms\.venv\lib\site-packages\asgiref\sync.py", line 476, in thread_handler
+    return func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\mixins.py", line 40, in list
+    page = self.paginate_queryset(queryset)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\generics.py", line 171, in paginate_queryset
+    return self.paginator.paginate_queryset(queryset, self.request, view=self)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\rest_framework\pagination.py", line 216, in paginate_queryset
+    return list(self.page)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\core\paginator.py", line 177, in __len__
+    return len(self.object_list)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 376, in __len__
+    self._fetch_all()
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1868, in _fetch_all
+    self._prefetch_related_objects()
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 1257, in _prefetch_related_objects
+    prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
+  File "D:\Document\code\vue\greater_wms\.venv\lib\site-packages\django\db\models\query.py", line 2272, in prefetch_related_objects
+    raise AttributeError(
+AttributeError: Cannot find 'container_links' on LocationModel object, 'container_links' is an invalid parameter to prefetch_related()

+ 2 - 2
templates/src/pages/dashboard/dashboard.vue

@@ -23,7 +23,7 @@
                 exact
               />
             </transition>
-            <transition appear enter-active-class="animated zoomIn">
+            <!-- <transition appear enter-active-class="animated zoomIn">
               <q-route-tab
                 name="status_statements"
                 :label="$t('dashboards.status_statements')"
@@ -49,7 +49,7 @@
                 :to="{ name: 'inventory_inquiry' }"
                 exact
                 />
-            </transition>
+            </transition> -->
 
             
           </q-tabs>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 788 - 244
templates/src/pages/dashboard/flows_statements.vue


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1360 - 111
templates/src/pages/dashboard/inboundAndOutbound.vue


+ 302 - 224
templates/src/pages/outbound/dn.vue

@@ -71,7 +71,7 @@
                   push
                   color="black"
                   icon="description"
-                  @click="detailData(props.row)"
+                  @click="detailData(props.row.id)"
                 >
                   <q-tooltip
                     content-class="bg-amber text-black shadow-4"
@@ -90,7 +90,7 @@
                   push
                   color="black"
                   icon="description"
-                  @click="detailData(props.row)"
+                  @click="detailData(props.row.id)"
                 >
                   <q-tooltip
                     content-class="bg-amber text-black shadow-4"
@@ -688,6 +688,7 @@
                       map-options
                       transition-show="scale"
                       transition-hide="scale"
+                      @input="get_refresh_data"
                     />
                   </div>
                   <div class="col column q-gutter-y-md">
@@ -705,44 +706,12 @@
                       :readonly="false"
                       transition-show="scale"
                       transition-hide="scale"
-                      :rules="[(val) => (val && val.length > 0) || error1]"
+                      @input="get_refresh_data"
                     />
                   </div>
                 </div>
-
-                <div class="q-mt-lg" v-show="showConditions">
-                  <q-card flat bordered>
-                    <q-card-section>
-                      <div class="text-caption">生成查询条件:</div>
-                      <pre>{{ generatedQuery }}</pre>
-                    </q-card-section>
-
-                    <q-card-actions align="right"> </q-card-actions>
-                  </q-card>
-                </div>
-              </q-card>
-            </div>
-            <div class="q-mb-md">
-              {{ "已有批次信息" }}
-              <div style="float: right; padding: 15px 15px 15px 0">
-                <q-btn color="primary" @click="get_refresh_data()">{{
-                  "刷新"
-                }}</q-btn>
-              </div>
-            </div>
-            <q-card class="q-mb-md" bordered>
-              <q-card-section class="q-pt-md">
                 <div class="row q-gutter-x-md">
                   <div class="col column q-gutter-y-md">
-                    <q-input
-                      dense
-                      outlined
-                      square
-                      v-model.number="newBatchFormData.goods_weight"
-                      :label="'单重'"
-                      type="number"
-                      :readonly="true"
-                    />
                     <q-input
                       dense
                       outlined
@@ -762,6 +731,8 @@
                       :label="'单位'"
                       :readonly="true"
                     />
+                  </div>
+                  <div class="col column q-gutter-y-md">
                     <q-input
                       dense
                       outlined
@@ -772,8 +743,18 @@
                     />
                   </div>
                 </div>
-              </q-card-section>
-            </q-card>
+
+                <div class="q-mt-lg" v-show="showConditions">
+                  <q-card flat bordered>
+                    <q-card-section>
+                      <div class="text-caption">生成查询条件:</div>
+                      <pre>{{ generatedQuery }}</pre>
+                    </q-card-section>
+                    <q-card-actions align="right"> </q-card-actions>
+                  </q-card>
+                </div>
+              </q-card>
+            </div>
           </div>
           <q-input
             dense
@@ -790,7 +771,7 @@
             v-model.number="newBatchFormData.goods_out_qty"
             :label="'出库数量'"
             type="number"
-            :rules="[(val) => (val && val > 0) || error1]"
+            :rules="[(val) => (val && val > 0) || '出库数量必须大于0']"
           />
           <q-input
             dense
@@ -798,7 +779,7 @@
             square
             v-model="newBatchFormData.creater"
             :label="'经办人'"
-            :rules="[(val) => (val && val.length > 0) || error1]"
+            :rules="[(val) => (val && val.length > 0) || '出库人不能为空']"
           />
         </q-card-section>
 
@@ -810,9 +791,12 @@
             @click="newBatchCancel()"
             >{{ $t("cancel") }}</q-btn
           >
-          <q-btn color="primary" @click="newBatchSubmit()">{{
-            $t("submit")
-          }}</q-btn>
+          <q-btn
+            color="primary"
+            v-if="newBatchFormData.goods_out_qty > 0"
+            @click="newBatchSubmit()"
+            >{{ $t("submit") }}</q-btn
+          >
         </div>
       </q-card>
     </q-dialog>
@@ -842,8 +826,8 @@
         </q-bar>
         <q-card-section class="q-pt-md">
           <q-tabs v-model="activeTab">
-            <q-tab name="tab1" label="出库信息" />
-            <!-- <q-tab name="tab2" label="货物信息" /> -->
+            <q-tab name="tab1" label="出库计划" />
+            <q-tab name="tab2" label="批次计划" />
           </q-tabs>
         </q-card-section>
         <!-- 选项卡内容 -->
@@ -871,89 +855,199 @@
                 />
               </div>
             </div>
+            <div
+              style="
+                float: right;
+                padding: 15px 15px 50px 15px;
+                min-width: 100%;
+              "
+              flow="row wrap"
+            >
+              <q-card class="q-mb-md" bordered>
+                <q-card-actions
+                  class="q-px-none"
+                  style="
+                    position: absolute;
+                    right: 20px;
+                    top: 10px;
+                    z-index: 100;
+                  "
+                >
+                  <q-btn
+                    icon="add"
+                    flat
+                    dense
+                    color="primary"
+                    @click="addbatch()"
+                    :label="$t('stock.add')"
+                  />
+                  <q-btn
+                    icon="done"
+                    flat
+                    dense
+                    color="primary"
+                    @click="generatebatch()"
+                    :label="'生成批次'"
+                  />
+                </q-card-actions>
+                <q-card-section>
+                  <template>
+                    <div class="text-h6 q-mb-md">{{ "物料需求信息" }}</div>
+                    <template v-if="batch_detail.length > 0">
+                      <div
+                        v-for="(item, index) in batch_detail"
+                        :key="index"
+                        class="row q-col-gutter-md q-mb-sm"
+                      >
+                        <div class="col-2" style="min-width: 150px">
+                          <q-input
+                            v-model="item.goods_code"
+                            :label="'物料编码'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+                        <div class="col">
+                          <q-input
+                            v-model="item.goods_desc"
+                            :label="'货物名称'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+
+                        <div class="col-2">
+                          <q-input
+                            v-model="item.goods_qty"
+                            :label="'需求数量'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+                        <div class="col-2">
+                          <q-input
+                            v-model="item.goods_unit"
+                            :label="'单位'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+                      </div>
+                    </template>
+                  </template>
+                </q-card-section>
+              </q-card>
+            </div>
           </q-tab-panel>
-        </q-tab-panels>
-
-        <div
-          style="float: right; padding: 15px 15px 50px 15px; min-width: 100%"
-          flow="row wrap"
-        >
-          <q-card class="q-mb-md" bordered>
-            <q-card-actions
-              class="q-px-none"
-              style="position: absolute; right: 20px; top: 10px; z-index: 100"
+          <q-tab-panel name="tab2" style="height: 70px">
+            <div class="row q-gutter-x-md">
+              <div class="col column q-gutter-y-md">
+                <q-input
+                  dense
+                  outlined
+                  square
+                  v-model="table_detail.bound_date"
+                  :label="'单据时间'"
+                  :readonly="true"
+                />
+              </div>
+              <div class="col column q-gutter-y-md">
+                <q-input
+                  dense
+                  outlined
+                  square
+                  v-model="table_detail.bound_code"
+                  :label="'单据编码'"
+                  :readonly="true"
+                />
+              </div>
+            </div>
+            <div
+              style="
+                float: right;
+                padding: 15px 15px 50px 15px;
+                min-width: 100%;
+              "
+              flow="row wrap"
             >
-              <q-btn
-                icon="add"
-                flat
-                dense
-                color="primary"
-                @click="addbatch(table_detail.id)"
-                :label="$t('stock.add')"
-              />
-            </q-card-actions>
-            <q-card-section>
-              <template>
-                <div class="text-h6 q-mb-md">{{ "批次信息" }}</div>
-                <template v-if="batch_detail.length > 0">
-                  <div
-                    v-for="(item, index) in batch_detail"
-                    :key="index"
-                    class="row q-col-gutter-md q-mb-sm"
-                  >
-                    <div class="col" style="min-width: 150px">
-                      <q-input
-                        v-model="item.bound_batch.out_number"
-                        :label="'批次'"
-                        :readonly="onlyread"
-                        dense
-                        outlined
-                      />
-                    </div>
-                    <div class="col">
-                      <q-input
-                        v-model="item.bound_batch.goods_desc"
-                        :label="'货物'"
-                        :readonly="onlyread"
-                        dense
-                        outlined
-                      />
-                    </div>
-                    <div class="col">
-                      <q-input
-                        v-model="item.bound_batch.goods_weight"
-                        :label="'单重'"
-                        :readonly="onlyread"
-                        dense
-                        outlined
-                      />
-                    </div>
-                    <div class="col">
-                      <q-input
-                        v-model="item.bound_batch.goods_out_qty"
-                        :label="'出库数量'"
-                        :readonly="onlyread"
-                        dense
-                        outlined
-                      />
-                    </div>
-                    <!-- <div class="col" style="max-width: 50px">
-                      <q-btn
-                        v-if="!onlyread"
-                        icon="delete"
-                        flat
-                        dense
-                        color="primary"
-                        @click="addbatch(table_detail.id)"
-                        style="margin-top: 1px"
-                      />
-                    </div> -->
-                  </div>
-                </template>
-              </template>
-            </q-card-section>
-          </q-card>
-        </div>
+              <q-card class="q-mb-md" bordered>
+                <q-card-actions
+                  class="q-px-none"
+                  style="
+                    position: absolute;
+                    right: 20px;
+                    top: 10px;
+                    z-index: 100;
+                  "
+                >
+                  <q-btn
+                    icon="refresh"
+                    flat
+                    dense
+                    color="primary"
+                    @click="get_batchdemand()"
+                    :label="'刷新'"
+                  />
+                </q-card-actions>
+                <q-card-section>
+                  <template>
+                    <div class="text-h6 q-mb-md">{{ "计划安排批次" }}</div>
+                    <template v-if="batchdemand.length > 0">
+                      <div
+                        v-for="(item, index) in batchdemand"
+                        :key="index"
+                        class="row q-col-gutter-md q-mb-sm"
+                      >
+                        <div class="col-2" style="min-width: 150px">
+                          <q-input
+                            v-model="item.goods_code"
+                            :label="'物料编码'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+                        <div class="col">
+                          <q-input
+                            v-model="item.goods_desc"
+                            :label="'货物名称'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+                        <div class="col">
+                          <q-input
+                            v-model="item.batch_number.bound_number"
+                            :label="'管理批次'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+
+                        <div class="col-2">
+                          <q-input
+                            v-model="item.goods_out_qty"
+                            :label="'计划数量'"
+                            :readonly="onlyread"
+                            dense
+                            outlined
+                          />
+                        </div>
+
+                      </div>
+                    </template>
+                  </template>
+                </q-card-section>
+              </q-card>
+            </div>
+          </q-tab-panel>
+        </q-tab-panels>
       </q-card>
     </q-dialog>
   </div>
@@ -1004,6 +1098,7 @@ export default {
         id: 'printMe',
         popTitle: this.$t('inbound.asn')
       },
+      batchdemand: [],
       table_list: [],
       table_detail: {},
       batch_detail: [],
@@ -1081,6 +1176,7 @@ export default {
       newBatchForm: false,
       newFormData: {},
       newBatchFormData: {
+        bound_list_id: 0,
         goods_code: '',
         goods_desc: '',
         goods_weight: 0,
@@ -1093,7 +1189,7 @@ export default {
         goods_std: '',
         goods_batch: ''
       },
-      newDetailFormData: {},
+
       editid: 0,
       editFormData: {},
       editMode: false,
@@ -1118,10 +1214,10 @@ export default {
       fieldOptions: [
         { label: '物料编码', value: 'goods_code' },
         { label: '物料名称', value: 'goods_desc' },
-        { label: '管理批次号', value: 'bound_number' },
-        { label: 'ERP批次号', value: 'sourced_number' },
-        { label: '库存数量', value: 'goods_in_location_qty' },
-        { label: '入库日期', value: 'create_time' }
+        // { label: '管理批次号', value: 'bound_number' },
+        // { label: 'ERP批次号', value: 'sourced_number' },
+        { label: '库存数量', value: 'goods_in_location_qty' }
+        // { label: '入库日期', value: 'create_time' }
       ],
       operatorMap: {
         default: [
@@ -1192,6 +1288,40 @@ export default {
     }
   },
   methods: {
+    get_batchdemand () {
+      var _this = this
+      var demand_id = _this.detailid
+      var send_data = { bound_list_id: demand_id }
+      putauth('bound/batchdemand/', send_data).then((res) => {
+        console.log('获取批次需求成功', res)
+        _this.batchdemand = res.data
+      })
+    },
+
+    generatebatch () {
+      var _this = this
+      var demand_id = _this.detailid
+      var send_data = { bound_list_id: demand_id }
+      postauth('bound/batchdemand/', send_data)
+        .then((res) => {
+          this.get_batchdemand()
+          console.log('生成批次成功', res)
+          _this.$q.notify({
+            message: '生成批次成功',
+            icon: 'check',
+            color: 'positive'
+          })
+          _this.getList()
+        })
+        .catch((err) => {
+          console.log('生成批次失败', err)
+          _this.$q.notify({
+            message: err.detail,
+            icon: 'close',
+            color: 'negative'
+          })
+        })
+    },
     dayOptions (year, month) {
       if (!year || !month) return []
       const days = new Date(year, month, 0).getDate()
@@ -1244,11 +1374,12 @@ export default {
       this.newBatchFormData.goods_qty = 0
       this.newBatchFormData.goods_unit = ''
       this.newBatchFormData.goods_out_qty = 0
-      this.newBatchFormData.creater = ''
       this.newBatchFormData.out_number = ''
       this.newBatchFormData.out_type = '0'
       this.newBatchFormData.goods_std = ''
       this.newBatchFormData.goods_batch = ''
+
+      this.target_batch = ''
     },
 
     getList (params = {}) {
@@ -1308,14 +1439,16 @@ export default {
     },
 
     get_refresh_data () {
-      getauth('bound/batch/?bound_number=' + this.target_batch)
+      getauth('bound/batch/count/?goods_code=' + this.target_batch)
         .then((res) => {
           console.log('当前长度', res.results.length)
           console.log('当前值', res.results[0])
           if (res.results.length > 0) {
-            this.newBatchFormData.goods_qty = res.results[0].goods_qty
-            console.log('当前数目', this.newBatchFormData.goods_qty)
-            this.newBatchFormData.goods_weight = res.results[0].goods_weight
+            this.newBatchFormData.goods_qty =
+              res.results[0].total_quantity -
+              res.results[0].total_demanded_quantity
+
+            this.newBatchFormData.goods_weight = 1
             this.newBatchFormData.goods_std = res.results[0].goods_std
             this.newBatchFormData.goods_unit = res.results[0].goods_unit
           } else {
@@ -1361,14 +1494,14 @@ export default {
 
       console.log('查询参数', finalQuery)
 
-      getauth(`bound/batch/?${finalQuery}`)
+      getauth(`bound/batch/count/?${finalQuery}`)
         .then((res) => {
           _this.product_list = res.results.map((item) => ({
             label: item.goods_desc,
-            value: item.bound_number
+            value: item.goods_code
           }))
           _this.product_map = res.results.reduce((acc, item) => {
-            acc[item.bound_number] = item.goods_desc
+            acc[item.goods_code] = item.goods_desc
             return acc
           }, {})
         })
@@ -1515,37 +1648,22 @@ export default {
     },
     newBatchSubmit () {
       var _this = this
+      var send_data = {
+        bound_list_id: _this.detailid,
+        goods_code: _this.newBatchFormData.goods_code,
+        goods_desc: _this.newBatchFormData.goods_desc,
+        goods_std: _this.newBatchFormData.goods_std,
+        goods_unit: _this.newBatchFormData.goods_unit,
+        goods_out_qty: _this.newBatchFormData.goods_out_qty,
+        creater: _this.newBatchFormData.creater,
+        out_type: _this.newBatchFormData.out_type
+      }
 
-      _this.newBatchFormData.openid = _this.openid
-      _this.newBatchFormData.warehouse_code = _this.warehouse_code
-      _this.newBatchFormData.warehouse_name = _this.warehouse_name
-
-      postauth('bound/outbatch/', _this.newBatchFormData)
+      postauth('bound/outdemand/', send_data)
         .then((res) => {
           if (res.status_code !== 500) {
-            _this.newDetailFormData.bound_batch = res.id
-            _this.newDetailFormData.creater = _this.login_name
-
-            postauth('bound/outdetail/', _this.newDetailFormData).then(
-              (res) => {
-                if (res.status_code !== 500) {
-                  _this.detailData(_this.newDetailFormData)
-
-                  _this.$q.notify({
-                    message: '成功新增数据',
-                    icon: 'check',
-                    color: 'green'
-                  })
-                }
-              },
-              (err) => {
-                _this.$q.notify({
-                  message: err.detail,
-                  icon: 'close',
-                  color: 'negative'
-                })
-              }
-            )
+            _this.get_refresh_data()
+            _this.detailData(_this.detailid)
           }
         })
         .catch((err) => {
@@ -1555,31 +1673,6 @@ export default {
             color: 'negative'
           })
         })
-
-      getauth('bound/batch/?bound_number=' + this.target_batch)
-        .then((res) => {
-          console.log('当前长度', res.results.length)
-          console.log('当前值', res.results[0])
-          if (res.results.length > 0) {
-            this.newBatchFormData.goods_qty = res.results[0].goods_qty
-            console.log('当前数目', this.newBatchFormData.goods_qty)
-            this.newBatchFormData.goods_weight = res.results[0].goods_weight
-            this.newBatchFormData.goods_std = res.results[0].goods_std
-            this.newBatchFormData.goods_unit = res.results[0].goods_unit
-          } else {
-            this.newBatchFormData.goods_qty = ''
-            this.newBatchFormData.goods_weight = ''
-            this.newBatchFormData.goods_std = ''
-            this.newBatchFormData.goods_unit = ''
-          }
-        })
-        .catch((err) => {
-          this.$q.notify({
-            message: err.detail,
-            icon: 'close',
-            color: 'negative'
-          })
-        })
     },
     newDataCancel () {
       var _this = this
@@ -1592,13 +1685,21 @@ export default {
         creater: ''
       }
     },
-    addbatch (bound_number) {
+    addbatch () {
       var _this = this
       _this.newBatchForm = true
-      _this.newDetailFormData = {
-        id: bound_number,
-        bound_list: bound_number
-      }
+
+      this.newBatchFormData.goods_code = ''
+      this.newBatchFormData.goods_desc = ''
+      this.newBatchFormData.goods_weight = 0
+      this.newBatchFormData.goods_qty = 0
+      this.newBatchFormData.goods_unit = ''
+      this.newBatchFormData.goods_out_qty = 0
+      this.newBatchFormData.creater = _this.login_name
+      this.newBatchFormData.out_number = ''
+      this.newBatchFormData.out_type = '0'
+      this.newBatchFormData.goods_std = ''
+      this.newBatchFormData.goods_batch = ''
     },
     editData (e) {
       var _this = this
@@ -1685,10 +1786,10 @@ export default {
       _this.deleteForm = true
       _this.deleteid = e
     },
-    detailData (e) {
+    detailData (id) {
       var _this = this
       _this.detailForm = true
-      _this.detailid = e.id
+      _this.detailid = id
       console.log('detail查询的id是:', _this.detailid)
       getauth(_this.pathname + _this.detailid + '/')
         .then((res) => {
@@ -1703,9 +1804,9 @@ export default {
         })
       console.log('detail查询的结果是:', _this.table_detail)
 
-      getauth('bound/outdetail/?bound_list=' + _this.detailid)
+      putauth('bound/outdemand/', { bound_list_id: _this.detailid })
         .then((res) => {
-          _this.batch_detail = res.results
+          _this.batch_detail = res.data
         })
         .catch((err) => {
           _this.$q.notify({
@@ -1898,30 +1999,7 @@ export default {
         this.newBatchFormData.out_number = ''
         this.newBatchFormData.goods_desc = ''
       }
-      getauth('bound/batch/?bound_number=' + val)
-        .then((res) => {
-          console.log('当前长度', res.results.length)
-          console.log('当前值', res.results[0])
-          if (res.results.length > 0) {
-            this.newBatchFormData.goods_qty = res.results[0].goods_qty
-            console.log('当前数目', this.newBatchFormData.goods_qty)
-            this.newBatchFormData.goods_weight = res.results[0].goods_weight
-            this.newBatchFormData.goods_std = res.results[0].goods_std
-            this.newBatchFormData.goods_unit = res.results[0].goods_unit
-          } else {
-            this.newBatchFormData.goods_qty = ''
-            this.newBatchFormData.goods_weight = ''
-            this.newBatchFormData.goods_std = ''
-            this.newBatchFormData.goods_unit = ''
-          }
-        })
-        .catch((err) => {
-          this.$q.notify({
-            message: err.detail,
-            icon: 'close',
-            color: 'negative'
-          })
-        })
+      // this.get_refresh_data()
     },
     createDate1 (val) {
       if (val) {

+ 2 - 2
templates/src/pages/outbound/outbound.vue

@@ -9,7 +9,7 @@
         <transition appear enter-active-class="animated zoomIn">
           <q-route-tab name="dn" :label="$t('outbound.dn')" icon="img:statics/outbound/dnlist.png" :to="{ name: 'dn' }" exact/>
         </transition>
-        <transition appear enter-active-class="animated zoomIn">
+        <!-- <transition appear enter-active-class="animated zoomIn">
           <q-route-tab name="freshorder" :label="$t('outbound.freshorder')" icon="img:statics/outbound/freshorder.png" :to="{ name: 'freshorder' }" exact/>
         </transition>
         <transition appear enter-active-class="animated zoomIn">
@@ -32,7 +32,7 @@
         </transition>
         <transition appear enter-active-class="animated zoomIn">
           <q-route-tab name="pod" :label="$t('outbound.pod')" icon="img:statics/outbound/receiving.png" :to="{ name: 'pod' }" exact/>
-        </transition>
+        </transition> -->
       </q-tabs>
     </div>
   </div>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1848 - 172
templates/src/pages/outbound/pod.vue