| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- from datetime import datetime
- from decimal import Decimal
- from types import SimpleNamespace
- from unittest.mock import MagicMock
- import pytest
- from app.services.pl_io_order_service import apply_site_feedback
- def _header(**kwargs):
- defaults = dict(
- id="order-1",
- tenant_no="t1",
- status="in_progress",
- site_feedback_remark=None,
- site_feedback_images=None,
- site_feedback_time=None,
- site_first_submitted_at=None,
- update_by=None,
- )
- defaults.update(kwargs)
- return SimpleNamespace(**defaults)
- def _item(item_id="item-1"):
- return SimpleNamespace(
- id=item_id,
- plan_product_id="pp-1",
- actual_qty=None,
- qty_source=None,
- update_by=None,
- )
- def test_apply_site_feedback_sets_status_completed():
- header = _header()
- item = _item()
- db = MagicMock()
- apply_site_feedback(
- db,
- kind="inbound",
- header=header,
- items=[item],
- item_qty={"item-1": Decimal("12.5")},
- remark="ok",
- images=["a.jpg"],
- status="completed",
- )
- assert header.status == "completed"
- assert item.actual_qty == Decimal("12.5")
- assert header.site_first_submitted_at is not None
- assert header.site_feedback_remark == "ok"
- db.flush.assert_called_once()
- def test_apply_site_feedback_sets_status_voided():
- header = _header()
- apply_site_feedback(
- MagicMock(),
- kind="inbound",
- header=header,
- items=[_item()],
- item_qty={"item-1": Decimal("1")},
- remark=None,
- images=[],
- status="voided",
- )
- assert header.status == "voided"
- def test_apply_site_feedback_keeps_in_progress_when_requested():
- """首次提交选进行中时,不得隐式改成已完成。"""
- header = _header(status="in_progress")
- apply_site_feedback(
- MagicMock(),
- kind="inbound",
- header=header,
- items=[_item()],
- item_qty={"item-1": Decimal("1")},
- remark=None,
- images=[],
- status="in_progress",
- )
- assert header.status == "in_progress"
- assert header.site_first_submitted_at is not None
- def test_apply_site_feedback_rejects_invalid_status():
- header = _header()
- with pytest.raises(ValueError, match="无效状态"):
- apply_site_feedback(
- MagicMock(),
- kind="inbound",
- header=header,
- items=[_item()],
- item_qty={},
- remark=None,
- images=[],
- status="done",
- )
- def test_apply_site_feedback_rejects_already_voided():
- header = _header(status="voided")
- with pytest.raises(ValueError, match="单据已作废"):
- apply_site_feedback(
- MagicMock(),
- kind="inbound",
- header=header,
- items=[_item()],
- item_qty={},
- remark=None,
- images=[],
- status="completed",
- )
- def test_apply_site_feedback_does_not_reset_first_submitted_at():
- first = datetime(2026, 1, 1, 12, 0, 0)
- header = _header(
- status="completed",
- site_first_submitted_at=first,
- )
- apply_site_feedback(
- MagicMock(),
- kind="inbound",
- header=header,
- items=[_item()],
- item_qty={"item-1": Decimal("2")},
- remark="二改",
- images=[],
- status="in_progress",
- )
- assert header.status == "in_progress"
- assert header.site_first_submitted_at == first
|