542 lines
20 KiB
Python
542 lines
20 KiB
Python
"""财务子模块统计(订单/会员/其他充值),供 /jituan/houtai/*;旧 /houtai/* 不变。"""
|
||
from datetime import date, datetime
|
||
from decimal import Decimal
|
||
|
||
from django.db.models import Case, Count, DecimalField, Q, Sum, Value, When
|
||
from django.db.models.functions import TruncDate, TruncMonth, TruncYear
|
||
|
||
from jituan.constants import DATA_SCOPE_ALL
|
||
from jituan.models import ClubHuiyuanPrice
|
||
from jituan.services.club_context import (
|
||
filter_queryset_by_club,
|
||
resolve_club_id_from_request,
|
||
resolve_club_scope,
|
||
)
|
||
from jituan.services.club_penalty import filter_gsfenhong_qs, filter_penalty_qs
|
||
from orders.models import Order, Penalty
|
||
from products.czjilu_types import CZJILU_LEIXING_SHANGJIA, exclude_penalty_from_cz_qs
|
||
from products.models import Czjilu, Gsfenhong, Huiyuan, ShangpinLeixing
|
||
from rank.models import Bankuai
|
||
|
||
|
||
def _meta(request):
|
||
return {
|
||
'club_id': resolve_club_id_from_request(request),
|
||
'scope': resolve_club_scope(request),
|
||
}
|
||
|
||
|
||
def _parse_time_range(granularity, year, month, summary_date):
|
||
now = date.today()
|
||
if granularity == 'day':
|
||
if not year or not month:
|
||
return None, '按日统计需要年份和月份'
|
||
start_date = date(int(year), int(month), 1)
|
||
end_date = date(int(year), int(month) + 1, 1) if int(month) < 12 else date(int(year) + 1, 1, 1)
|
||
trunc_func = TruncDate('CreateTime')
|
||
if not summary_date:
|
||
summary_date = now.strftime('%Y-%m-%d')
|
||
summary_q = datetime.strptime(summary_date, '%Y-%m-%d').date()
|
||
elif granularity == 'month':
|
||
if not year:
|
||
return None, '按月统计需要年份'
|
||
y = int(year)
|
||
start_date = date(y, 1, 1)
|
||
end_date = date(y + 1, 1, 1)
|
||
trunc_func = TruncMonth('CreateTime')
|
||
if not summary_date:
|
||
summary_date = now.strftime('%Y-%m')
|
||
summary_q = datetime.strptime(summary_date + '-01', '%Y-%m-%d').date()
|
||
elif granularity == 'year':
|
||
y = int(year or now.year)
|
||
start_date = date(y, 1, 1)
|
||
end_date = date(y + 1, 1, 1)
|
||
trunc_func = TruncYear('CreateTime')
|
||
if not summary_date:
|
||
summary_date = str(y)
|
||
summary_q = date(y, 1, 1)
|
||
else:
|
||
return None, '无效的颗粒度'
|
||
|
||
start_dt = datetime.combine(start_date, datetime.min.time())
|
||
end_dt = datetime.combine(end_date, datetime.min.time())
|
||
return {
|
||
'start_dt': start_dt,
|
||
'end_dt': end_dt,
|
||
'trunc_func': trunc_func,
|
||
'summary_q': summary_q,
|
||
'granularity': granularity,
|
||
'year': int(year) if year is not None else None,
|
||
'month': int(month) if month is not None else None,
|
||
}, None
|
||
|
||
|
||
def _summary_date_filter(granularity, summary_q, field_prefix='CreateTime'):
|
||
if granularity == 'day':
|
||
return {f'{field_prefix}__date': summary_q}
|
||
if granularity == 'month':
|
||
return {f'{field_prefix}__year': summary_q.year, f'{field_prefix}__month': summary_q.month}
|
||
return {f'{field_prefix}__year': summary_q.year}
|
||
|
||
|
||
def _penalty_trunc_func(granularity):
|
||
if granularity == 'day':
|
||
return TruncDate('UpdateTime')
|
||
if granularity == 'month':
|
||
return TruncMonth('UpdateTime')
|
||
return TruncYear('UpdateTime')
|
||
|
||
|
||
def _penalty_fenhong_aggregates():
|
||
"""罚款分红只统计已入账(BonusCredited),与 process_fadan_fenhong 一致。"""
|
||
zero = Value(Decimal('0.00'), output_field=DecimalField(max_digits=12, decimal_places=2))
|
||
return {
|
||
'fenhong_amount': Sum(
|
||
Case(
|
||
When(BonusCredited=True, then='ApplicantBonusAmount'),
|
||
default=zero,
|
||
output_field=DecimalField(max_digits=12, decimal_places=2),
|
||
)
|
||
),
|
||
'fenhong_count': Count(
|
||
'id',
|
||
filter=Q(BonusCredited=True, ApplicantBonusAmount__gt=0),
|
||
),
|
||
}
|
||
|
||
|
||
def _czjilu_finance_qs(request, start_dt, end_dt, cz_types):
|
||
"""充值财务 czjilu:已支付;type4 排除罚款误标。"""
|
||
qs = filter_queryset_by_club(
|
||
Czjilu.query.filter(
|
||
CreateTime__gte=start_dt,
|
||
CreateTime__lt=end_dt,
|
||
leixing__in=cz_types,
|
||
zhuangtai=3,
|
||
),
|
||
request,
|
||
)
|
||
if CZJILU_LEIXING_SHANGJIA in cz_types:
|
||
qs = exclude_penalty_from_cz_qs(qs)
|
||
return qs
|
||
|
||
|
||
def _czjilu_summary_qs(request, lx, granularity, summary_q):
|
||
filter_kwargs = {'leixing': lx, 'zhuangtai': 3}
|
||
filter_kwargs.update(_summary_date_filter(granularity, summary_q))
|
||
qs = filter_queryset_by_club(Czjilu.query.filter(**filter_kwargs), request)
|
||
if lx == CZJILU_LEIXING_SHANGJIA:
|
||
qs = exclude_penalty_from_cz_qs(qs)
|
||
return qs
|
||
|
||
|
||
def build_order_types_payload():
|
||
types = ShangpinLeixing.query.filter(shenhezhuangtai=1).values('id', 'jieshao')
|
||
return list(types)
|
||
|
||
|
||
def build_order_finance_payload(
|
||
request,
|
||
granularity,
|
||
year,
|
||
month,
|
||
type_id=0,
|
||
order_source=0,
|
||
summary_date=None,
|
||
):
|
||
parsed, err = _parse_time_range(granularity, year, month, summary_date)
|
||
if err:
|
||
return None, err
|
||
|
||
start_dt = parsed['start_dt']
|
||
end_dt = parsed['end_dt']
|
||
trunc_func = parsed['trunc_func']
|
||
summary_q = parsed['summary_q']
|
||
granularity = parsed['granularity']
|
||
|
||
filters = {
|
||
'CreateTime__gte': start_dt,
|
||
'CreateTime__lt': end_dt,
|
||
'Status__in': [1, 2, 3, 4, 5, 6, 7, 8],
|
||
}
|
||
if int(type_id or 0) != 0:
|
||
filters['ProductTypeID'] = type_id
|
||
if int(order_source or 0) in [1, 2]:
|
||
filters['Platform'] = int(order_source)
|
||
|
||
order_base = filter_queryset_by_club(
|
||
Order.query.filter(**filters), request, club_field='ClubID',
|
||
)
|
||
qs = order_base.annotate(period=trunc_func).values('period').annotate(
|
||
order_count=Count('id'),
|
||
order_amount=Sum('Amount'),
|
||
success_count=Count('id', filter=Q(Status=3)),
|
||
success_amount=Sum('Amount', filter=Q(Status=3)),
|
||
refund_count=Count('id', filter=Q(Status=5)),
|
||
PlayerCommission_sum=Sum('PlayerCommission', filter=Q(Status=3)),
|
||
dianpu_fenhong_sum=Sum('pingtai_kuozhan__ShopIncome', filter=Q(Status=3, Platform=1)),
|
||
platform_success_amount=Sum('Amount', filter=Q(Status=3, Platform=1)),
|
||
merchant_success_amount=Sum('Amount', filter=Q(Status=3, Platform=2)),
|
||
platform_dashou=Sum('PlayerCommission', filter=Q(Status=3, Platform=1)),
|
||
merchant_dashou=Sum('PlayerCommission', filter=Q(Status=3, Platform=2)),
|
||
).order_by('period')
|
||
|
||
time_series = []
|
||
for item in qs:
|
||
period_str = (
|
||
item['period'].strftime('%Y-%m-%d') if granularity == 'day'
|
||
else item['period'].strftime('%Y-%m') if granularity == 'month'
|
||
else item['period'].strftime('%Y')
|
||
)
|
||
platform_profit = (item['platform_success_amount'] or 0) - (item['platform_dashou'] or 0) - (item['dianpu_fenhong_sum'] or 0)
|
||
merchant_profit = (item['merchant_success_amount'] or 0) - (item['merchant_dashou'] or 0)
|
||
time_series.append({
|
||
'date': period_str,
|
||
'order_count': item['order_count'],
|
||
'order_amount': float(item['order_amount'] or 0),
|
||
'success_count': item['success_count'],
|
||
'success_amount': float(item['success_amount'] or 0),
|
||
'refund_count': item['refund_count'],
|
||
'dashou_fencheng': float(item['PlayerCommission_sum'] or 0),
|
||
'dianpu_fenhong': float(item['dianpu_fenhong_sum'] or 0),
|
||
'profit': round(float(platform_profit + merchant_profit), 2),
|
||
})
|
||
|
||
summary_qs = filter_queryset_by_club(Order.query.filter(**filters), request, club_field='ClubID')
|
||
total_order_count = summary_qs.count()
|
||
total_order_amount = summary_qs.aggregate(s=Sum('Amount'))['s'] or 0
|
||
total_success_count = summary_qs.filter(Status=3).count()
|
||
total_success_amount = summary_qs.filter(Status=3).aggregate(s=Sum('Amount'))['s'] or 0
|
||
total_refund_count = summary_qs.filter(Status=5).count()
|
||
total_dashou = summary_qs.filter(Status=3).aggregate(s=Sum('PlayerCommission'))['s'] or 0
|
||
total_dianpu_fenhong = summary_qs.filter(Status=3, Platform=1).aggregate(
|
||
s=Sum('pingtai_kuozhan__ShopIncome'),
|
||
)['s'] or 0
|
||
platform_amount = summary_qs.filter(Status=3, Platform=1).aggregate(s=Sum('Amount'))['s'] or 0
|
||
merchant_amount = summary_qs.filter(Status=3, Platform=2).aggregate(s=Sum('Amount'))['s'] or 0
|
||
platform_dashou_sum = summary_qs.filter(Status=3, Platform=1).aggregate(s=Sum('PlayerCommission'))['s'] or 0
|
||
merchant_dashou_sum = summary_qs.filter(Status=3, Platform=2).aggregate(s=Sum('PlayerCommission'))['s'] or 0
|
||
profit_platform = platform_amount - platform_dashou_sum - total_dianpu_fenhong
|
||
profit_merchant = merchant_amount - merchant_dashou_sum
|
||
total_profit = profit_platform + profit_merchant
|
||
|
||
data = {
|
||
**_meta(request),
|
||
'time_series': time_series,
|
||
'summary': {
|
||
'total_order_count': total_order_count,
|
||
'total_order_amount': round(float(total_order_amount), 2),
|
||
'total_success_count': total_success_count,
|
||
'total_success_amount': round(float(total_success_amount), 2),
|
||
'total_refund_count': total_refund_count,
|
||
'total_PlayerCommission': round(float(total_dashou), 2),
|
||
'total_dianpu_fenhong': round(float(total_dianpu_fenhong), 2),
|
||
'total_profit': round(float(total_profit), 2),
|
||
},
|
||
}
|
||
return data, None
|
||
|
||
|
||
def build_chongzhi_finance_payload(request, granularity, year, month, types=None, summary_date=None):
|
||
if types is None:
|
||
types = [2, 3, 4, 5, 6]
|
||
if isinstance(types, list) and len(types) == 0:
|
||
types = [2, 3, 4, 5, 6]
|
||
|
||
parsed, err = _parse_time_range(granularity, year, month, summary_date)
|
||
if err:
|
||
return None, err
|
||
|
||
start_dt = parsed['start_dt']
|
||
end_dt = parsed['end_dt']
|
||
trunc_func = parsed['trunc_func']
|
||
summary_q = parsed['summary_q']
|
||
granularity = parsed['granularity']
|
||
|
||
time_series_map = {}
|
||
|
||
def ensure_date(ds):
|
||
if ds not in time_series_map:
|
||
time_series_map[ds] = {}
|
||
return time_series_map[ds]
|
||
|
||
cz_types = [t for t in types if t in [2, 3, 4, 5]]
|
||
if cz_types:
|
||
cz_qs = _czjilu_finance_qs(request, start_dt, end_dt, cz_types).annotate(
|
||
period=trunc_func,
|
||
).values('period', 'leixing').annotate(
|
||
total_count=Count('id'),
|
||
total_amount=Sum('jine'),
|
||
).order_by('period', 'leixing')
|
||
|
||
for item in cz_qs:
|
||
period_str = (
|
||
item['period'].strftime('%Y-%m-%d') if granularity == 'day'
|
||
else item['period'].strftime('%Y-%m') if granularity == 'month'
|
||
else item['period'].strftime('%Y')
|
||
)
|
||
lx = item['leixing']
|
||
amount = float(item['total_amount'] or 0)
|
||
count = item['total_count']
|
||
profit = amount if lx == 3 else 0.0
|
||
day_data = ensure_date(period_str)
|
||
day_data[str(lx)] = {
|
||
'count': count,
|
||
'amount': amount,
|
||
'profit': profit,
|
||
'fenhong_count': 0,
|
||
'fenhong_amount': 0.0,
|
||
}
|
||
|
||
if 6 in types:
|
||
penalty_trunc = _penalty_trunc_func(granularity)
|
||
penalty_qs = filter_penalty_qs(
|
||
Penalty.query.filter(
|
||
UpdateTime__gte=start_dt,
|
||
UpdateTime__lt=end_dt,
|
||
Status=2,
|
||
),
|
||
request,
|
||
).annotate(period=penalty_trunc).values('period').annotate(
|
||
penalty_count=Count('id'),
|
||
penalty_amount=Sum('FineAmount'),
|
||
**_penalty_fenhong_aggregates(),
|
||
).order_by('period')
|
||
|
||
for item in penalty_qs:
|
||
period_str = (
|
||
item['period'].strftime('%Y-%m-%d') if granularity == 'day'
|
||
else item['period'].strftime('%Y-%m') if granularity == 'month'
|
||
else item['period'].strftime('%Y')
|
||
)
|
||
day_data = ensure_date(period_str)
|
||
penalty_amt = float(item['penalty_amount'] or 0)
|
||
fenhong_amt = float(item['fenhong_amount'] or 0)
|
||
day_data['6'] = {
|
||
'count': item['penalty_count'],
|
||
'amount': penalty_amt,
|
||
'profit': round(penalty_amt - fenhong_amt, 2),
|
||
'fenhong_count': item['fenhong_count'],
|
||
'fenhong_amount': fenhong_amt,
|
||
}
|
||
|
||
time_series = []
|
||
for period_str in sorted(time_series_map.keys()):
|
||
entry = {'date': period_str, 'types': {}}
|
||
for type_code in sorted(time_series_map[period_str].keys()):
|
||
entry['types'][type_code] = time_series_map[period_str][type_code]
|
||
time_series.append(entry)
|
||
|
||
summary_result = {'by_type': {}, 'total_count': 0, 'total_amount': 0.0, 'total_profit': 0.0}
|
||
|
||
for lx in cz_types:
|
||
agg = _czjilu_summary_qs(request, lx, granularity, summary_q).aggregate(
|
||
count=Count('id'), amount=Sum('jine'),
|
||
)
|
||
count = agg['count'] or 0
|
||
amount = float(agg['amount'] or 0)
|
||
profit = amount if lx == 3 else 0.0
|
||
summary_result['by_type'][str(lx)] = {
|
||
'count': count,
|
||
'amount': round(amount, 2),
|
||
'profit': round(profit, 2),
|
||
'fenhong_count': 0,
|
||
'fenhong_amount': 0.0,
|
||
}
|
||
summary_result['total_count'] += count
|
||
summary_result['total_amount'] += amount
|
||
summary_result['total_profit'] += profit
|
||
|
||
if 6 in types:
|
||
penalty_filter = {'Status': 2}
|
||
penalty_filter.update(_summary_date_filter(granularity, summary_q, field_prefix='UpdateTime'))
|
||
agg = filter_penalty_qs(Penalty.query.filter(**penalty_filter), request).aggregate(
|
||
count=Count('id'),
|
||
amount=Sum('FineAmount'),
|
||
**_penalty_fenhong_aggregates(),
|
||
)
|
||
penalty_count = agg['count'] or 0
|
||
penalty_amount = float(agg['amount'] or 0)
|
||
fh_amount = float(agg['fenhong_amount'] or 0)
|
||
fh_count = agg['fenhong_count'] or 0
|
||
profit = round(penalty_amount - fh_amount, 2)
|
||
summary_result['by_type']['6'] = {
|
||
'count': penalty_count,
|
||
'amount': round(penalty_amount, 2),
|
||
'profit': profit,
|
||
'fenhong_count': fh_count,
|
||
'fenhong_amount': round(fh_amount, 2),
|
||
}
|
||
summary_result['total_count'] += penalty_count
|
||
summary_result['total_amount'] += penalty_amount
|
||
summary_result['total_profit'] += profit
|
||
|
||
summary_result['total_amount'] = round(summary_result['total_amount'], 2)
|
||
summary_result['total_profit'] = round(summary_result['total_profit'], 2)
|
||
|
||
return {
|
||
**_meta(request),
|
||
'time_series': time_series,
|
||
'summary': summary_result,
|
||
}, None
|
||
|
||
|
||
def build_huiyuan_bankuai_payload(request):
|
||
club_id = resolve_club_id_from_request(request)
|
||
price_map = {}
|
||
if resolve_club_scope(request) != DATA_SCOPE_ALL:
|
||
for row in ClubHuiyuanPrice.query.filter(club_id=club_id, is_enabled=True):
|
||
price_map[row.huiyuan_id] = {
|
||
'jiage': float(row.jiage or 0),
|
||
'guanshifc': float(row.guanshifc or 0),
|
||
'zuzhangfc': float(row.zuzhangfc or 0),
|
||
}
|
||
|
||
bankuai_list = []
|
||
for bk in Bankuai.query.all():
|
||
members = []
|
||
for m in Huiyuan.query.filter(bankuai=bk).values('huiyuan_id', 'jieshao', 'bankuai_id'):
|
||
item = dict(m)
|
||
if m['huiyuan_id'] in price_map:
|
||
item['club_price'] = price_map[m['huiyuan_id']]
|
||
members.append(item)
|
||
bankuai_list.append({
|
||
'bankuai_id': bk.bankuai_id,
|
||
'mingcheng': bk.mingcheng,
|
||
'members': members,
|
||
})
|
||
|
||
return {**_meta(request), 'bankuai_list': bankuai_list}
|
||
|
||
|
||
def build_huiyuan_stats_payload(
|
||
request,
|
||
huiyuan_id,
|
||
granularity,
|
||
year,
|
||
month,
|
||
include_guanshi=False,
|
||
include_zuzhang=False,
|
||
summary_date=None,
|
||
):
|
||
if not huiyuan_id:
|
||
return None, '缺少会员ID'
|
||
|
||
parsed, err = _parse_time_range(granularity, year, month, summary_date)
|
||
if err:
|
||
return None, err
|
||
|
||
start_dt = parsed['start_dt']
|
||
end_dt = parsed['end_dt']
|
||
trunc_func = parsed['trunc_func']
|
||
summary_q = parsed['summary_q']
|
||
granularity = parsed['granularity']
|
||
|
||
chongzhi_filter = {
|
||
'huiyuan_id': huiyuan_id,
|
||
'leixing': 1,
|
||
'zhuangtai': 3,
|
||
'CreateTime__gte': start_dt,
|
||
'CreateTime__lt': end_dt,
|
||
}
|
||
fenhong_filter = {
|
||
'huiyuan_id': huiyuan_id,
|
||
'CreateTime__gte': start_dt,
|
||
'CreateTime__lt': end_dt,
|
||
}
|
||
|
||
chongzhi_qs = filter_queryset_by_club(
|
||
Czjilu.query.filter(**chongzhi_filter), request,
|
||
).annotate(period=trunc_func).values('period').annotate(
|
||
chongzhi_count=Count('id'),
|
||
chongzhi_amount=Sum('jine'),
|
||
).order_by('period')
|
||
|
||
fenhong_qs = None
|
||
if include_guanshi or include_zuzhang:
|
||
fenhong_agg = {}
|
||
if include_guanshi:
|
||
fenhong_agg['guanshi_amount'] = Sum('fenhong')
|
||
if include_zuzhang:
|
||
fenhong_agg['zuzhang_amount'] = Sum('zuzhang_fenhong')
|
||
fenhong_qs = filter_gsfenhong_qs(
|
||
Gsfenhong.query.filter(**fenhong_filter), request,
|
||
).annotate(period=trunc_func).values('period').annotate(**fenhong_agg).order_by('period')
|
||
|
||
data_map = {}
|
||
for item in chongzhi_qs:
|
||
period_str = (
|
||
item['period'].strftime('%Y-%m-%d') if granularity == 'day'
|
||
else item['period'].strftime('%Y-%m') if granularity == 'month'
|
||
else item['period'].strftime('%Y')
|
||
)
|
||
data_map[period_str] = {
|
||
'chongzhi_count': item['chongzhi_count'],
|
||
'chongzhi_amount': float(item['chongzhi_amount'] or 0),
|
||
}
|
||
|
||
if fenhong_qs:
|
||
for item in fenhong_qs:
|
||
period_str = (
|
||
item['period'].strftime('%Y-%m-%d') if granularity == 'day'
|
||
else item['period'].strftime('%Y-%m') if granularity == 'month'
|
||
else item['period'].strftime('%Y')
|
||
)
|
||
if period_str not in data_map:
|
||
data_map[period_str] = {'chongzhi_count': 0, 'chongzhi_amount': 0.0}
|
||
if include_guanshi:
|
||
data_map[period_str]['guanshi_amount'] = float(item.get('guanshi_amount') or 0)
|
||
if include_zuzhang:
|
||
data_map[period_str]['zuzhang_amount'] = float(item.get('zuzhang_amount') or 0)
|
||
|
||
time_series = []
|
||
for period_str, vals in data_map.items():
|
||
guanshi = vals.get('guanshi_amount', 0) if include_guanshi else 0
|
||
zuzhang = vals.get('zuzhang_amount', 0) if include_zuzhang else 0
|
||
vals['shouyi'] = round(vals['chongzhi_amount'] - guanshi - zuzhang, 2)
|
||
vals['date'] = period_str
|
||
time_series.append(vals)
|
||
time_series.sort(key=lambda x: x['date'])
|
||
|
||
summary_chongzhi_filter = dict(chongzhi_filter)
|
||
summary_chongzhi_filter.pop('CreateTime__gte', None)
|
||
summary_chongzhi_filter.pop('CreateTime__lt', None)
|
||
summary_chongzhi_filter.update(_summary_date_filter(granularity, summary_q))
|
||
summary_chongzhi = filter_queryset_by_club(
|
||
Czjilu.query.filter(**summary_chongzhi_filter), request,
|
||
).aggregate(total_count=Count('id'), total_amount=Sum('jine'))
|
||
total_chongzhi_count = summary_chongzhi['total_count'] or 0
|
||
total_chongzhi_amount = float(summary_chongzhi['total_amount'] or 0)
|
||
|
||
total_guanshi = 0.0
|
||
total_zuzhang = 0.0
|
||
if include_guanshi or include_zuzhang:
|
||
summary_fenhong_filter = dict(fenhong_filter)
|
||
summary_fenhong_filter.pop('CreateTime__gte', None)
|
||
summary_fenhong_filter.pop('CreateTime__lt', None)
|
||
summary_fenhong_filter.update(_summary_date_filter(granularity, summary_q))
|
||
fenhong_agg = {}
|
||
if include_guanshi:
|
||
fenhong_agg['guanshi_sum'] = Sum('fenhong')
|
||
if include_zuzhang:
|
||
fenhong_agg['zuzhang_sum'] = Sum('zuzhang_fenhong')
|
||
summary_fenhong = filter_gsfenhong_qs(
|
||
Gsfenhong.query.filter(**summary_fenhong_filter), request,
|
||
).aggregate(**fenhong_agg)
|
||
total_guanshi = float(summary_fenhong.get('guanshi_sum') or 0)
|
||
total_zuzhang = float(summary_fenhong.get('zuzhang_sum') or 0)
|
||
|
||
total_shouyi = round(total_chongzhi_amount - total_guanshi - total_zuzhang, 2)
|
||
|
||
return {
|
||
**_meta(request),
|
||
'time_series': time_series,
|
||
'summary': {
|
||
'total_chongzhi_count': total_chongzhi_count,
|
||
'total_chongzhi_amount': total_chongzhi_amount,
|
||
'total_guanshi_fenhong': total_guanshi,
|
||
'total_zuzhang_fenhong': total_zuzhang,
|
||
'total_shouyi': total_shouyi,
|
||
},
|
||
}, None
|