Files
orion/docs/implementation/oms-feature-plan.md
Samir Boulahtit 4d9b816072 docs: add OMS positioning strategy and implementation plan
- Add "Lightweight OMS for Letzshop Sellers" positioning strategy
- Add back-office vs marketing positioning comparison
- Update pricing tiers for OMS model (Essential/Professional/Business)
- Add VAT invoice feature technical specification
- Add comprehensive OMS feature implementation plan
- Fix code block formatting in synology doc

New docs:
- docs/marketing/strategy/back-office-positioning.md
- docs/marketing/strategy/customer-marketing-positioning.md
- docs/implementation/vat-invoice-feature.md
- docs/implementation/oms-feature-plan.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 23:57:02 +01:00

17 KiB

OMS Feature Implementation Plan

Overview

Transform Wizamart into a "Lightweight OMS for Letzshop Sellers" by building the missing features that justify the tier pricing structure.

Goal: Ship Essential tier quickly, then build Professional differentiators, then Business features.

Design Decisions (Confirmed)

Decision Choice
Phase 1 scope Invoicing + Tier Limits together
PDF library WeasyPrint (HTML/CSS to PDF)
Invoice style Simple & Clean (minimal design)

Current State Summary

Already Production-Ready

  • Multi-tenant architecture (Company → Vendor hierarchy)
  • Letzshop order sync, confirmation, tracking
  • Inventory management with locations and reservations
  • Unified Order model (direct + marketplace)
  • Customer model with pre-calculated stats (total_orders, total_spent)
  • Team management + RBAC
  • CSV export patterns (products)

Needs to be Built

Feature Tier Impact Priority
Basic LU Invoice (PDF) Essential P0
Tier limits enforcement Essential P0
Vendor VAT Settings Professional P1
EU VAT Invoice Professional P1
Incoming Stock / PO Professional P1
Customer CSV Export Professional P1
Multi-vendor view Business P2
Accounting export Business P2

Phase 1: Essential Tier (Target: 1 week)

Goal: Launch Essential (€49) with basic invoicing and tier enforcement.

Step 1.1: Vendor Invoice Settings (1 day)

Create model for vendor billing details:

models/database/vendor_invoice_settings.py

Fields:

  • vendor_id (FK, unique - one-to-one)
  • company_name (legal name for invoices)
  • company_address, company_city, company_postal_code, company_country
  • vat_number (e.g., "LU12345678")
  • invoice_prefix (default "INV")
  • invoice_next_number (auto-increment)
  • payment_terms (optional text)
  • bank_details (optional IBAN etc.)
  • footer_text (optional)

Pattern to follow: models/database/letzshop.py (VendorLetzshopCredentials)

Files to create/modify:

  • models/database/vendor_invoice_settings.py (new)
  • models/database/__init__.py (add import)
  • models/database/vendor.py (add relationship)
  • models/schema/invoice.py (new - Pydantic schemas)
  • alembic/versions/xxx_add_vendor_invoice_settings.py (migration)

Step 1.2: Basic Invoice Model (0.5 day)

Create invoice storage:

models/database/invoice.py

Fields:

  • id, vendor_id (FK)
  • order_id (FK, nullable - for manual invoices later)
  • invoice_number (unique per vendor)
  • invoice_date
  • seller_details (JSONB snapshot)
  • buyer_details (JSONB snapshot)
  • line_items (JSONB snapshot)
  • subtotal_cents, vat_rate, vat_amount_cents, total_cents
  • currency (default EUR)
  • status (draft, issued, paid, cancelled)
  • pdf_generated_at, pdf_path (optional)

Files to create/modify:

  • models/database/invoice.py (new)
  • models/database/__init__.py (add import)
  • alembic/versions/xxx_add_invoices_table.py (migration)

Step 1.3: Invoice Service - Basic LU Only (1 day)

Create service for invoice generation:

app/services/invoice_service.py

Methods:

  • create_invoice_from_order(order_id, vendor_id) - Generate invoice from order
  • get_invoice(invoice_id, vendor_id) - Retrieve invoice
  • list_invoices(vendor_id, skip, limit) - List vendor invoices
  • _generate_invoice_number(settings) - Auto-increment number
  • _snapshot_seller(settings) - Capture vendor details
  • _snapshot_buyer(order) - Capture customer details
  • _calculate_totals(order) - Calculate with LU VAT (17%)

For Essential tier: Fixed 17% Luxembourg VAT only. EU VAT comes in Professional.

Files to create:

  • app/services/invoice_service.py (new)

Step 1.4: PDF Generation (1.5 days)

Add WeasyPrint dependency and create PDF service:

app/services/invoice_pdf_service.py

Methods:

  • generate_pdf(invoice) - Returns PDF bytes
  • _render_html(invoice) - Jinja2 template rendering

Template:

app/templates/invoices/invoice.html

Simple, clean invoice layout:

  • Seller details (top left)
  • Buyer details (top right)
  • Invoice number + date
  • Line items table
  • Totals with VAT breakdown
  • Footer (payment terms, bank details)

Files to create/modify:

  • requirements.txt (add weasyprint)
  • app/services/invoice_pdf_service.py (new)
  • app/templates/invoices/invoice.html (new)
  • app/templates/invoices/invoice.css (new, optional)

Step 1.5: Invoice API Endpoints (0.5 day)

Create vendor invoice endpoints:

app/api/v1/vendor/invoices.py

Endpoints:

  • POST /orders/{order_id}/invoice - Generate invoice for order
  • GET /invoices - List invoices
  • GET /invoices/{invoice_id} - Get invoice details
  • GET /invoices/{invoice_id}/pdf - Download PDF

Files to create/modify:

  • app/api/v1/vendor/invoices.py (new)
  • app/api/v1/vendor/__init__.py (add router)

Step 1.6: Invoice Settings UI (0.5 day)

Add invoice settings to vendor settings page:

Modify existing vendor settings template to add "Invoice Settings" section:

  • Company name, address fields
  • VAT number
  • Invoice prefix
  • Payment terms
  • Bank details

Files to modify:

  • app/templates/vendor/settings.html (add section)
  • static/vendor/js/settings.js (add handlers)
  • app/api/v1/vendor/settings.py (add endpoints if needed)

Step 1.7: Order Detail - Invoice Button (0.5 day)

Add "Generate Invoice" / "Download Invoice" button to order detail:

  • If no invoice: Show "Generate Invoice" button
  • If invoice exists: Show "Download Invoice" link

Files to modify:

  • app/templates/vendor/order-detail.html (add button)
  • static/vendor/js/order-detail.js (add handler)

Step 1.8: Tier Limits Enforcement (1 day)

Create tier/subscription model:

models/database/vendor_subscription.py

Fields:

  • vendor_id (FK, unique)
  • tier (essential, professional, business)
  • orders_this_month (counter, reset monthly)
  • period_start, period_end
  • is_active

Create limits service:

app/services/tier_limits_service.py

Methods:

  • check_order_limit(vendor_id) - Returns (allowed: bool, remaining: int)
  • increment_order_count(vendor_id) - Called when order synced
  • get_tier_limits(tier) - Returns limit config
  • reset_monthly_counters() - Cron job

Tier limits:

Tier Orders/month Products
Essential 100 200
Professional 500 Unlimited
Business Unlimited Unlimited

Integration points:

  • order_service.py - Check limit before creating order
  • Letzshop sync - Check limit before importing

Files to create/modify:

  • models/database/vendor_subscription.py (new)
  • app/services/tier_limits_service.py (new)
  • app/services/order_service.py (add limit check)
  • app/services/letzshop/order_service.py (add limit check)

Phase 2: Professional Tier (Target: 2 weeks)

Goal: Build the differentiating features that justify €99/month.

Step 2.1: EU VAT Rates Table (0.5 day)

Create VAT rates reference table:

models/database/eu_vat_rates.py

Fields:

  • country_code (LU, DE, FR, etc.)
  • country_name
  • standard_rate (decimal)
  • reduced_rate_1, reduced_rate_2 (optional)
  • effective_from, effective_until

Seed with current EU rates (27 countries).

Files to create:

  • models/database/eu_vat_rates.py (new)
  • alembic/versions/xxx_add_eu_vat_rates.py (migration + seed)

Step 2.2: Enhanced Vendor VAT Settings (0.5 day)

Add OSS fields to VendorInvoiceSettings:

  • is_oss_registered (boolean)
  • oss_registration_country (if different from company country)

Files to modify:

  • models/database/vendor_invoice_settings.py (add fields)
  • alembic/versions/xxx_add_oss_fields.py (migration)

Step 2.3: VAT Service (1 day)

Create VAT calculation service:

app/services/vat_service.py

Methods:

  • get_vat_rate(country_code, as_of_date) - Lookup rate
  • determine_vat_regime(seller_country, buyer_country, buyer_vat_number, is_oss) - Returns (regime, rate)
  • validate_vat_number(vat_number) - Format check (VIES integration later)

VAT Decision Logic:

  1. B2B with valid VAT number → Reverse charge (0%)
  2. Domestic sale → Domestic VAT
  3. Cross-border + OSS registered → Destination VAT
  4. Cross-border + under threshold → Origin VAT

Files to create:

  • app/services/vat_service.py (new)

Step 2.4: Enhanced Invoice Service (1 day)

Upgrade invoice service for EU VAT:

  • Add vat_regime field to invoice (domestic, oss, reverse_charge, origin)
  • Add destination_country field
  • Use VATService to calculate correct rate
  • Update invoice template for regime-specific text

Files to modify:

  • models/database/invoice.py (add fields)
  • app/services/invoice_service.py (use VATService)
  • app/templates/invoices/invoice.html (add regime text)
  • alembic/versions/xxx_add_vat_regime_to_invoices.py

Step 2.5: Purchase Order Model (1 day)

Create purchase order tracking:

models/database/purchase_order.py

PurchaseOrder:

  • id, vendor_id (FK)
  • po_number (auto-generated)
  • supplier_name (free text for now)
  • status (draft, ordered, partial, received, cancelled)
  • order_date, expected_date
  • notes

PurchaseOrderItem:

  • purchase_order_id (FK)
  • product_id (FK)
  • quantity_ordered
  • quantity_received
  • unit_cost_cents (optional)

Files to create:

  • models/database/purchase_order.py (new)
  • models/database/__init__.py (add import)
  • models/schema/purchase_order.py (new)
  • alembic/versions/xxx_add_purchase_orders.py

Step 2.6: Purchase Order Service (1 day)

Create PO management service:

app/services/purchase_order_service.py

Methods:

  • create_purchase_order(vendor_id, data) - Create PO
  • add_item(po_id, product_id, quantity) - Add line item
  • receive_items(po_id, items) - Mark items received, update inventory
  • get_incoming_stock(vendor_id) - Summary of pending stock
  • list_purchase_orders(vendor_id, status, skip, limit)

Integration: When items received → call inventory_service.adjust_inventory()

Files to create:

  • app/services/purchase_order_service.py (new)

Step 2.7: Purchase Order UI (1.5 days)

Create PO management page:

app/templates/vendor/purchase-orders.html

Features:

  • List POs with status
  • Create new PO (select products, quantities, expected date)
  • Receive items (partial or full)
  • View incoming stock summary

Inventory page enhancement:

  • Show "On Order" column in inventory list
  • Query: SUM of quantity_ordered - quantity_received for pending POs

Files to create/modify:

  • app/templates/vendor/purchase-orders.html (new)
  • static/vendor/js/purchase-orders.js (new)
  • app/api/v1/vendor/purchase_orders.py (new endpoints)
  • app/routes/vendor_pages.py (add route)
  • app/templates/vendor/partials/sidebar.html (add menu item)
  • app/templates/vendor/inventory.html (add On Order column)

Step 2.8: Customer Export Service (1 day)

Create customer export functionality:

app/services/customer_export_service.py

Methods:

  • export_customers_csv(vendor_id, filters) - Returns CSV string

CSV Columns:

  • email, first_name, last_name, phone
  • customer_number
  • total_orders, total_spent, avg_order_value
  • first_order_date, last_order_date
  • preferred_language
  • marketing_consent
  • tags (if we add tagging)

Files to create:

  • app/services/customer_export_service.py (new)

Step 2.9: Customer Export API + UI (0.5 day)

Add export endpoint:

GET /api/v1/vendor/customers/export?format=csv

Add export button to customers page:

  • "Export to CSV" button
  • Downloads file directly

Files to modify:

  • app/api/v1/vendor/customers.py (add export endpoint)
  • app/templates/vendor/customers.html (add button)

Phase 3: Business Tier (Target: 1-2 weeks)

Goal: Build features for teams and high-volume operations.

Step 3.1: Multi-Vendor Consolidated View (2 days)

For companies with multiple Letzshop accounts:

New page:

app/templates/vendor/multi-vendor-dashboard.html

Features:

  • See all vendor accounts under same company
  • Consolidated order count, revenue
  • Switch between vendor contexts
  • Unified reporting

Requires: Company-level authentication context (already exists via Company → Vendor relationship)

Files to create/modify:

  • app/templates/vendor/multi-vendor-dashboard.html (new)
  • app/services/multi_vendor_service.py (new)
  • app/api/v1/vendor/multi_vendor.py (new)

Step 3.2: Accounting Export (1 day)

Export invoices in accounting-friendly formats:

app/services/accounting_export_service.py

Methods:

  • export_invoices_csv(vendor_id, date_from, date_to) - Simple CSV
  • export_invoices_xml(vendor_id, date_from, date_to) - For accounting software

CSV format for accountants:

  • invoice_number, invoice_date
  • customer_name, customer_vat
  • subtotal, vat_rate, vat_amount, total
  • currency, status

Files to create:

  • app/services/accounting_export_service.py (new)
  • app/api/v1/vendor/accounting.py (new endpoints)

Step 3.3: API Access Documentation (1 day)

If not already documented, create API documentation page:

  • Document existing vendor API endpoints
  • Add rate limiting for API tier
  • Generate API keys for vendors

Files to create/modify:

  • docs/api/vendor-api.md (documentation)
  • app/services/api_key_service.py (if needed)

Implementation Order Summary

Week 1: Essential Tier

Day Task Deliverable
1 Step 1.1 Vendor Invoice Settings model
1 Step 1.2 Invoice model
2 Step 1.3 Invoice Service (LU only)
3-4 Step 1.4 PDF Generation
4 Step 1.5 Invoice API
5 Step 1.6 Invoice Settings UI
5 Step 1.7 Order Detail button

Week 2: Tier Limits + EU VAT Start

Day Task Deliverable
1 Step 1.8 Tier limits enforcement
2 Step 2.1 EU VAT rates table
2 Step 2.2 OSS fields
3 Step 2.3 VAT Service
4 Step 2.4 Enhanced Invoice Service
5 Testing End-to-end invoice testing

Week 3: Purchase Orders + Customer Export

Day Task Deliverable
1 Step 2.5 Purchase Order model
2 Step 2.6 Purchase Order service
3-4 Step 2.7 Purchase Order UI
5 Step 2.8-2.9 Customer Export

Week 4: Business Tier

Day Task Deliverable
1-2 Step 3.1 Multi-vendor view
3 Step 3.2 Accounting export
4 Step 3.3 API documentation
5 Testing + Polish Full testing

Key Files Reference

Models to Create

  • models/database/vendor_invoice_settings.py
  • models/database/invoice.py
  • models/database/eu_vat_rates.py
  • models/database/vendor_subscription.py
  • models/database/purchase_order.py

Services to Create

  • app/services/invoice_service.py
  • app/services/invoice_pdf_service.py
  • app/services/vat_service.py
  • app/services/tier_limits_service.py
  • app/services/purchase_order_service.py
  • app/services/customer_export_service.py
  • app/services/accounting_export_service.py

Templates to Create

  • app/templates/invoices/invoice.html
  • app/templates/vendor/purchase-orders.html

Existing Files to Modify

  • models/database/__init__.py
  • models/database/vendor.py
  • app/services/order_service.py
  • app/templates/vendor/settings.html
  • app/templates/vendor/order-detail.html
  • app/templates/vendor/inventory.html
  • app/templates/vendor/customers.html
  • requirements.txt

Dependencies to Add

# requirements.txt
weasyprint>=60.0

Note: WeasyPrint requires system dependencies:

  • libpango-1.0-0
  • libpangocairo-1.0-0
  • libgdk-pixbuf2.0-0

Add to Dockerfile if deploying via Docker.


Testing Strategy

Unit Tests

  • tests/unit/services/test_invoice_service.py
  • tests/unit/services/test_vat_service.py
  • tests/unit/services/test_tier_limits_service.py
  • tests/unit/services/test_purchase_order_service.py

Integration Tests

  • tests/integration/api/v1/vendor/test_invoices.py
  • tests/integration/api/v1/vendor/test_purchase_orders.py

Manual Testing

  • Generate invoice for LU customer
  • Generate invoice for DE customer (OSS)
  • Generate invoice for B2B with VAT number (reverse charge)
  • Create PO, receive items, verify inventory update
  • Export customers CSV, import to Mailchimp

Success Criteria

Essential Tier Ready When:

  • Can generate PDF invoice from order (LU VAT)
  • Invoice settings page works
  • Order detail shows invoice button
  • Tier limits enforced on order sync

Professional Tier Ready When:

  • EU VAT calculated correctly by destination
  • OSS regime supported
  • Reverse charge for B2B supported
  • Purchase orders can be created and received
  • Incoming stock shows in inventory
  • Customer export to CSV works

Business Tier Ready When:

  • Multi-vendor dashboard works
  • Accounting export works
  • API access documented