docs: update Letzshop order import documentation
- Update implementation guide with unified order approach - Add mkdocs navigation entry - Add background task for order sync - Add debug script for historical imports 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -463,39 +463,97 @@ From the Letzshop merchant interface:
|
||||
- Filter dropdown, status badges, and action buttons now use "Declined"
|
||||
- Added "Declined" stats card to orders dashboard
|
||||
|
||||
### Historical Import: Declined Orders ✅
|
||||
- Historical import now fetches both `confirmed` AND `declined` shipments
|
||||
### Historical Import: Multiple Phases ✅
|
||||
- Historical import now fetches both `confirmed` AND `unconfirmed` (pending) shipments
|
||||
- Note: "declined" is NOT a valid Letzshop shipment state - declined items are tracked at inventory unit level
|
||||
- Combined stats shown in import result
|
||||
|
||||
---
|
||||
|
||||
## Completed (2025-12-19)
|
||||
|
||||
### Historical Import Progress Bar ✅
|
||||
Real-time progress feedback for historical import using background tasks with database polling.
|
||||
|
||||
**Implementation:**
|
||||
- Background task (`app/tasks/letzshop_tasks.py`) runs historical import asynchronously
|
||||
- Progress stored in `LetzshopHistoricalImportJob` database model
|
||||
- Frontend polls status endpoint every 2 seconds
|
||||
- Two-phase import: confirmed orders first, then unconfirmed (pending) orders
|
||||
|
||||
**Backend:**
|
||||
- `LetzshopHistoricalImportJob` model tracks: status, current_phase, current_page, shipments_fetched, orders_processed, confirmed_stats, declined_stats
|
||||
- `POST /vendors/{id}/import-history` starts background job, returns job_id immediately
|
||||
- `GET /vendors/{id}/import-history/{job_id}/status` returns current progress
|
||||
|
||||
**Frontend:**
|
||||
- Progress panel shows: phase (confirmed/pending), page number, shipments fetched, orders processed
|
||||
- Disabled "Import History" button during import with spinner
|
||||
- Final result summary shows combined stats from both phases
|
||||
|
||||
**Key Discovery:**
|
||||
- Letzshop API has NO "declined" shipment state
|
||||
- Valid states: `awaiting_order_completion`, `unconfirmed`, `completed`, `accepted`, `confirmed`
|
||||
- Declined items are tracked at inventory unit level with state `confirmed_unavailable`
|
||||
|
||||
### Filter for Declined Items ✅
|
||||
Added ability to filter orders that have at least one declined/unavailable item.
|
||||
|
||||
**Backend:**
|
||||
- `list_orders()` accepts `has_declined_items: bool` parameter
|
||||
- Uses JSON string contains check: `inventory_units.cast(String).contains("confirmed_unavailable")`
|
||||
- `get_order_stats()` returns `has_declined_items` count
|
||||
|
||||
**Frontend:**
|
||||
- "Has Declined Items" toggle button in filters section
|
||||
- Shows count badge when there are orders with declined items
|
||||
- Toggles between all orders and filtered view
|
||||
|
||||
**API:**
|
||||
- `GET /vendors/{id}/orders?has_declined_items=true` - filter orders
|
||||
|
||||
### Order Date Display ✅
|
||||
Orders now display the actual order date from Letzshop instead of the import date.
|
||||
|
||||
**Database:**
|
||||
- Added `order_date` column to `LetzshopOrder` model
|
||||
- Migration: `2362c2723a93_add_order_date_to_letzshop_orders.py`
|
||||
|
||||
**Backend:**
|
||||
- `create_order()` extracts `completedAt` from Letzshop order data and stores as `order_date`
|
||||
- `update_order_from_shipment()` populates `order_date` if not already set
|
||||
- Date parsing handles ISO format with timezone (including `Z` suffix)
|
||||
|
||||
**Frontend:**
|
||||
- Order table displays `order_date` with fallback to `created_at` for legacy orders
|
||||
- Format: localized date/time string
|
||||
|
||||
**Note:** Existing orders imported before this change will continue showing `created_at` until re-imported via historical import.
|
||||
|
||||
### Search Filter ✅
|
||||
Added search functionality to find orders by order number, customer name, or email.
|
||||
|
||||
**Backend:**
|
||||
- `list_orders()` accepts `search: str` parameter
|
||||
- Uses ILIKE for case-insensitive partial matching across:
|
||||
- `letzshop_order_number`
|
||||
- `customer_name`
|
||||
- `customer_email`
|
||||
|
||||
**Frontend:**
|
||||
- Search input field with magnifying glass icon
|
||||
- Debounced input (300ms) to avoid excessive API calls
|
||||
- Clear button to reset search
|
||||
- Resets to page 1 when search changes
|
||||
|
||||
**API:**
|
||||
- `GET /vendors/{id}/orders?search=query` - search orders
|
||||
|
||||
---
|
||||
|
||||
## Next Steps (TODO)
|
||||
|
||||
### Priority 1: Historical Import Progress Bar
|
||||
Add real-time progress feedback for historical import (currently no visibility into import progress).
|
||||
|
||||
**Requirements:**
|
||||
- Show progress indicator while import is running
|
||||
- Display current page being fetched (e.g., "Fetching page 3 of 12...")
|
||||
- Show running count of orders imported/updated
|
||||
- Prevent user from thinking the process is stuck
|
||||
|
||||
**Implementation options:**
|
||||
1. **Polling approach**: Frontend polls a status endpoint every few seconds
|
||||
2. **Server-Sent Events (SSE)**: Real-time updates pushed to frontend
|
||||
3. **WebSocket**: Bi-directional real-time communication
|
||||
|
||||
**Backend changes needed:**
|
||||
- Store import progress in database or cache (Redis)
|
||||
- Add endpoint `GET /api/v1/admin/letzshop/vendors/{id}/import-progress`
|
||||
- Update `import_historical_shipments()` to report progress
|
||||
|
||||
**Frontend changes needed:**
|
||||
- Progress bar component in Orders tab
|
||||
- Polling/SSE logic to fetch progress updates
|
||||
- Disable "Import History" button while import is in progress
|
||||
|
||||
### Priority 2: Stock Management
|
||||
### Priority 1: Stock Management
|
||||
When an order is confirmed/imported:
|
||||
1. Match EAN from order to local product catalog
|
||||
2. Decrease stock quantity for matched products
|
||||
@@ -506,18 +564,12 @@ When an order is confirmed/imported:
|
||||
- Need rollback mechanism if order is rejected
|
||||
- Handle partial matches (some items found, some not)
|
||||
|
||||
### Priority 2: Order Detail View Enhancement
|
||||
Improve the order detail modal to show:
|
||||
- Product details (name, EAN, MPN, SKU)
|
||||
- Match status per line item (found/not found in catalog)
|
||||
- Link to local product if matched
|
||||
|
||||
### Priority 3: Invoice Generation
|
||||
### Priority 2: Invoice Generation
|
||||
Use `customer_locale` to generate invoices in customer's language:
|
||||
- Invoice template with multi-language support
|
||||
- PDF generation
|
||||
|
||||
### Priority 4: Analytics Dashboard
|
||||
### Priority 3: Analytics Dashboard
|
||||
Build sales analytics based on imported orders:
|
||||
- Sales by product
|
||||
- Sales by time period
|
||||
@@ -526,20 +578,24 @@ Build sales analytics based on imported orders:
|
||||
|
||||
---
|
||||
|
||||
## Files Modified (2025-12-16 to 2025-12-18)
|
||||
## Files Modified (2025-12-16 to 2025-12-19)
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `app/services/letzshop/client_service.py` | Added paginated query, updated all queries with EAN/locale/country |
|
||||
| `app/services/letzshop/order_service.py` | Added historical import, EAN matching, summary endpoint, order stats |
|
||||
| `models/database/letzshop.py` | Added locale and country columns |
|
||||
| `app/services/letzshop/order_service.py` | Historical import, EAN matching, order stats, has_declined_items filter, search filter, order_date extraction |
|
||||
| `models/database/letzshop.py` | Added locale/country/order_date columns, `LetzshopHistoricalImportJob` model |
|
||||
| `models/database/product.py` | Added `gtin` and `gtin_type` columns for EAN matching |
|
||||
| `models/schema/letzshop.py` | Added `LetzshopOrderStats` schema, stats to order list response |
|
||||
| `app/api/v1/admin/letzshop.py` | Added import-history and import-summary endpoints, stats in orders response |
|
||||
| `app/templates/admin/partials/letzshop-orders-tab.html` | Added Import History button and result display |
|
||||
| `static/admin/js/marketplace-letzshop.js` | Added importHistoricalOrders(), server-side stats |
|
||||
| `models/schema/letzshop.py` | Added `LetzshopOrderStats`, `LetzshopHistoricalImportJobResponse`, `order_date` field |
|
||||
| `app/api/v1/admin/letzshop.py` | Import-history endpoints, has_declined_items filter, search filter, order_date in response |
|
||||
| `app/tasks/letzshop_tasks.py` | **NEW** - Background task for historical import with progress tracking |
|
||||
| `app/templates/admin/partials/letzshop-orders-tab.html` | Import History button, progress panel, declined items filter, search input, order_date display |
|
||||
| `static/admin/js/marketplace-letzshop.js` | Historical import polling, progress display, declined items filter, search functionality |
|
||||
| `tests/unit/services/test_letzshop_service.py` | Added tests for new functionality |
|
||||
| `scripts/test_historical_import.py` | Manual test script for historical import |
|
||||
| `scripts/debug_historical_import.py` | **NEW** - Debug script for shipment states and declined items |
|
||||
| `scripts/letzshop_introspect.py` | GraphQL schema introspection tool, tracking workaround tests |
|
||||
| `alembic/versions/a9a86cef6cca_*.py` | Migration for locale/country columns |
|
||||
| `alembic/versions/cb88bc9b5f86_*.py` | Migration for gtin columns on Product table |
|
||||
| `alembic/versions/*_add_historical_import_jobs.py` | **NEW** - Migration for LetzshopHistoricalImportJob table |
|
||||
| `alembic/versions/2362c2723a93_*.py` | **NEW** - Migration for order_date column |
|
||||
|
||||
Reference in New Issue
Block a user