gaoluyang
2 天以前 e40a608ef9bf51db294d8eefada6a8e2e80cebca
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import sys,json
from pathlib import Path
from read_links import P,connect,encode
def save(name,data):(P/name).write_text(encode(data),encoding='utf8')
def main():
 assert not (P/'oqc-binding-result.json').exists(),'Already applied'
 plan=json.loads((P/'oqc-binding-plan.json').read_text(encoding='utf8'))
 c=connect(sys.stdin.readline().strip())
 try:
  with c.cursor() as q:
   q.execute("SET time_zone='+08:00'");q.execute('SELECT DATABASE() db,NOW() now');state=q.fetchone();assert state['db']=='mom-hm'
   q.execute("SELECT GET_LOCK('codex-customer-chain-repair-20261015',0) locked");assert q.fetchone()['locked']==1
   q.execute('SELECT * FROM mes_qc_oqc WHERE deleted=0 ORDER BY id FOR UPDATE');before=q.fetchall()
   backup='oqc-before-'+state['now'].strftime('%Y%m%d-%H%M%S')+'.json';save(backup,before)
   current={r['id']:r for r in before};expected={id:dict(r) for id,r in current.items()}
   q.execute('SELECT id,name FROM crm_customer WHERE deleted=0 FOR SHARE');customers={r['id']:r for r in q.fetchall()}
   q.execute('SELECT id,no,customer_id,order_time FROM erp_sale_order WHERE deleted=0 FOR SHARE');orders={r['id']:r for r in q.fetchall()}
   q.execute('SELECT id,order_id,product_id FROM erp_sale_order_items WHERE deleted=0 FOR SHARE');lines={r['id']:r for r in q.fetchall()}
   for change in plan['changes']:
    id=change['id'];assert encode(current[id])==encode(change['source_before']),f'QC changed: {id}'
    assert change['after'] in customers and customers[change['after']]['name']==change['customer_name']
    for e in change['evidence']:
     if 'order_id' in e:
      o=orders[e['order_id']];l=lines[e['line_id']]
      assert o['customer_id']==change['after'] and o['no']==e['order_no'] and str(o['order_time'])==e['order_time']
      assert l['order_id']==o['id'] and l['product_id']==e['product_id']
    expected[id]['client_id']=change['after']
    q.execute('UPDATE mes_qc_oqc SET client_id=%s,update_time=%s WHERE id=%s AND client_id IS NULL AND deleted=0',
     (change['after'],current[id]['update_time'],id));assert q.rowcount==1
   q.execute('SELECT * FROM mes_qc_oqc WHERE deleted=0 ORDER BY id');after={r['id']:r for r in q.fetchall()}
   assert encode(after)==encode(expected),'Unexpected QC field change'
   assert all(r['client_id'] in customers for r in after.values()),'Missing or invalid customer remains'
   c.commit()
   result=dict(plan['summary'],committed_at=str(state['now']),backup=str(P/backup),
    changed_fields=['client_id'],unrelated_oqc_unchanged=len(before)-len(plan['changes']),
    all_active_oqc_customer_valid=len(after),source_doc_links_unchanged=True,
    qc_results_quantities_dates_statuses_unchanged=True)
   save('oqc-binding-result.json',result);print(encode(result))
 except BaseException:c.rollback();raise
 finally:c.close()
 
def verify():
 plan=json.loads((P/'oqc-binding-plan.json').read_text(encoding='utf8'))
 result=json.loads((P/'oqc-binding-result.json').read_text(encoding='utf8'))
 before=json.loads(Path(result['backup']).read_text(encoding='utf8'))
 expected={r['id']:r for r in before}
 for r in plan['changes']:expected[r['id']]['client_id']=r['after']
 c=connect(sys.stdin.readline().strip())
 try:
  with c.cursor() as q:
   q.execute("SET time_zone='+08:00'");q.execute('SELECT NOW() now');now=q.fetchone()['now']
   q.execute('SELECT * FROM mes_qc_oqc WHERE deleted=0 ORDER BY id');after={r['id']:r for r in q.fetchall()}
   assert encode(after)==encode(expected),'Unexpected field changes'
   q.execute('SELECT id,name FROM crm_customer WHERE deleted=0');customers={r['id']:r for r in q.fetchall()}
   assert all(r['client_id'] in customers for r in after.values())
   for r in plan['changes']:assert after[r['id']]['client_id']==r['after'] and customers[r['after']]['name']==r['customer_name']
   verified={'passed':True,'verified_at':str(now),'updated':len(plan['changes']),'all_active_oqc':len(after),
    'missing_or_invalid_customers':0,'only_client_id_changed':True,'match_basis_retained':True}
   save('oqc-binding-verification.json',verified);print(encode(verified))
 finally:c.close()
if __name__=='__main__':verify() if '--verify' in sys.argv else main()