协议样本、生产产出和盘点明细按行更新并保留原 id;补齐存储证明质检预填、离职人员显示名,以及样本采集通知模板字段。 Co-authored-by: Cursor <cursoragent@cursor.com>
119 lines
3.6 KiB
Python
119 lines
3.6 KiB
Python
"""盘点未用完明细按行保存,再次登记同一批次时保留原行 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()
|