1
0
forked from erp-dev/erp

feat: shipment change && version modelize

This commit is contained in:
2026-07-09 23:03:22 +08:00
parent 36e4bb6de6
commit 48e4782e1e
23 changed files with 947 additions and 36 deletions

View File

@@ -0,0 +1,94 @@
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)))