feat: add customer multiple addresses management
- Add CustomerAddressService with CRUD operations - Add shop API endpoints for address management (GET, POST, PUT, DELETE) - Add set default endpoint for address type - Implement addresses.html with full UI (cards, modals, Alpine.js) - Integrate saved addresses in checkout flow - Address selector dropdowns for shipping/billing - Auto-select default addresses - Save new address checkbox option - Add country_iso field alongside country_name - Add address exceptions (NotFound, LimitExceeded, InvalidType) - Max 10 addresses per customer limit - One default address per type (shipping/billing) - Add unit tests for CustomerAddressService - Add integration tests for shop addresses API 🤖 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,13 @@ This module provides frontend-friendly exceptions with consistent error codes,
|
||||
messages, and HTTP status mappings.
|
||||
"""
|
||||
|
||||
# Address exceptions
|
||||
from .address import (
|
||||
AddressLimitExceededException,
|
||||
AddressNotFoundException,
|
||||
InvalidAddressTypeException,
|
||||
)
|
||||
|
||||
# Admin exceptions
|
||||
from .admin import (
|
||||
AdminOperationException,
|
||||
|
||||
38
app/exceptions/address.py
Normal file
38
app/exceptions/address.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# app/exceptions/address.py
|
||||
"""
|
||||
Address-related custom exceptions.
|
||||
|
||||
Used for customer address management operations.
|
||||
"""
|
||||
|
||||
from .base import BusinessLogicException, ResourceNotFoundException
|
||||
|
||||
|
||||
class AddressNotFoundException(ResourceNotFoundException):
|
||||
"""Raised when a customer address is not found."""
|
||||
|
||||
def __init__(self, address_id: str | int):
|
||||
super().__init__(
|
||||
resource_type="Address",
|
||||
identifier=str(address_id),
|
||||
)
|
||||
|
||||
|
||||
class AddressLimitExceededException(BusinessLogicException):
|
||||
"""Raised when customer exceeds maximum number of addresses."""
|
||||
|
||||
def __init__(self, max_addresses: int = 10):
|
||||
super().__init__(
|
||||
message=f"Maximum number of addresses ({max_addresses}) reached",
|
||||
error_code="ADDRESS_LIMIT_EXCEEDED",
|
||||
)
|
||||
|
||||
|
||||
class InvalidAddressTypeException(BusinessLogicException):
|
||||
"""Raised when an invalid address type is provided."""
|
||||
|
||||
def __init__(self, address_type: str):
|
||||
super().__init__(
|
||||
message=f"Invalid address type '{address_type}'. Must be 'shipping' or 'billing'",
|
||||
error_code="INVALID_ADDRESS_TYPE",
|
||||
)
|
||||
Reference in New Issue
Block a user