1.2.6
🚀 New Features¶
- Added a debug page and backend endpoint to request, poll, and download Selling Partner API reports from Amazon.
- Frontend:
/debug/amazon/reports— form to request any SP-API report byreportType,marketplaceIds, optionaldataStartTime/dataEndTime, andreportOptionsJSON. The page downloads the resulting file automatically. - Backend:
POST /reports/retrieve— unified server-side flow moved toservices.amazon.spapi_client.fetch_report_document()which:- creates the report via SP-API,
- polls until processing finishes (handles
IN_QUEUE/IN_PROGRESS→DONE/FATAL/CANCELLED), - fetches report document metadata and downloads the document,
- decompresses GZIP payloads and returns the raw bytes.
- Behavior: the server now content-sniffs the downloaded document and returns a
.tsv(tab-separated) response for tab-delimited reports,.txtfor other formats. The frontend derives the filename from the requestedreportType(CORS hides Content-Disposition in some setups). - Notes: The frontend uses repeated
marketplaceIdsquery params (viaURLSearchParams.append) to satisfy FastAPI'sList[str]parsing.reportOptionsis sent as JSON body. - For Kaufland Articles Standard package of type "S-Paket" is selected if no weight can be found in plenty
🔧 Improvements¶
- End-to-end
maximum_pricesupport for Kaufland articles: - Backend:
maximum_priceadded to the update models so the API accepts and persists the field. - Frontend: "Max Price (€)" field added to the Kaufland article edit/create dialog and included in save flow (converted to cents).
-
DB: migration SQL added to create the
maximum_pricecolumn when missing. -
Reworked Otto product sync to use active-status as single source of truth:
- Added
get_active_status_bulk()to callGET /v5/products/active-statusonce (paginated) and produce a SKU->active boolean map. - Sync endpoint now performs a diff-first algorithm: (1) fetch active-status, (2) purge DB SKUs that are inactive, (3) compute candidate SKUs (active but not in DB), (4) call quantity API only for candidates and import only those with quantity > 0.
- New imports are enriched by fetching product data (
get_product_data) for fields likemoin,weight,my_price,sale_price, andcategoryso created records are immediately useful. - Result: drastically fewer API calls, deterministic purge behavior, and more complete article records on import.
🐛 Bug Fixes¶
-
Fixed toggle persistence: clearing cached article pages after toggling "Use Min/Max Rules" so the UI shows the persisted value immediately instead of stale cached data.
-
Prevented spurious recalculation on Kaufland article updates: the endpoint now only triggers recalculation when fields were explicitly sent and actually changed (uses
model_fields_set), so manually-savedmaximum_priceand other fields are not overwritten. -
Fixed CRUD update behavior that prevented clearing fields to
null: removed an overly-strictvalue is not Noneguard sonullvalues from the client are now persisted. -
Frontend: after saving an article the cache is now cleared and a forced refetch is performed so the UI shows saved values immediately (avoids stale localStorage entries).
-
Fixed a bug in the Plenty population cron workflow where a FastAPI
Query(...)default leaked into a direct function call and was passed to SQLAlchemy as a value (error: "can't adapt type 'Query'"). -
Root cause: endpoint-style parameter defaults (e.g.
snapshot_date: Optional[date] = Query(None)) are FastAPI wrappers and are not automatically unwrapped when the function is invoked directly from Python code. -
Fix: explicitly pass
snapshot_date=Nonewhen callingcalculate_and_update_stock_valuesfrom the populate workflow, ensuring SQLAlchemy receivesNonerather than aQueryobject. This prevents SQL binding errors during the FIFO stock-value calculation and allows the cron job to complete.