feat: add invoicing system and subscription tier enforcement
Phase 1 OMS implementation: Invoicing: - Add Invoice and VendorInvoiceSettings database models - Full EU VAT support (27 countries, OSS, B2B reverse charge) - Invoice PDF generation with WeasyPrint + Jinja2 templates - Vendor invoice API endpoints for settings, creation, PDF download Subscription Tiers: - Add VendorSubscription model with 4 tiers (Essential/Professional/Business/Enterprise) - Tier limit enforcement for orders, products, team members - Feature gating based on subscription tier - Automatic trial subscription creation for new vendors - Integrate limit checks into order creation (direct and Letzshop sync) Marketing: - Update pricing documentation with 4-tier structure - Revise back-office positioning strategy - Update homepage with Veeqo-inspired Letzshop-focused messaging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ from sqlalchemy import String, and_, func, or_
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.services.order_service import order_service as unified_order_service
|
||||
from app.services.subscription_service import subscription_service
|
||||
from models.database.letzshop import (
|
||||
LetzshopFulfillmentQueue,
|
||||
LetzshopHistoricalImportJob,
|
||||
@@ -792,6 +793,7 @@ class LetzshopOrderService:
|
||||
"updated": 0,
|
||||
"skipped": 0,
|
||||
"errors": 0,
|
||||
"limit_exceeded": 0,
|
||||
"products_matched": 0,
|
||||
"products_not_found": 0,
|
||||
"eans_processed": set(),
|
||||
@@ -800,6 +802,10 @@ class LetzshopOrderService:
|
||||
"error_messages": [],
|
||||
}
|
||||
|
||||
# Get subscription usage upfront for batch efficiency
|
||||
usage = subscription_service.get_usage(self.db, vendor_id)
|
||||
orders_remaining = usage.orders_remaining # None = unlimited
|
||||
|
||||
for i, shipment in enumerate(shipments):
|
||||
shipment_id = shipment.get("id")
|
||||
if not shipment_id:
|
||||
@@ -844,11 +850,24 @@ class LetzshopOrderService:
|
||||
else:
|
||||
stats["skipped"] += 1
|
||||
else:
|
||||
# Check tier limit before creating order
|
||||
if orders_remaining is not None and orders_remaining <= 0:
|
||||
stats["limit_exceeded"] += 1
|
||||
stats["error_messages"].append(
|
||||
f"Shipment {shipment_id}: Order limit reached"
|
||||
)
|
||||
continue
|
||||
|
||||
# Create new order using unified service
|
||||
try:
|
||||
self.create_order(vendor_id, shipment)
|
||||
self.db.commit() # noqa: SVC-006 - background task needs incremental commits
|
||||
stats["imported"] += 1
|
||||
|
||||
# Decrement remaining count for batch efficiency
|
||||
if orders_remaining is not None:
|
||||
orders_remaining -= 1
|
||||
|
||||
except Exception as e:
|
||||
self.db.rollback() # Rollback failed order
|
||||
stats["errors"] += 1
|
||||
|
||||
Reference in New Issue
Block a user