baseline: 批次A-D 成果 + membership 半成品(测试红)
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""inventory async ViewSets。
|
||||
|
||||
库存账面与流水是只读对外接口(写入走 services);
|
||||
仓库可增删改。
|
||||
"""
|
||||
|
||||
from adrf.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||
from datetime import timedelta
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.core.viewset import BaseTenantViewSet
|
||||
from apps.core.viewset import StandardAsyncPagination
|
||||
from .models import Warehouse, Stock, StockBatch, StockMovement
|
||||
from .serializers import WarehouseSerializer, StockSerializer, StockMovementSerializer, StockBatchSerializer
|
||||
|
||||
|
||||
class WarehouseViewSet(BaseTenantViewSet):
|
||||
model = Warehouse
|
||||
serializer_class = WarehouseSerializer
|
||||
search_fields = ["code", "name"]
|
||||
|
||||
|
||||
class StockViewSet(BaseTenantViewSet):
|
||||
model = Stock
|
||||
serializer_class = StockSerializer
|
||||
search_fields = ["product__code", "product__name", "warehouse__code"]
|
||||
http_method_names = ["get", "head", "options"] # 只读
|
||||
select_related_fields = ("product", "warehouse", "product__base_unit")
|
||||
|
||||
|
||||
class StockMovementViewSet(BaseTenantViewSet):
|
||||
model = StockMovement
|
||||
serializer_class = StockMovementSerializer
|
||||
search_fields = ["product__code", "product__name", "source_ref"]
|
||||
http_method_names = ["get", "head", "options"] # 只读
|
||||
select_related_fields = ("product", "warehouse")
|
||||
|
||||
|
||||
class StockBatchViewSet(BaseTenantViewSet):
|
||||
"""批次库存(只读;写入走 inbound/outbound 服务)。"""
|
||||
|
||||
model = StockBatch
|
||||
serializer_class = StockBatchSerializer
|
||||
search_fields = ["batch_no", "product__code", "product__name", "warehouse__code"]
|
||||
http_method_names = ["get", "head", "options"] # 只读
|
||||
select_related_fields = ("product", "warehouse", "product__base_unit")
|
||||
|
||||
async def get_queryset(self):
|
||||
qs = await super().get_queryset()
|
||||
# 支持按 product / warehouse 过滤,且默认只看有量批次
|
||||
product_id = self.request.query_params.get("product")
|
||||
warehouse_id = self.request.query_params.get("warehouse")
|
||||
in_stock = self.request.query_params.get("in_stock", "")
|
||||
near_expiry = self.request.query_params.get("near_expiry", "")
|
||||
expiry_days = self.request.query_params.get("expiry_days", "30")
|
||||
if product_id:
|
||||
qs = qs.filter(product_id=product_id)
|
||||
if warehouse_id:
|
||||
qs = qs.filter(warehouse_id=warehouse_id)
|
||||
if in_stock in ("1", "true", "True"):
|
||||
qs = qs.filter(on_hand__gt=0)
|
||||
if near_expiry in ("1", "true", "True"):
|
||||
try:
|
||||
days = max(0, min(int(expiry_days), 3650))
|
||||
except (TypeError, ValueError):
|
||||
days = 30
|
||||
cutoff = timezone.localdate() + timedelta(days=days)
|
||||
qs = qs.filter(expiry_date__isnull=False, expiry_date__lte=cutoff)
|
||||
return qs
|
||||
Reference in New Issue
Block a user