Add multi account support to shpping cart

This commit is contained in:
2026-02-14 11:44:34 +01:00
parent 8daf064e4d
commit de4167728d
3 changed files with 49 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
from decimal import Decimal
from typing import Annotated
from fastapi import APIRouter, HTTPException, Request
from fastapi import APIRouter, Form, HTTPException, Request
from sqlalchemy import select
from starlette import status
from starlette.responses import RedirectResponse
@@ -29,17 +30,32 @@ async def get_cart(request: Request, session: SessionDep, user: UserDep):
return templates.TemplateResponse(
"order.html.jinja",
context={"request": request, "order": user.shopping_cart, "is_cart": True},
context={
"request": request,
"user": user,
"order": user.shopping_cart,
"is_cart": True,
},
)
@shop_router.get("/shop/finalize_order")
async def finalize_order(request: Request, session: SessionDep, user: UserDep):
@shop_router.post("/shop/finalize_order")
async def finalize_order(
request: Request,
session: SessionDep,
user: UserDep,
account_id: Annotated[float, Form()],
):
cart = user.shopping_cart
# TODO: Implement
cart.finalize(user.accounts[0])
for account in user.accounts:
if account.id == account_id:
break
else:
raise HTTPException(status_code=400, detail="Invalid account ID.")
cart.finalize(account)
return RedirectResponse(url=f"/", status_code=status.HTTP_302_FOUND)

View File

@@ -71,7 +71,19 @@
{% if is_cart %}
<div class="d-flex justify-content-between align-items-center mt-3">
<div >
<a href="/shop/finalize_order" class="btn btn-primary">Jetzt Buchen</a>
<form method="post" action="/shop/finalize_order" class="d-flex align-items-center">
{% if user.accounts|length > 1 %}
<select name="account_id" class="form-select form-select-sm me-2" required>
<option value="">-- Konto wählen --</option>
{% for account in user.accounts %}
<option value="{{ account.id }}">{{ account.name }} ({{ account.balance | format_number }} €)</option>
{% endfor %}
</select>
{% elif user.accounts|length == 1 %}
<input type="hidden" name="account_id" value="{{ user.accounts[0].id }}">
{% endif %}
<button type="submit" class="btn btn-primary">Jetzt Bezahlen</button>
</form>
</div>
</div>
{% endif %}

View File

@@ -147,19 +147,30 @@ def test_remove_item_from_cart_wrong_user(client: APSTestClient, test_db, produc
def test_finalize_order(client: APSTestClient, test_db, product):
user = create_user_with_account(test_db, "test", balance=100.0)
second_account = Account(name=f"Another account")
second_account.transactions.append(
Transaction(total_amount=Decimal(50.0), type="deposit")
)
test_db.add(second_account)
user.accounts.append(second_account)
user.shopping_cart.items.append(
OrderItem(product=product, quantity=2, total_amount=product.price * 2)
)
test_db.flush()
response = client.get("/shop/finalize_order", follow_redirects=False)
response = client.post(
"/shop/finalize_order",
follow_redirects=False,
data={"account_id": second_account.id},
)
assert response.status_code == 302
assert len(user.shopping_cart.items) == 0
assert len(user.orders) == 2 # shopping cart + finalized order
assert user.accounts[0].balance == Decimal(100.0) - (product.price * 2)
assert user.accounts[0].balance == Decimal(100.0)
assert user.accounts[1].balance == Decimal(50.0) - (product.price * 2)
def test_view_order(client: APSTestClient, test_db, product):