Add multi account support to shpping cart
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
from decimal import Decimal
|
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 sqlalchemy import select
|
||||||
from starlette import status
|
from starlette import status
|
||||||
from starlette.responses import RedirectResponse
|
from starlette.responses import RedirectResponse
|
||||||
@@ -29,17 +30,32 @@ async def get_cart(request: Request, session: SessionDep, user: UserDep):
|
|||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"order.html.jinja",
|
"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")
|
@shop_router.post("/shop/finalize_order")
|
||||||
async def finalize_order(request: Request, session: SessionDep, user: UserDep):
|
async def finalize_order(
|
||||||
|
request: Request,
|
||||||
|
session: SessionDep,
|
||||||
|
user: UserDep,
|
||||||
|
account_id: Annotated[float, Form()],
|
||||||
|
):
|
||||||
|
|
||||||
cart = user.shopping_cart
|
cart = user.shopping_cart
|
||||||
|
|
||||||
# TODO: Implement
|
for account in user.accounts:
|
||||||
cart.finalize(user.accounts[0])
|
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)
|
return RedirectResponse(url=f"/", status_code=status.HTTP_302_FOUND)
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,19 @@
|
|||||||
{% if is_cart %}
|
{% if is_cart %}
|
||||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||||
<div >
|
<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>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -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):
|
def test_finalize_order(client: APSTestClient, test_db, product):
|
||||||
|
|
||||||
user = create_user_with_account(test_db, "test", balance=100.0)
|
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(
|
user.shopping_cart.items.append(
|
||||||
OrderItem(product=product, quantity=2, total_amount=product.price * 2)
|
OrderItem(product=product, quantity=2, total_amount=product.price * 2)
|
||||||
)
|
)
|
||||||
test_db.flush()
|
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 response.status_code == 302
|
||||||
|
|
||||||
assert len(user.shopping_cart.items) == 0
|
assert len(user.shopping_cart.items) == 0
|
||||||
assert len(user.orders) == 2 # shopping cart + finalized order
|
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):
|
def test_view_order(client: APSTestClient, test_db, product):
|
||||||
|
|||||||
Reference in New Issue
Block a user