Initial commit

This commit is contained in:
Misaka_Company
2026-07-30 14:17:18 +08:00
commit 4dc563cdd9
16 changed files with 1144 additions and 0 deletions

1
tests/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""tests 包。"""

155
tests/test_transform.py Normal file
View File

@@ -0,0 +1,155 @@
"""装箱单 build_context 纯逻辑测试(不连数据库)。
字段集v3序号/产品名称/产品型号/量程/数量/位号/备注。
产品名称取自合同表 [客户名称](历史遗留命名,实为产品名称)。
"""
from datetime import datetime
import pytest
from reports.packing_list.transform import (
EmptyBoxError,
build_context,
)
# —— 真实样本R04398/箱13 项,含位号,合计 4+4+5=13 ——
ROWS_R04398 = [
{
"paichan_no": "R04398", "box_no": 1,
"created_at": datetime(2026, 5, 26, 8, 58, 44, 473000),
"zongpai_no": "26B14077", "box_qty": 4,
"product_name": "压力表(不锈钢压力表)",
"model": "YTH-100.A0.531.M201.M08|BP-088.2312.M08.0A3|WHP.70X20X1.3",
"range_": "0-1.6MPa", "weihao": "PG-01105,PG-01106,PG-01107,PG-01108",
"remark": "", "order_no": "26YB0410175",
},
{
"paichan_no": "R04398", "box_no": 1,
"created_at": datetime(2026, 5, 26, 8, 58, 44, 473000),
"zongpai_no": "26B14078", "box_qty": 4,
"product_name": "耐震压力表(不锈钢耐震压力表)",
"model": "YTHN-100.A0.531.M201.M05.Y3|BP-088.2312.M05.0A3|WHP.70X20X1.3",
"range_": "0-0.4MPa", "weihao": "PG-00401A,PG-00401B,PG-00405A,PG-00405B",
"remark": "", "order_no": "26YB0410175",
},
{
"paichan_no": "R04398", "box_no": 1,
"created_at": datetime(2026, 5, 26, 8, 58, 44, 473000),
"zongpai_no": "26B14079", "box_qty": 5,
"product_name": "耐震压力表(不锈钢耐震压力表)",
"model": "YTHN-100.A0.531.M201.M07.Y3|BP-088.2312.M07.0A3|WHP.70X20X1.3",
"range_": "0-1MPa", "weihao": "PG-00801A,PG-01201,PG-01202,PG-01203A,PG-01203B",
"remark": "", "order_no": "26YB0410175",
},
]
def test_box_header_fields():
ctx = build_context(ROWS_R04398)
assert ctx["paichan_no"] == "R04398"
assert ctx["box_no"] == 1
assert ctx["pack_date"] == "2026-05-26"
assert ctx["order_no"] == "26YB0410175"
def test_total_qty_is_sum():
ctx = build_context(ROWS_R04398)
assert ctx["total_qty"] == 13 # 4 + 4 + 5
def test_rows_flattened_with_sequence():
"""明细行预展开为 r0_/r1_/r2_序号从 1 起。"""
ctx = build_context(ROWS_R04398)
assert ctx["r0_seq"] == "1"
assert ctx["r1_seq"] == "2"
assert ctx["r2_seq"] == "3"
assert ctx["r0_qty"] == "4"
assert ctx["r2_qty"] == "5"
def test_product_name_from_kehu_mingcheng():
"""产品名称取自 product_name即合同表 [客户名称])。"""
ctx = build_context(ROWS_R04398)
assert ctx["r0_product_name"] == "压力表(不锈钢压力表)"
assert ctx["r1_product_name"] == "耐震压力表(不锈钢耐震压力表)"
def test_row_show_flags():
ctx = build_context(ROWS_R04398)
assert ctx["r0_show"] == "1"
assert ctx["r2_show"] == "1"
assert ctx["r3_show"] == "" # 第 4 行无数据
def test_weihao_populated():
ctx = build_context(ROWS_R04398)
assert ctx["r0_weihao"] == "PG-01105,PG-01106,PG-01107,PG-01108"
def test_remark_blank_when_empty():
"""备注为空时留白。"""
ctx = build_context(ROWS_R04398)
assert ctx["r0_remark"] == ""
def test_weihao_and_remark_blank():
rows = [
{
"paichan_no": "R07425", "box_no": 1,
"created_at": datetime(2026, 5, 26, 8, 58, 44),
"zongpai_no": "26B24529", "box_qty": 1,
"product_name": "耐震压力表",
"model": "YTHN-100.A0.531.M201.M09.Y3|BP-088.2312.M09.0p3",
"range_": "0-2.5MPa", "weihao": "", "remark": "",
"order_no": "26YB0210489",
}
]
ctx = build_context(rows)
assert ctx["r0_weihao"] == ""
assert ctx["r0_remark"] == ""
assert ctx["total_qty"] == 1
def test_none_values_cleaned_to_blank():
rows = [
{
"paichan_no": "X001", "box_no": 2,
"created_at": None,
"zongpai_no": "26B1", "box_qty": None,
"product_name": None, "model": None, "range_": None,
"weihao": None, "remark": None, "order_no": None,
}
]
ctx = build_context(rows)
assert ctx["pack_date"] == ""
assert ctx["order_no"] == ""
assert ctx["r0_product_name"] == ""
assert ctx["r0_model"] == ""
assert ctx["r0_qty"] == "0"
assert ctx["total_qty"] == 0
def test_iso_string_date():
rows = [
{
"paichan_no": "X002", "box_no": 1,
"created_at": "2026-07-30T10:00:00Z",
"zongpai_no": "26B2", "box_qty": 7,
"product_name": "P", "model": "M", "range_": "R",
"weihao": "W", "remark": "RM", "order_no": "O",
}
]
ctx = build_context(rows)
assert ctx["pack_date"] == "2026-07-30"
def test_empty_rows_raise():
with pytest.raises(EmptyBoxError):
build_context([])
def test_row_heights_estimated():
ctx = build_context(ROWS_R04398)
assert len(ctx["row_heights"]) == 8
assert all(h > 0 for h in ctx["row_heights"][:3])
assert ctx["row_heights"][3] == 0.0