import json,collections,unicodedata from pathlib import Path import xml.etree.ElementTree as ET from decimal import Decimal P=Path('scripts/quotation-import') plan=json.loads((P/'local-plan.json').read_text(encoding='utf-8')) db=ET.parse(P/'remote-snapshot.xml') def rows(tag):return [{e.tag:e.text or '' for e in x} for x in db.findall('./'+tag+'/row')] norm=lambda v:unicodedata.normalize('NFKC',v).casefold().strip() materials={x['code']:x for x in rows('materials')} units={x['name'].strip():x for x in rows('units')} customers=collections.defaultdict(list) for x in rows('customers'): if x['deleted']=='0':customers[norm(x['name'])].append(x) owners=[x for x in rows('users') if x['username']=='zhuli'] assert len(owners)==1 and owners[0]['nickname'].strip()=='朱莉' and owners[0]['status']=='0' owner=owners[0] new={x['code']:x for x in plan['new_products']} matched=set();created=set() for q in plan['quotes']: matches=customers[norm(q['customer'])] assert len(matches)<=1,(q['customer'],matches) if matches: q['customer']=matches[0]['name'];matched.add(q['customer']) assert matches[0]['owner_user_id']==owner['id'],('Existing customer owner differs',q['customer']) else:created.add(q['customer']) for x in q['items']: if x['name']=='黑果枸杞' and x['specification']=='120克(4g/罐×30)': candidate=materials['TC0020'] assert '黑果枸杞' in candidate['name'] and '120' in (candidate['name']+candidate['specification']) x['item_code']='TC0020' code=x['item_code'];unit=units[x['unit']] x['item_unit_id']=int(unit['id']) if code in materials: m=materials[code];assert m['status']=='0' x.update(item_id=int(m['id']),item_name=m['name'],expected_base_unit=int(m['unit_measure_id'])) else: assert code in new,code x.update(item_id=0,expected_base_unit=int(unit['id'])) new[code]['unit_id']=int(unit['id']) needed={x['item_code'] for q in plan['quotes'] for x in q['items'] if not x['item_id']} plan['new_products']=[x for code,x in new.items() if code in needed] plan.update(target='remote',owner_remote_id=int(owner['id']),matched_customers=len(matched),new_customers=len(created)) assert len(plan['quotes'])==345 and sum(len(q['items']) for q in plan['quotes'])==1702 assert sum(Decimal(q['total']) for q in plan['quotes'])==Decimal('15392805.71') (P/'remote-plan.json').write_text(json.dumps(plan,ensure_ascii=False,indent=2),encoding='utf-8') print('Remote prepared: 345 quotes, 1702 lines;',len(matched),'existing customers,',len(created),'new customers,',len(needed),'new products; owner',owner['username'],owner['id'])