feat: material list filter low_inm优化

This commit is contained in:
caoqianming 2025-11-28 15:57:21 +08:00
parent a51494aea9
commit 8211a33b58
4 changed files with 31 additions and 26 deletions

View File

@ -2,13 +2,11 @@ from django_filters import rest_framework as filters
from apps.mtm.models import Goal, Material, Route, RoutePack
from django.db.models.expressions import F
from rest_framework.exceptions import ParseError
from django.db.models import Sum, Q, Value, F, ExpressionWrapper, DecimalField
from django.db.models.functions import Coalesce
class MaterialFilter(filters.FilterSet):
tag = filters.CharFilter(method='filter_tag', label="low_inm:库存不足")
count__gt = filters.NumberFilter(field_name='count', lookup_expr='gt')
count_mb__gt = filters.NumberFilter(field_name='count_mb', lookup_expr='gt')
count_wm__gt = filters.NumberFilter(field_name='count_wm', lookup_expr='gt')
class Meta:
model = Material
@ -30,7 +28,7 @@ class MaterialFilter(filters.FilterSet):
def filter_tag(self, queryset, name, value):
if value == 'low_inm':
queryset = queryset.exclude(count_safe=None).exclude(count_safe__lte=0).filter(
queryset = Material.annotate_count(queryset.exclude(count_safe=None).exclude(count_safe__lte=0)).filter(
count__lte=F('count_safe'))
return queryset

View File

@ -6,6 +6,8 @@ from collections import defaultdict, deque
from django.db.models import Q
from datetime import datetime, timedelta
from django.utils import timezone
from django.db.models import Sum, Q, Value, F, ExpressionWrapper, DecimalField
from django.db.models.functions import Coalesce
class Process(CommonBModel):
"""
@ -123,7 +125,26 @@ class Material(CommonAModel):
def fname(self):
return f'{self.name}|{self.specification if self.specification else ""}|{self.model if self.model else ""}|{self.process.name if self.process else ""}'
@staticmethod
def annotate_count(qs):
return qs.annotate(
count_mb=Coalesce(
Sum('mb_m__count', filter=Q(mb_m__state=10, mb_m__count__gt=0)),
Value(0),
output_field=DecimalField()
),
count_wm=Coalesce(
Sum('wm_m__count', filter=Q(wm_m__state=10, wm_m__count__gt=0)),
Value(0),
output_field=DecimalField()
)
).annotate(
count=ExpressionWrapper(
F('count_wm') + F('count_mb'),
output_field=DecimalField()
)
)
class Shift(CommonBModel):
"""TN:班次
"""

View File

@ -38,13 +38,15 @@ class MaterialSerializer(CustomModelSerializer):
count = serializers.SerializerMethodField()
def get_count_mb(self, obj):
return getattr(obj, 'count_mb', 0)
return getattr(obj, 'count_mb', None)
def get_count_wm(self, obj):
return getattr(obj, 'count_wm', 0)
return getattr(obj, 'count_wm', None)
def get_count(self, obj):
return getattr(obj, 'count_mb', 0) + getattr(obj, 'count_wm', 0)
if hasattr(obj, 'count_mb') and hasattr(obj, 'count_wm'):
return getattr(obj, 'count_mb', 0) + getattr(obj, 'count_wm', 0)
return None
class Meta:
model = Material

View File

@ -45,23 +45,7 @@ class MaterialViewSet(CustomModelViewSet):
def get_queryset(self):
qs = super().get_queryset()
if self.action in ["list", "retrieve"] and self.request.query_params.get('wiith_count', None) == 'yes':
return qs.annotate(
count_mb=Coalesce(
Sum('mb_m__count', filter=Q(mb_m__state=10, mb_m__count___gt=0)),
Value(0),
output_field=DecimalField()
),
count_wm=Coalesce(
Sum('wm_m__count', filter=Q(wm_m__state=10, wm_m__count___gt=0)),
Value(0),
output_field=DecimalField()
)
).annotate(
count=ExpressionWrapper(
F('count_wm') + F('count_mb'),
output_field=DecimalField()
)
)
return Material.annotate_count(qs)
return qs
def perform_destroy(self, instance):