feat: 协作台账支持归档并精简状态列
This commit is contained in:
@@ -1817,6 +1817,128 @@ class TestCollabStatusBatch(TestCollabBase):
|
||||
assert excinfo.value.code == "status_batch_too_large"
|
||||
|
||||
|
||||
class TestCollabArchive(TestCollabBase):
|
||||
"""归档是可见性状态:不影响业务状态,默认隐藏,归档视图可搜索。"""
|
||||
|
||||
def _done(self, order_no: str, **kwargs) -> HuyaExternalOrder:
|
||||
order = self._create(order_no=order_no, **kwargs)
|
||||
order.status = collab.STATUS_DONE
|
||||
self.db.commit()
|
||||
self.db.refresh(order)
|
||||
return order
|
||||
|
||||
def test_archive_hides_by_default_but_is_searchable_in_archive_scope(self):
|
||||
archived = self._done("ARCH-1", remark="客户已验收")
|
||||
active = self._create(order_no="ARCH-2")
|
||||
|
||||
result = collab.archive_orders(
|
||||
self.db, self.user, [archived], reason="活动结束,完成对账"
|
||||
)
|
||||
|
||||
assert result["archived"] == 1
|
||||
assert archived.archived_at is not None
|
||||
assert archived.archive_reason == "活动结束,完成对账"
|
||||
assert archived.status == collab.STATUS_DONE
|
||||
|
||||
rows, total = collab.list_orders(self.db)
|
||||
assert total == 1
|
||||
assert [row.id for row in rows] == [active.id]
|
||||
|
||||
rows, total = collab.list_orders(
|
||||
self.db, archive_scope="archived", keyword="客户已验收"
|
||||
)
|
||||
assert total == 1
|
||||
assert [row.id for row in rows] == [archived.id]
|
||||
|
||||
default_summary = collab.summary(self.db)
|
||||
archived_summary = collab.summary(self.db, archive_scope="archived")
|
||||
assert default_summary["by_status"]["done"] == 0
|
||||
assert default_summary["archived_total"] == 1
|
||||
assert archived_summary["total"] == 1
|
||||
|
||||
audit = self._audits(archived)[-1]
|
||||
assert audit.action == "huya:collab:archive"
|
||||
assert "完成对账" in audit.detail
|
||||
|
||||
def test_only_done_orders_can_be_archived(self):
|
||||
pending = self._create(order_no="ARCH-PENDING")
|
||||
|
||||
result = collab.archive_orders(self.db, self.user, [pending])
|
||||
|
||||
assert result["archived"] == 0
|
||||
assert result["skipped"] == 1
|
||||
assert "抢购成功" in result["results"][0]["message"]
|
||||
assert pending.archived_at is None
|
||||
|
||||
def test_archived_order_is_read_only_until_unarchived(self):
|
||||
order = self._done("ARCH-READONLY")
|
||||
collab.archive_orders(self.db, self.user, [order])
|
||||
|
||||
with pytest.raises(collab.CollabError) as excinfo:
|
||||
collab.set_status(
|
||||
self.db,
|
||||
self.user,
|
||||
order,
|
||||
collab.STATUS_PENDING,
|
||||
rollback=True,
|
||||
)
|
||||
assert excinfo.value.code == "order_archived"
|
||||
|
||||
with pytest.raises(collab.CollabError) as excinfo:
|
||||
collab.update_order(
|
||||
self.db,
|
||||
self.user,
|
||||
order,
|
||||
{"remark": "归档后不应该能改"},
|
||||
expected_version=order.version,
|
||||
)
|
||||
assert excinfo.value.code == "order_archived"
|
||||
|
||||
def test_unarchive_restores_row_and_clears_archive_note(self):
|
||||
order = self._done("ARCH-UNARCHIVE")
|
||||
collab.archive_orders(self.db, self.user, [order], reason="临时隐藏")
|
||||
|
||||
result = collab.unarchive_orders(self.db, self.user, [order])
|
||||
|
||||
assert result["unarchived"] == 1
|
||||
assert order.archived_at is None
|
||||
assert order.archived_by is None
|
||||
assert order.archive_reason == ""
|
||||
rows, total = collab.list_orders(self.db)
|
||||
assert total == 1
|
||||
assert [row.id for row in rows] == [order.id]
|
||||
assert self._audits(order)[-1].action == "huya:collab:unarchive"
|
||||
|
||||
def test_archive_by_filter_checks_expected_count_and_only_archives_done(self):
|
||||
first = self._done("ARCH-FILTER-1", shop="佳佳")
|
||||
second = self._done("ARCH-FILTER-2", shop="佳佳")
|
||||
self._create(order_no="ARCH-FILTER-PENDING", shop="佳佳")
|
||||
|
||||
with pytest.raises(collab.CollabError) as excinfo:
|
||||
collab.archive_orders_by_filter(
|
||||
self.db,
|
||||
self.user,
|
||||
expected_count=1,
|
||||
shop="佳佳",
|
||||
status=collab.STATUS_DONE,
|
||||
)
|
||||
assert excinfo.value.code == "archive_count_changed"
|
||||
|
||||
result = collab.archive_orders_by_filter(
|
||||
self.db,
|
||||
self.user,
|
||||
expected_count=2,
|
||||
shop="佳佳",
|
||||
status=collab.STATUS_DONE,
|
||||
reason="批量清理",
|
||||
)
|
||||
assert result["archived"] == 2
|
||||
assert first.archived_at is not None
|
||||
assert second.archived_at is not None
|
||||
_, total = collab.list_orders(self.db, shop="佳佳", archive_scope="active")
|
||||
assert total == 1
|
||||
|
||||
|
||||
class TestCollabActivityLifecycle(TestCollabBase):
|
||||
"""抢购之后:查积分 + 兑换记录 → 落生命周期快照 → 按结果自动改状态。"""
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ TESTS_DIR = Path(__file__).resolve().parent
|
||||
PROJECT_ROOT = TESTS_DIR.parent
|
||||
VERSIONS_DIR = PROJECT_ROOT / "web" / "backend" / "migrations" / "versions"
|
||||
|
||||
HEAD_REVISION = "20261016_0059"
|
||||
HEAD_REVISION = "20261019_0060"
|
||||
|
||||
# 迁移新增、但不声明在模型里的复合查询索引。
|
||||
EXTRA_INDEXES = (
|
||||
|
||||
Reference in New Issue
Block a user