97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
from datetime import UTC, datetime
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import BigInteger, create_engine
|
|
from sqlalchemy.ext.compiler import compiles
|
|
from sqlalchemy.orm import Session, sessionmaker
|
|
|
|
|
|
@compiles(BigInteger, "sqlite")
|
|
def _compile_bigint_for_sqlite(type_, compiler, **kw) -> str:
|
|
_ = type_, compiler, kw
|
|
return "INTEGER"
|
|
|
|
|
|
import app.models.master_data # noqa: E402,F401
|
|
from app.api.routes import master_data # noqa: E402
|
|
from app.models.base import Base # noqa: E402
|
|
from app.models.master_data import Item # noqa: E402
|
|
from app.schemas.database import MaterialCreate # noqa: E402
|
|
|
|
|
|
class MaterialCodeGenerationTest(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
engine = create_engine("sqlite+pysqlite:///:memory:", future=True)
|
|
Base.metadata.create_all(engine)
|
|
self.SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True)
|
|
self.db: Session = self.SessionLocal()
|
|
|
|
def tearDown(self) -> None:
|
|
self.db.close()
|
|
|
|
def _payload(self) -> MaterialCreate:
|
|
return MaterialCreate(
|
|
item_name="冷轧钢板",
|
|
specification="1.0*1000",
|
|
material_grade="SPCC",
|
|
unit_weight_kg=1,
|
|
safety_stock_weight_kg=0,
|
|
scrap_sale_price=0,
|
|
default_supplier_id=None,
|
|
purchase_calc_mode="BY_WEIGHT",
|
|
min_purchase_qty=0,
|
|
purchase_multiple_qty=0,
|
|
purchase_multiple_weight_kg=0,
|
|
lead_time_days=0,
|
|
quality_rule=None,
|
|
status="ACTIVE",
|
|
)
|
|
|
|
def _add_item(self, code: str, item_type: str = "RAW_MATERIAL") -> None:
|
|
now = datetime.now(UTC)
|
|
self.db.add(
|
|
Item(
|
|
item_code=code,
|
|
item_name=f"测试物料{code}",
|
|
item_type=item_type,
|
|
specification="",
|
|
material_grade="",
|
|
unit_weight_kg=Decimal("0"),
|
|
safety_stock_weight_kg=Decimal("0"),
|
|
scrap_sale_price=Decimal("0"),
|
|
status="ACTIVE",
|
|
created_at=now,
|
|
updated_at=now,
|
|
)
|
|
)
|
|
self.db.commit()
|
|
|
|
def test_material_code_starts_from_named_five_digit_sequence(self) -> None:
|
|
self.assertEqual(master_data._build_material_code(self.db, self._payload()), "原材料00001")
|
|
|
|
def test_material_code_increments_existing_named_material_codes(self) -> None:
|
|
self._add_item("原材料00001")
|
|
self._add_item("RM-SPCC-001")
|
|
|
|
self.assertEqual(master_data._build_material_code(self.db, self._payload()), "原材料00002")
|
|
|
|
def test_material_code_ignores_legacy_numeric_codes(self) -> None:
|
|
self._add_item("00001")
|
|
self._add_item("110801001050")
|
|
self._add_item("110501000185")
|
|
|
|
self.assertEqual(master_data._build_material_code(self.db, self._payload()), "原材料00001")
|
|
|
|
def test_material_code_skips_codes_used_by_other_item_types(self) -> None:
|
|
self._add_item("原材料00001")
|
|
self._add_item("原材料00002", item_type="FINISHED_GOOD")
|
|
|
|
self.assertEqual(master_data._build_material_code(self.db, self._payload()), "原材料00003")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|