"""Customer assignment correction requested by the user; no financial amount changes."""
|
import sys,json
|
from pathlib import Path
|
from decimal import Decimal
|
P=Path(__file__).parent
|
sys.path.insert(0,str(P.parent/'iqc-import-20261012/deps'))
|
import pymysql
|
plan=json.loads((P/'import-plan.json').read_text(encoding='utf8'))
|
regroup=json.loads((P/'source-order-regroup-result.json').read_text(encoding='utf8'))
|
assert not (P/'ecommerce-customer-correction-result.json').exists(),'Correction already completed; verify current data.'
|
selected=[(g,r) for g,r in zip(plan['groups'],regroup['groups']) if '(电商)' in g['original'] or g['customer_name']=='电商']
|
assert len(selected)==8 and sum(len(r['orders']) for g,r in selected)==8
|
docids=[r['contract_id'] for r in regroup['groups']]
|
c=pymysql.connect(host='36.213.150.237',port=10000,user='root',password=sys.stdin.readline().strip(),database='mom-hm',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor,autocommit=False)
|
try:
|
with c.cursor() as q:
|
q.execute('SELECT DATABASE() db,NOW() now,GET_LOCK(%s,10) locked',('sales-ledger-202609',));state=q.fetchone();assert state['db']=='mom-hm' and state['locked']==1
|
q.execute("SELECT * FROM crm_customer WHERE name='电商' AND deleted=0 FOR UPDATE");found=q.fetchall();assert len(found)==1 and found[0]['owner_user_id']==291;target=found[0]
|
q.execute('SELECT COUNT(*) n FROM crm_permission WHERE biz_type=2 AND biz_id=%s AND user_id=291 AND level=1 AND deleted=0',(target['id'],));assert q.fetchone()['n']==1
|
# Capture scoped headers plus all live detail and permission records before changing customer fields.
|
backup={'state':state,'target_customer':target,'tables':{}}
|
for t,field in [('erp_sale_order','contract_id'),('crm_contract','id'),('crm_sale_quotation','contract_id'),('crm_invoice','contract_id'),('crm_receivable','contract_id'),('crm_receivable_plan','contract_id')]:
|
q.execute('SELECT * FROM `'+t+'` WHERE `'+field+'` IN ('+','.join(['%s']*len(docids))+') AND deleted=0 ORDER BY id',docids);backup['tables'][t]=q.fetchall()
|
for t in ['crm_contract_product','crm_sale_quotation_product','erp_sale_order_items','crm_permission']:
|
q.execute('SELECT * FROM `'+t+'` WHERE deleted=0 ORDER BY id');backup['tables'][t]=q.fetchall()
|
q.execute('SELECT * FROM crm_customer WHERE id IN (%s,%s) ORDER BY id',(target['id'],1381));backup['tables']['crm_customer']=q.fetchall()
|
(P/'ecommerce-customer-correction-before.json').write_text(json.dumps(backup,ensure_ascii=False,default=str,indent=2),encoding='utf8')
|
tables={t:{r['id']:r for r in rs} for t,rs in backup['tables'].items()}
|
affected={t:set() for t in ['erp_sale_order','crm_contract','crm_sale_quotation','crm_invoice','crm_receivable','crm_receivable_plan']}
|
for g,r in selected:
|
ct=tables['crm_contract'][r['contract_id']];oldid=ct['customer_id']
|
assert oldid in [1381,target['id']],(g['key'],oldid)
|
if oldid==target['id']:continue
|
affected['crm_contract'].add(ct['id'])
|
affected['erp_sale_order'].update(o['order_id'] for o in r['orders'])
|
for t in ['crm_sale_quotation','crm_invoice','crm_receivable','crm_receivable_plan']:
|
affected[t].update(id for id,x in tables[t].items() if x['contract_id']==ct['id'])
|
assert len(affected['erp_sale_order'])==7
|
for t,ids in affected.items():
|
if not ids:continue
|
for id in ids:assert tables[t][id]['customer_id']==1381
|
q.execute('UPDATE `'+t+'` SET customer_id=%s,updater=%s,update_time=%s WHERE id IN ('+','.join(['%s']*len(ids))+')',[target['id'],'291',state['now'],*sorted(ids)])
|
for id in affected['crm_contract']:
|
name=tables['crm_contract'][id]['name'];assert '北京同仁堂健康药业电子商务有限公司' in name
|
q.execute('UPDATE crm_contract SET name=%s WHERE id=%s',(name.replace('北京同仁堂健康药业电子商务有限公司','电商'),id))
|
# Keep original invoice titles and source remarks: customer assignment is distinct from legal invoice-title evidence.
|
for t,rs in backup['tables'].items():
|
for old in rs:
|
q.execute('SELECT * FROM `'+t+'` WHERE id=%s',(old['id'],));new=q.fetchone();changed={k for k in old if old[k]!=new[k]}
|
allowed={'customer_id','updater','update_time'} | ({'name'} if t=='crm_contract' else set())
|
assert not changed or old['id'] in affected.get(t,set()) and changed<=allowed,(t,old['id'],changed)
|
nos=[o['source_no'] for g,r in selected for o in r['orders']]
|
q.execute('SELECT no,customer_id,total_price FROM erp_sale_order WHERE no IN ('+','.join(['%s']*len(nos))+') AND deleted=0',nos);orders=q.fetchall();assert len(orders)==8 and all(x['customer_id']==target['id'] for x in orders)
|
total=sum(x['total_price'] for x in orders);assert total==Decimal('2030440.62')
|
c.commit()
|
result={'committed':True,'at':str(state['now']),'target_customer_id':target['id'],'target_customer_name':'电商','changed_counts':{t:len(ids) for t,ids in affected.items()},'changed_ids':{t:sorted(ids) for t,ids in affected.items()},'order_numbers':nos,'orders':8,'total':str(total),'preserved_invoice_titles':True,'selected_contract_ids':[r['contract_id'] for g,r in selected]}
|
(P/'ecommerce-customer-correction-result.json').write_text(json.dumps(result,ensure_ascii=False,indent=2),encoding='utf8')
|
print(json.dumps(result,ensure_ascii=False))
|
except Exception:c.rollback();raise
|
finally:
|
with c.cursor() as q:q.execute('SELECT RELEASE_LOCK(%s)',('sales-ledger-202609',))
|
c.close()
|