1
0
forked from erp-dev/erp
Files
erpnew/printing/management/commands/backfill_printing_order_kd_riqi.py

95 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
from django.core.management.base import BaseCommand
from api_v1.external_datetime import parse_external_china_datetime
from printing.models import PrintingOrder
class Command(BaseCommand):
help = '从 PrintingOrder.external_raw.first_record.KdRiQi 批量回填或修正 kd_riqi'
def add_arguments(self, parser):
parser.add_argument('--dry-run', action='store_true', help='只统计不写入')
parser.add_argument('--batch-size', type=int, default=1000, help='批量处理大小')
parser.add_argument('--limit', type=int, default=None, help='最多处理多少条候选记录')
parser.add_argument('--merchant-id', type=int, default=None, help='限定商户ID')
parser.add_argument('--external-order-id', default=None, help='限定外部订单编号')
parser.add_argument('--overwrite', action='store_true', help='覆盖已有 kd_riqi用于修正历史错误值')
parser.add_argument('--update-outgoing-date', action='store_true', help='同时用 KdRiQi 修正 outgoing_date')
def handle(self, *args, **options):
dry_run = bool(options['dry_run'])
batch_size = max(1, int(options['batch_size'] or 1000))
limit = options.get('limit')
overwrite = bool(options['overwrite'])
update_outgoing_date = bool(options['update_outgoing_date'])
queryset = PrintingOrder.objects.exclude(external_raw={})
if not overwrite:
queryset = queryset.filter(kd_riqi__isnull=True)
merchant_id = options.get('merchant_id')
if merchant_id:
queryset = queryset.filter(merchant_id=merchant_id)
external_order_id = (options.get('external_order_id') or '').strip()
if external_order_id:
queryset = queryset.filter(external_order_id=external_order_id)
queryset = queryset.order_by('id').only('id', 'external_raw', 'kd_riqi', 'outgoing_date')
if limit is not None:
queryset = queryset[: max(0, int(limit))]
matched = 0
updated = 0
skipped_missing = 0
skipped_invalid = 0
pending_updates = []
update_fields = ['kd_riqi']
if update_outgoing_date:
update_fields.append('outgoing_date')
for order in queryset.iterator(chunk_size=batch_size):
matched += 1
try:
first_record = (order.external_raw or {}).get('first_record') or {}
raw_value = first_record.get('KdRiQi')
except AttributeError:
raw_value = None
if not raw_value:
skipped_missing += 1
continue
parsed = parse_external_china_datetime(raw_value)
if parsed is None:
skipped_invalid += 1
continue
order.kd_riqi = parsed
if update_outgoing_date:
order.outgoing_date = parsed
updated += 1
if dry_run:
continue
pending_updates.append(order)
if len(pending_updates) >= batch_size:
PrintingOrder.objects.bulk_update(pending_updates, update_fields)
pending_updates = []
if pending_updates:
PrintingOrder.objects.bulk_update(pending_updates, update_fields)
payload = {
'dry_run': dry_run,
'matched': matched,
'updated': 0 if dry_run else updated,
'would_update': updated if dry_run else 0,
'skipped_missing': skipped_missing,
'skipped_invalid': skipped_invalid,
'overwrite': overwrite,
'update_outgoing_date': update_outgoing_date,
}
self.stdout.write(self.style.SUCCESS(json.dumps(payload, ensure_ascii=False)))