Modify cart items
This commit is contained in:
@@ -78,8 +78,43 @@ async def add_to_cart(request: Request, session: SessionDep, user: UserDep):
|
||||
)
|
||||
|
||||
|
||||
@shop_router.get("/shop/cart/remove/{item_id}")
|
||||
async def remove_from_cart(
|
||||
request: Request, session: SessionDep, user: UserDep, item_id: int
|
||||
):
|
||||
|
||||
cart = user.shopping_cart
|
||||
for item in cart.items:
|
||||
if item.id == item_id:
|
||||
item.order = None
|
||||
session.delete(item)
|
||||
break
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="Item not found in cart.")
|
||||
|
||||
return RedirectResponse(url=f"/shop/cart", status_code=status.HTTP_302_FOUND)
|
||||
|
||||
|
||||
@shop_router.post("/shop/cart/update/{item_id}")
|
||||
async def update_cart_item(
|
||||
request: Request, session: SessionDep, user: UserDep, item_id: int
|
||||
):
|
||||
|
||||
form_data = await request.form()
|
||||
|
||||
cart = user.shopping_cart
|
||||
for item in cart.items:
|
||||
if item.id == item_id:
|
||||
item.update_quantity(Decimal(form_data["quantity"]))
|
||||
break
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="Item not found in cart.")
|
||||
|
||||
return RedirectResponse(url=f"/shop/cart", status_code=status.HTTP_302_FOUND)
|
||||
|
||||
|
||||
@shop_router.get("/shop/order/{order_id}")
|
||||
async def add_to_cart(
|
||||
async def get_order_details(
|
||||
request: Request, session: SessionDep, user: UserDep, order_id: int
|
||||
):
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ class Product(Base):
|
||||
|
||||
price: Mapped[decimal.Decimal] = mapped_column(Numeric(10, 2))
|
||||
unit_of_measure: Mapped[UnitsOfMeasure] = mapped_column(nullable=False)
|
||||
allow_fractional: Mapped[bool] = mapped_column(nullable=False, default=True)
|
||||
|
||||
# TODO: limit this to actually used vat rates?
|
||||
vat_rate: Mapped[decimal.Decimal] = mapped_column(Numeric(10, 2))
|
||||
|
||||
@@ -162,6 +164,13 @@ class OrderItem(Base):
|
||||
Numeric(10, 2), nullable=False
|
||||
)
|
||||
|
||||
def update_quantity(self, new_quantity: decimal.Decimal):
|
||||
if new_quantity <= 0:
|
||||
raise ValueError("Quantity must be positive.")
|
||||
|
||||
self.quantity = new_quantity
|
||||
self.total_amount = self.product.price * new_quantity
|
||||
|
||||
|
||||
TransactionTypes = typing.Literal[
|
||||
"order",
|
||||
|
||||
@@ -67,14 +67,15 @@
|
||||
<input type="hidden" name="product_id" value="{{ product.id }}">
|
||||
<input type="hidden" name="area_id" value="{{ area.id }}">
|
||||
<div class="mb-3">
|
||||
<label for="quantity{{ product.id }}" class="form-label">Menge</label>
|
||||
<label for="quantity{{ product.id }}" class="form-label">Menge{% if product.unit_of_measure != 'piece' %} (in {{product.unit_of_measure}}){% endif %}</label>
|
||||
<input type="number"
|
||||
class="form-control"
|
||||
id="quantity{{ product.id }}"
|
||||
name="quantity"
|
||||
value="1"
|
||||
min="1"
|
||||
{% if product.allow_fractional %}min="0.01"{% else %}min="1"{% endif %}
|
||||
max="999"
|
||||
{% if product.allow_fractional %}step="0.01"{% else %}step="1"{% endif %}
|
||||
oninput="updateTotal{{ product.id }}(this.value)"
|
||||
style="max-width: 150px;">
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<!-- Latest Transactions Section -->
|
||||
<div class="transactions-section">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="h3 mb-0">Latest Transactions</h2>
|
||||
<h2 class="h3 mb-0">Letzte Buchungen</h2>
|
||||
<a href="#" class="btn btn-outline-primary btn-sm">View All</a>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
{% set total = namespace(value=0) %}
|
||||
{% for item in items %}
|
||||
{% set price = item.price if item.price is defined else (item.unit_price if item.unit_price is defined else 0) %}
|
||||
{% set qty = item.quantity if item.quantity is defined else (item.qty if item.qty is defined else 1) %}
|
||||
{% set subtotal = price * qty %}
|
||||
{% set subtotal = price * item.quantity %}
|
||||
{% set total.value = total.value + subtotal %}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -35,18 +34,26 @@
|
||||
</td>
|
||||
<td class="text-center" style="width:180px;">
|
||||
{% if is_cart %}
|
||||
<form method="post" action="/cart/update/{{ item.id }}" class="d-flex align-items-center justify-content-center">
|
||||
<input type="number" name="quantity" value="{{ qty }}" min="1" step="0.01" class="form-control form-control-sm me-2" style="width:80px;">
|
||||
<form method="post" action="/shop/cart/update/{{ item.id }}" class="d-flex align-items-center justify-content-center">
|
||||
<input
|
||||
type="number"
|
||||
name="quantity"
|
||||
value="{% if item.product.allow_fractional %}{{ item.quantity | format_number }}{% else %}{{ item.quantity | int }}{% endif %}"
|
||||
{% if item.product.allow_fractional %}min="0.01" step="0.01"{% else %}min="1" step="1"{% endif %}
|
||||
class="form-control form-control-sm me-2"
|
||||
style="width:80px;"
|
||||
required>
|
||||
{% if item.product.unit_of_measure != 'piece' %}<span class="text-muted small ms-1 me-2">{{ item.product.unit_of_measure }}</span>{% endif %}
|
||||
<button class="btn btn-sm btn-outline-secondary" type="submit">Aktualisieren</button>
|
||||
</form>
|
||||
{% else %}
|
||||
{{ item.quantity | format_number }}
|
||||
{{ item.quantity | format_number }}{% if item.product.unit_of_measure != 'piece' %} {{ item.product.unit_of_measure }}{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-end">{{ item.product.price | format_number }} €</td>
|
||||
<td class="text-end">{{ item.total_amount | format_number }} €</td>
|
||||
<td class="text-end">
|
||||
{% if is_cart %}<a href="/cart/remove/{{ item.id }}" class="btn btn-sm btn-outline-danger">Entfernen</a>{% endif %}
|
||||
{% if is_cart %}<a href="/shop/cart/remove/{{ item.id }}" class="btn btn-sm btn-outline-danger">Entfernen</a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -64,7 +71,6 @@
|
||||
{% if is_cart %}
|
||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||
<div>
|
||||
<a href="/cart/clear" class="btn btn-outline-danger me-2">Warenkorb leeren</a>
|
||||
<a href="/shop/finalize_order" class="btn btn-primary">Jetzt Buchen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user