72 lines
2.1 KiB
Python
72 lines
2.1 KiB
Python
"""商家订单维度统计(从订单表聚合,保证金额准确)。"""
|
||
from decimal import Decimal
|
||
|
||
from django.db.models import Count, Sum
|
||
|
||
from merchant_ops.models import MerchantOrderDispatch
|
||
from orders.models import MerchantOrderExt
|
||
|
||
STATUS_PENDING = 8
|
||
STATUS_COMPLETED = 3
|
||
STATUS_REFUNDED = 5
|
||
|
||
|
||
def _money_str(val):
|
||
if val is None:
|
||
return '0.00'
|
||
return str(val)
|
||
|
||
|
||
def _agg_amount(qs, status=None):
|
||
if status is not None:
|
||
qs = qs.filter(Order__Status=status)
|
||
row = qs.aggregate(cnt=Count('id'), amt=Sum('Order__Amount'))
|
||
return int(row['cnt'] or 0), _money_str(row['amt'])
|
||
|
||
|
||
def build_merchant_order_stats(base_qs):
|
||
"""
|
||
base_qs: MerchantOrderExt queryset(已含商家/客服范围与时间等筛选)
|
||
返回订单统计字典。
|
||
"""
|
||
pending_cnt, pending_amt = _agg_amount(base_qs, STATUS_PENDING)
|
||
completed_cnt, completed_amt = _agg_amount(base_qs, STATUS_COMPLETED)
|
||
refund_cnt, refund_amt = _agg_amount(base_qs, STATUS_REFUNDED)
|
||
dispatch_cnt, dispatch_amt = _agg_amount(base_qs, None)
|
||
|
||
return {
|
||
'pending_count': pending_cnt,
|
||
'pending_amount': pending_amt,
|
||
'completed_count': completed_cnt,
|
||
'completed_amount': completed_amt,
|
||
'refund_count': refund_cnt,
|
||
'refund_amount': refund_amt,
|
||
'dispatch_count': dispatch_cnt,
|
||
'dispatch_amount': dispatch_amt,
|
||
}
|
||
|
||
|
||
def merchant_ext_qs(merchant_id, zhuangtai_list=None):
|
||
qs = MerchantOrderExt.query.filter(MerchantID=merchant_id).select_related('Order')
|
||
if zhuangtai_list is not None:
|
||
qs = qs.filter(Order__Status__in=zhuangtai_list)
|
||
return qs
|
||
|
||
|
||
def filter_by_staff_member(qs, merchant_id, staff_member_id):
|
||
if not staff_member_id:
|
||
return qs
|
||
try:
|
||
mid = int(staff_member_id)
|
||
except (TypeError, ValueError):
|
||
return qs.none()
|
||
order_ids = list(
|
||
MerchantOrderDispatch.query.filter(
|
||
merchant_id=merchant_id,
|
||
staff_member_id=mid,
|
||
).values_list('order_id', flat=True)
|
||
)
|
||
if not order_ids:
|
||
return qs.none()
|
||
return qs.filter(Order__OrderID__in=order_ids)
|