"""盘点未用完明细按行保存,再次登记同一批次时保留原行 id。""" import unittest from datetime import date, datetime from decimal import Decimal from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.crud.material_stock_check import save_unused_lines from app.models.material import ( BizMaterialStockBatch, BizMaterialStockCheck, BizMaterialStockCheckUnusedLine, ) def _session(): engine = create_engine("sqlite://") for model in ( BizMaterialStockCheck, BizMaterialStockBatch, BizMaterialStockCheckUnusedLine, ): model.__table__.create(bind=engine) return sessionmaker(bind=engine)() class StockCheckUnusedLinesKeepIdentity(unittest.TestCase): def setUp(self): self.db = _session() now = datetime(2026, 10, 27, 10, 0, 0) self.db.add( BizMaterialStockCheck( id="check-1", title="盘点", check_time=now, status="draft", tenant_no="tenant-a", create_dept_id="", create_time=now, update_time=now, del_flag=0, ) ) self.db.add( BizMaterialStockBatch( id="batch-1", material_id="mat-1", material_code="M-1", material_name="培养基", stock_in_no="RK-1", stock_in_date=date(2026, 10, 1), expire_date=date(2027, 10, 1), catalog_no="C-1", batch_no="B-1", manufacturer="厂家", unit_price=Decimal("10.00"), amount=Decimal("100.00"), in_qty=Decimal("10"), remaining_qty=Decimal("4"), tenant_no="tenant-a", create_dept_id="", create_time=now, update_time=now, del_flag=0, ) ) self.db.commit() def tearDown(self): self.db.close() def test_resave_same_batch_keeps_id_and_drops_removed_line(self): save_unused_lines( self.db, "check-1", items=[ {"batch_id": "batch-1", "material_name": "培养基", "unused_qty": 2}, {"material_name": "手工行", "unused_qty": 1}, ], tenant_no="tenant-a", user_id="user-1", ) rows = ( self.db.query(BizMaterialStockCheckUnusedLine) .filter(BizMaterialStockCheckUnusedLine.del_flag == 0) .order_by(BizMaterialStockCheckUnusedLine.order_num.asc()) .all() ) self.assertEqual(len(rows), 2) kept_id = rows[0].id manual_id = rows[1].id save_unused_lines( self.db, "check-1", items=[{"batch_id": "batch-1", "material_name": "培养基", "unused_qty": 3}], tenant_no="tenant-a", user_id="user-1", ) live = ( self.db.query(BizMaterialStockCheckUnusedLine) .filter(BizMaterialStockCheckUnusedLine.del_flag == 0) .all() ) self.assertEqual([row.id for row in live], [kept_id]) self.assertEqual(live[0].unused_qty, Decimal("3")) removed = ( self.db.query(BizMaterialStockCheckUnusedLine) .filter(BizMaterialStockCheckUnusedLine.id == manual_id) .one() ) self.assertEqual(removed.del_flag, 1) if __name__ == "__main__": unittest.main()