feat: integer cents money handling, order page fixes, and vendor filter persistence
Money Handling Architecture: - Store all monetary values as integer cents (€105.91 = 10591) - Add app/utils/money.py with Money class and conversion helpers - Add static/shared/js/money.js for frontend formatting - Update all database models to use _cents columns (Product, Order, etc.) - Update CSV processor to convert prices to cents on import - Add Alembic migration for Float to Integer conversion - Create .architecture-rules/money.yaml with 7 validation rules - Add docs/architecture/money-handling.md documentation Order Details Page Fixes: - Fix customer name showing 'undefined undefined' - use flat field names - Fix vendor info empty - add vendor_name/vendor_code to OrderDetailResponse - Fix shipping address using wrong nested object structure - Enrich order detail API response with vendor info Vendor Filter Persistence Fixes: - Fix orders.js: restoreSavedVendor now sets selectedVendor and filters - Fix orders.js: init() only loads orders if no saved vendor to restore - Fix marketplace-letzshop.js: restoreSavedVendor calls selectVendor() - Fix marketplace-letzshop.js: clearVendorSelection clears TomSelect dropdown - Align vendor selector placeholder text between pages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,9 @@ This module provides:
|
||||
- Session-based cart management
|
||||
- Cart item operations (add, update, remove)
|
||||
- Cart total calculations
|
||||
|
||||
All monetary calculations use integer cents internally for precision.
|
||||
See docs/architecture/money-handling.md for details.
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -19,6 +22,7 @@ from app.exceptions import (
|
||||
InvalidCartQuantityException,
|
||||
ProductNotFoundException,
|
||||
)
|
||||
from app.utils.money import cents_to_euros
|
||||
from models.database.cart import CartItem
|
||||
from models.database.product import Product
|
||||
|
||||
@@ -62,21 +66,23 @@ class CartService:
|
||||
extra={"item_count": len(cart_items)},
|
||||
)
|
||||
|
||||
# Build response
|
||||
# Build response - calculate totals in cents, return euros
|
||||
items = []
|
||||
subtotal = 0.0
|
||||
subtotal_cents = 0
|
||||
|
||||
for cart_item in cart_items:
|
||||
product = cart_item.product
|
||||
line_total = cart_item.line_total
|
||||
line_total_cents = cart_item.line_total_cents
|
||||
|
||||
items.append(
|
||||
{
|
||||
"product_id": product.id,
|
||||
"product_name": product.marketplace_product.title,
|
||||
"product_name": product.marketplace_product.get_title("en")
|
||||
if product.marketplace_product
|
||||
else str(product.id),
|
||||
"quantity": cart_item.quantity,
|
||||
"price": cart_item.price_at_add,
|
||||
"line_total": line_total,
|
||||
"price": cart_item.price_at_add, # Returns euros via property
|
||||
"line_total": cents_to_euros(line_total_cents),
|
||||
"image_url": (
|
||||
product.marketplace_product.image_link
|
||||
if product.marketplace_product
|
||||
@@ -85,8 +91,10 @@ class CartService:
|
||||
}
|
||||
)
|
||||
|
||||
subtotal += line_total
|
||||
subtotal_cents += line_total_cents
|
||||
|
||||
# Convert to euros for API response
|
||||
subtotal = cents_to_euros(subtotal_cents)
|
||||
cart_data = {
|
||||
"vendor_id": vendor_id,
|
||||
"session_id": session_id,
|
||||
@@ -166,8 +174,12 @@ class CartService:
|
||||
},
|
||||
)
|
||||
|
||||
# Get current price (use sale_price if available, otherwise regular price)
|
||||
current_price = product.sale_price if product.sale_price else product.price
|
||||
# Get current price in cents (use sale_price if available, otherwise regular price)
|
||||
current_price_cents = (
|
||||
product.effective_sale_price_cents
|
||||
or product.effective_price_cents
|
||||
or 0
|
||||
)
|
||||
|
||||
# Check if item already exists in cart
|
||||
existing_item = (
|
||||
@@ -236,13 +248,13 @@ class CartService:
|
||||
available=product.available_inventory,
|
||||
)
|
||||
|
||||
# Create new cart item
|
||||
# Create new cart item (price stored in cents)
|
||||
cart_item = CartItem(
|
||||
vendor_id=vendor_id,
|
||||
session_id=session_id,
|
||||
product_id=product_id,
|
||||
quantity=quantity,
|
||||
price_at_add=current_price,
|
||||
price_at_add_cents=current_price_cents,
|
||||
)
|
||||
db.add(cart_item)
|
||||
db.flush()
|
||||
@@ -253,7 +265,7 @@ class CartService:
|
||||
extra={
|
||||
"cart_item_id": cart_item.id,
|
||||
"quantity": quantity,
|
||||
"price": current_price,
|
||||
"price_cents": current_price_cents,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user