1
0
forked from erp-dev/erp

feat: shipment customer aou

This commit is contained in:
2026-03-30 22:03:14 +08:00
parent 38f40644a3
commit aff10b8925
7 changed files with 690 additions and 6 deletions

View File

@@ -7,11 +7,46 @@ from __future__ import annotations
from typing import List
from django.db import transaction
from django.db.models import QuerySet
from django.db.models import Count, Exists, IntegerField, OuterRef, QuerySet, Subquery
from django.db.models.functions import Coalesce
from shipment.models import ExternalFinishedProduct, SalesItem, Shipment
def get_customers_with_unshipped_sales_items(*, merchant) -> QuerySet:
"""
查询当前商户下“存在未出货销售品”的客户列表。
返回 Customer 查询集,并附带:
- unshipped_sales_items_count: 该客户未出货销售品数量
"""
from basic_info.models import Customer
base_sales_items = SalesItem.objects.filter(
merchant=merchant,
shipment__isnull=True,
customer_id=OuterRef("pk"),
)
count_subquery = (
base_sales_items.values("customer_id")
.annotate(total=Count("id"))
.values("total")[:1]
)
return (
Customer.objects.filter(merchant=merchant)
.annotate(has_unshipped_sales_items=Exists(base_sales_items))
.filter(has_unshipped_sales_items=True)
.annotate(
unshipped_sales_items_count=Coalesce(
Subquery(count_subquery, output_field=IntegerField()),
0,
)
)
.order_by("id")
)
def get_sales_items_by_printing_order(
printing_order_id: int,
include_already_has_shipment: bool = False,
@@ -43,6 +78,28 @@ def get_sales_items_by_printing_order(
return queryset.select_related("shipment").order_by("id")
def get_sales_items_by_customer(
*,
merchant,
customer_id: int,
include_already_has_shipment: bool = False,
) -> QuerySet[SalesItem]:
"""
通过客户ID查询对应销售品。
仅返回当前商户下、customer_id 匹配的销售品。
"""
queryset = SalesItem.objects.filter(
merchant=merchant,
customer_id=customer_id,
)
if not include_already_has_shipment:
queryset = queryset.filter(shipment__isnull=True)
return queryset.select_related("shipment").order_by("id")
@transaction.atomic
def create_shipment(
customer_id: int,