修复财务接口:统一date字段查询,板子全平台合计

This commit is contained in:
XingQue
2026-06-24 22:08:40 +08:00
parent 79f2d4f020
commit 8e5db24bad
5 changed files with 329 additions and 335 deletions

View File

@@ -1,64 +1,68 @@
"""
一键恢复财务「每日收入」统计repair_wechat_income 搞乱后执行)
恢复 daily_income_stat每日收入统计表全表数据
只重建
- daily_income_stat(每日收入统计表,财务看板读这个)
- platform_income_log支付幂等日志
repair_wechat_income 对该表的破坏
- 把扫描到的每笔订单/充值重复写入 daily_income_stat
- 金额记到「执行命令那天」,不是真实支付日
- 含退款单(Status=5)也被当成收入加进去
绝不碰:
- daily_payout_stat每日支出repair 没动过)
- szjilu收支记录表已废弃
- 订单 / 充值业务表
本命令按 platform_income_log + 无日志的已支付单,重建整张 daily_income_stat。
不碰 daily_payout_stat,不碰 szjilu不删订单。
用法:
预览python manage.py restore_finance_stats
执行python manage.py restore_finance_stats --yes
"""
from datetime import date
from django.core.management.base import BaseCommand
from django.db.models import Sum
from jituan.services.szjilu_accounting import restore_finance_daily_stats
from config.models import DailyIncomeStat, DailyPayoutStat
from jituan.services.szjilu_accounting import rebuild_daily_income_stat_table
class Command(BaseCommand):
help = '从订单/充值重建 daily_income_stat(恢复 repair 搞乱的每日收入'
help = '恢复 daily_income_stat 全表(财务四个板子读这张表'
def add_arguments(self, parser):
parser.add_argument('--since-year', type=int, default=2020, help='从哪年开始重算')
parser.add_argument('--until-year', type=int, default=0, help='到哪年,默认今年')
parser.add_argument('--yes', action='store_true', help='确认写入数据库')
def handle(self, *args, **options):
until_year = options['until_year'] or date.today().year
since_year = options['since_year'] or 2020
dry_run = not options['yes']
if dry_run:
self.stdout.write(self.style.WARNING(
'【预览】未改数据库。下面「恢复后」应是正确每日收入合计。\n'
))
self.stdout.write(self.style.WARNING('【预览】未改数据库\n'))
else:
self.stdout.write(self.style.WARNING(
'【执行】正在从订单/充值重建 daily_income_stat...\n'
))
self.stdout.write(self.style.WARNING('【执行】重建 daily_income_stat...\n'))
r = restore_finance_daily_stats(since_year, until_year, dry_run=dry_run)
r = rebuild_daily_income_stat_table(dry_run=dry_run)
self.stdout.write(f'范围: {r["since_year"]} ~ {r["until_year"]}')
self.stdout.write(f' 支付笔数: {r["after_count"]}')
self.stdout.write(f' 支付笔数(去重): {r["payment_rows"]}')
self.stdout.write(f' 其中日志: {r["from_log"]}')
self.stdout.write(f' 补漏订单: {r["gap_orders"]}')
self.stdout.write(f' 补漏充值: {r["gap_cz"]}')
self.stdout.write(f' 日统计行数: {r["daily_rows"]}')
self.stdout.write(f' 恢复前 daily 合计: {r["before_daily_total"]:.2f}')
self.stdout.write(self.style.SUCCESS(
f' 恢复后 daily 合计: {r.get("after_daily_total", r["after_total"]):.2f}'
f' 恢复后 daily 合计: {r["after_daily_total"]:.2f}'
))
self.stdout.write(f' 其中今日收入: {r["today_amount"]:.2f} 元 / {r["today_count"]}')
payout_today = DailyPayoutStat.objects.filter(date=date.today()).aggregate(
t=Sum('total_amount'),
)['t'] or 0
self.stdout.write(
f' (未动)今日支出表: {float(payout_today):.2f}'
)
if dry_run:
self.stdout.write(self.style.WARNING(
'\n数字对的话执行:\n'
' python manage.py restore_finance_stats --yes'
'\n预览数字合理后执行:\n'
' python manage.py restore_finance_stats --yes\n'
'然后 push 代码并刷新财务页。'
))
else:
check = DailyIncomeStat.objects.aggregate(t=Sum('total_amount'))['t'] or 0
self.stdout.write(self.style.SUCCESS(
'\n完成。daily_payout_stat 未动。请 push 代码后刷新财务页。'
f'\n完成。数据库 daily_income_stat 合计: {float(check):.2f}'
))