feat: make Product fully independent from MarketplaceProduct
- Add is_digital and product_type columns to Product model - Remove is_digital/product_type properties that derived from MarketplaceProduct - Update Create form with translation tabs, GTIN type, sale price, VAT rate, image - Update Edit form to allow editing is_digital (remove disabled state) - Add Availability field to Edit form - Fix Detail page for directly created products (no marketplace source) - Update vendor_product_service to handle new fields in create/update - Add VendorProductCreate/Update schema fields for translations and is_digital - Add unit tests for is_digital column and direct product creation - Add integration tests for create/update API with new fields - Create product-architecture.md documenting the independent copy pattern - Add migration y3d4e5f6g7h8 for is_digital and product_type columns 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
49
app/api/v1/vendor/products.py
vendored
49
app/api/v1/vendor/products.py
vendored
@@ -15,6 +15,7 @@ from app.api.deps import get_current_vendor_api
|
||||
from app.core.database import get_db
|
||||
from app.services.product_service import product_service
|
||||
from app.services.subscription_service import subscription_service
|
||||
from app.services.vendor_product_service import vendor_product_service
|
||||
from models.database.user import User
|
||||
from models.schema.product import (
|
||||
ProductCreate,
|
||||
@@ -25,6 +26,10 @@ from models.schema.product import (
|
||||
ProductToggleResponse,
|
||||
ProductUpdate,
|
||||
)
|
||||
from models.schema.vendor_product import (
|
||||
VendorDirectProductCreate,
|
||||
VendorProductCreateResponse,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/products")
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -106,6 +111,50 @@ def add_product_to_catalog(
|
||||
return ProductResponse.model_validate(product)
|
||||
|
||||
|
||||
@router.post("/create", response_model=VendorProductCreateResponse)
|
||||
def create_product_direct(
|
||||
product_data: VendorDirectProductCreate,
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Create a new product directly without marketplace product.
|
||||
|
||||
This creates a Product and ProductTranslation without requiring
|
||||
an existing MarketplaceProduct.
|
||||
"""
|
||||
# Check product limit before creating
|
||||
subscription_service.check_product_limit(db, current_user.token_vendor_id)
|
||||
|
||||
# Build data dict with vendor_id from token
|
||||
data = {
|
||||
"vendor_id": current_user.token_vendor_id,
|
||||
"title": product_data.title,
|
||||
"brand": product_data.brand,
|
||||
"vendor_sku": product_data.vendor_sku,
|
||||
"gtin": product_data.gtin,
|
||||
"price": product_data.price,
|
||||
"currency": product_data.currency,
|
||||
"availability": product_data.availability,
|
||||
"is_active": product_data.is_active,
|
||||
"is_featured": product_data.is_featured,
|
||||
"description": product_data.description,
|
||||
}
|
||||
|
||||
product = vendor_product_service.create_product(db=db, data=data)
|
||||
db.commit()
|
||||
|
||||
logger.info(
|
||||
f"Product {product.id} created by user {current_user.username} "
|
||||
f"for vendor {current_user.token_vendor_code}"
|
||||
)
|
||||
|
||||
return VendorProductCreateResponse(
|
||||
id=product.id,
|
||||
message="Product created successfully",
|
||||
)
|
||||
|
||||
|
||||
@router.put("/{product_id}", response_model=ProductResponse)
|
||||
def update_product(
|
||||
product_id: int,
|
||||
|
||||
Reference in New Issue
Block a user