gaoluyang
10 小时以前 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
62
63
64
import json,xml.etree.ElementTree as ET,collections,re
from pathlib import Path
from decimal import Decimal,ROUND_HALF_UP
root=Path('scripts/stock-import-202609')
before=ET.parse(root/'remote-snapshot.xml').getroot()
after=ET.parse(root/'remote-post-snapshot.xml').getroot()
def rows(db,key):return [{c.tag:c.text or '' for c in r} for r in db.find(key)]
source=json.loads((root/'source.json').read_text(encoding='utf-8'),parse_float=Decimal)
ledger=next(s for s in source if s['sheet']=='Sheet1')['rows']
original={str(r[4]).strip():r for r in ledger if len(r)>20 and isinstance(r[4],(str,int)) and re.fullmatch('[A-Za-z0-9]+',str(r[4]).strip())}
assert len(original)==843
units={r['id']:r['name'].strip() for r in rows(after,'units')}
materials=collections.defaultdict(list)
for m in rows(after,'materials'):materials[m['code']].append(m)
warehouses={w['id']:w for w in rows(after,'warehouses')}
batches={b['id']:b for b in rows(after,'batches')}
stock=[s for s in rows(after,'stock') if s['creator']=='stock-import-202609']
assert len(stock)==855
assert len(rows(after,'warehouses'))==len(rows(before,'warehouses'))+9
oldmdm={m['id']:m for m in rows(before,'materials')}
newmdm={m['id']:m for m in rows(after,'materials')}
assert all(newmdm[k]==m for k,m in oldmdm.items()),'Existing material was modified'
assert len(newmdm)-len(oldmdm)==582
assert rows(before,'deletedMaterials')==rows(after,'deletedMaterials')
actual=collections.defaultdict(Decimal)
distribution=collections.Counter()
stockids=set()
for s in stock:
    assert s['id'] not in stockids;stockids.add(s['id'])
    m=newmdm[s['item_id']]
    assert m['code'] in original
    b=batches[s['batch_id']]
    assert b['item_id']==s['item_id'] and b['code']=='INIT202609-'+m['code']==s['batch_code']
    assert b['produce_date']==b['expire_date']==''
    assert s['frozen']=='0' and Decimal(s['frozen_quantity'])==Decimal(s['reserved_quantity'])==Decimal(s['in_transit_quantity'])==0
    assert Decimal(s['quantity'])>=0
    actual[m['code']]+=Decimal(s['quantity'])
    distribution[warehouses[s['warehouse_id']]['name']]+=1
    assert s['location_id']==s['area_id']==s['vendor_id']==''
    assert s['receipt_time']=='2026-09-30 23:59:59'
assert set(actual)==set(original)
for code,r in original.items():
    assert len(materials[code])==1
    m=materials[code][0];sourceunit=r[5];unit=units[m['unit_measure_id']]
    if code=='81013938':sourceunit='克'
    quantity=Decimal(r[20])
    if sourceunit=='公斤' and unit=='克':quantity*=1000
    elif sourceunit=='克' and unit=='公斤':quantity/=1000
    elif sourceunit!=unit:assert sourceunit in ('盒','罐','袋','套','个') and unit in ('个','张')
    assert actual[code]==quantity.quantize(Decimal('.000001'),rounding=ROUND_HALF_UP),(code,quantity,actual[code])
transactions=[t for t in rows(after,'transactions') if t['creator']=='stock-import-202609']
positive={s['id']:s for s in stock if Decimal(s['quantity'])>0}
assert len(transactions)==len(positive)==755
seen=set()
for t in transactions:
    sid=t['material_stock_id'];assert sid not in seen;seen.add(sid)
    s=positive[sid]
    assert t['item_id']==s['item_id'] and t['batch_id']==s['batch_id'] and t['warehouse_id']==s['warehouse_id']
    assert Decimal(t['quantity'])==Decimal(s['quantity']) and t['type']=='1' and t['biz_type']=='126'
assert seen==set(positive)
assert len(rows(after,'batches'))==843
text='线上36 mom-hm独立回读校验通过:843个台账物料、855条分仓库存、582个新物料、9个仓库、843个期初汇总批次、755条库存流水;100条零结存;原有物料和已删除记录未改动。\n'+json.dumps(dict(distribution),ensure_ascii=False)+'\n'
(root/'verification-result.txt').write_text(text,encoding='utf-8')
print(text)