feat: change order status by moving its Deck card between stacks

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V57jSQPqwkGG8BuAXg59X5
This commit is contained in:
Jonny 2026-09-13 16:18:42 +02:00
parent 21e63685c9
commit c10fd61c54
2 changed files with 71 additions and 0 deletions

View File

@ -556,6 +556,29 @@ async def list_orders(status: str = None) -> list:
return orders return orders
async def update_order_status(order_id: int, status: str) -> dict:
board = await _ensure_deck_board()
if status not in board["stacks"]:
raise ValueError(f"Unknown status: {status}")
target_stack_id = board["stacks"][status]
stacks = await _deck_request("GET", f"/boards/{board['board_id']}/stacks")
current_stack_id = None
for stack in stacks:
if any(c["id"] == order_id for c in stack.get("cards", [])):
current_stack_id = stack["id"]
break
if current_stack_id is None:
raise ValueError(f"Order {order_id} not found")
await _deck_request(
"PUT",
f"/boards/{board['board_id']}/stacks/{current_stack_id}/cards/{order_id}/reorder",
{"stackId": target_stack_id, "order": 999},
)
return {"id": order_id, "status": status}
def _decode_mime_words(value: str) -> str: def _decode_mime_words(value: str) -> str:
parts = decode_header(value) parts = decode_header(value)
decoded = [] decoded = []

View File

@ -215,3 +215,51 @@ async def test_list_orders_filters_by_status():
orders = await main.list_orders(status="Erledigt") orders = await main.list_orders(status="Erledigt")
assert [o["id"] for o in orders] == [56] assert [o["id"] for o in orders] == [56]
@pytest.mark.asyncio
async def test_update_order_status_finds_current_stack_and_reorders():
stacks_response = [
{"id": 1, "title": "Offen", "cards": [{"id": 55, "title": "A"}]},
{"id": 2, "title": "In Arbeit", "cards": []},
{"id": 3, "title": "Erledigt", "cards": []},
]
async def fake_deck_request(method, path, json_body=None):
if (method, path) == ("GET", "/boards/10/stacks"):
return stacks_response
if method == "PUT":
return {"id": 55}
raise AssertionError(f"unexpected call {method} {path}")
with patch.object(main, "_ensure_deck_board", new=AsyncMock(return_value=_BOARD)), patch.object(
main, "_deck_request", new=AsyncMock(side_effect=fake_deck_request)
) as mock_req:
result = await main.update_order_status(55, "In Arbeit")
assert result == {"id": 55, "status": "In Arbeit"}
put_call = [c for c in mock_req.call_args_list if c.args[0] == "PUT"][0]
_, path, body = put_call.args
assert path == "/boards/10/stacks/1/cards/55/reorder"
assert body == {"stackId": 2, "order": 999}
@pytest.mark.asyncio
async def test_update_order_status_raises_for_unknown_status():
with patch.object(main, "_ensure_deck_board", new=AsyncMock(return_value=_BOARD)):
with pytest.raises(ValueError):
await main.update_order_status(55, "Storniert")
@pytest.mark.asyncio
async def test_update_order_status_raises_when_card_not_found():
stacks_response = [
{"id": 1, "title": "Offen", "cards": []},
{"id": 2, "title": "In Arbeit", "cards": []},
{"id": 3, "title": "Erledigt", "cards": []},
]
with patch.object(main, "_ensure_deck_board", new=AsyncMock(return_value=_BOARD)), patch.object(
main, "_deck_request", new=AsyncMock(return_value=stacks_response)
):
with pytest.raises(ValueError):
await main.update_order_status(999, "Erledigt")