1.8.14
⚙️ Patch 1.8.14 — Plenty retours import & parent order linking¶
🚀 Summary¶
- Plenty retours storage — return orders (
orderTypeId=4) are fetched from Plenty, stored in a newplenty_retourstable (one row per returned article line), and linked to the original sales order viaparent_order_id. has_retouronplenty_orders— parent sales orders are flagged when a retour exists; missing parent orders are backfilled from Plenty automatically during retour import.- Profit cron & UI — daily profit cron now imports yesterday's retours; Statistics → Profit tab has a manual retour date-range import panel.
✨ Improvements¶
Database¶
| Table / column | Purpose |
|---|---|
plenty_retours |
Flat retour lines: retour_id, parent_order_id, item/SKU, amounts, retour_date, origin, shipping destination |
plenty_orders.has_retour |
BOOLEAN, indexed — true when at least one retour references this sales order_id |
Migration: docker/postgres/updates/add_plenty_retours_and_has_retour.sql
Fresh installs: docker/postgres/tables/plenty_retours.sql + updated plenty_orders.sql.
service-omni — Plenty API¶
| Route | Purpose |
|---|---|
POST /api/v1/omni/plenty/retours?date=YYYY-MM-DD |
Fetch & store retours for one day |
POST /api/v1/omni/plenty/retours/range?start_date=…&end_date=… |
Backfill retours for a date range |
Plenty search filter: orderTypeId in [4] + orderDate_2 between start/end of day (same timezone pattern as orders).
Parent resolution: orderItemSummary.parentOrderId → fallback orderReferences (referenceType: "parent") → fallback reverseOrderReferences.
Backfill flow: After storing retours, any parent_order_id not yet in plenty_orders is fetched via GET /rest/orders?orderIds=…, upserted, and marked has_retour=true.
Response fields (PlentyRetoursResponse):
| Field | Meaning |
|---|---|
total_lines |
Retour article lines stored |
parent_orders_total |
Unique parent sales order IDs referenced |
parent_orders_fetched |
Parent orders newly imported from Plenty |
parent_orders_marked |
Unique parent orders with has_retour=true |
parent_orders_missing |
Parent IDs Plenty did not return |
Profit cron (Statistics)¶
The existing plenty_orders_runner cron now runs, in order:
- Retry unpaid pending orders
- Fetch yesterday's Plenty sales orders
- Fetch yesterday's Plenty retours (+ parent backfill)
- Sync yesterday's Amazon FBA orders
Cron endpoints unchanged: POST /statistics/profit/cron/start|stop, GET /statistics/profit/cron/status.
Frontend¶
| Area | Change |
|---|---|
| Statistics → Profit | New card Manual Plenty Retour Date Range Import |
| API client | profitStatisticsApi.storeRetoursForDateRange(start, end) |
| Success message | Shows retour lines, backfilled parents, marked count, and any missing parents |
DB sync¶
plenty_retours added to scripts/db-sync/tables.json (full + profit presets).
🔧 Deploy¶
- Run migration on Postgres:
psql -f docker/postgres/updates/add_plenty_retours_and_has_retour.sql - Rebuild / restart
service-omni. - Rebuild frontend (Profit tab retour import UI).
- Rebuild docs if you publish patchnotes from the repo.
- Optional: backfill historical retours via UI or API before relying on
has_retourin Metabase.
✅ Verify¶
- Single day:
POST /api/v1/omni/plenty/retours?date=2026-07-13→200,total_lines > 0,parent_orders_markedmatches unique parents. - Parent backfill: Import retours for a day where parent sales orders were never imported →
parent_orders_fetched > 0, corresponding rows appear inplenty_orderswithhas_retour=true. - Metabase:
SELECT order_id, has_retour FROM plenty_orders WHERE has_retour = truereturns expected IDs; joinplenty_retours.parent_order_id = plenty_orders.order_id. - Cron: After next profit cron run, logs show retour fetch step without error.
- UI: Statistics → Profit → Import Retours for a date range → success toast with fetched/marked counts.
- Tests:
pytest backend/service_omni/app/tests/test_plenty_retours.py
⚠️ Notes¶
- Retours are filtered by retour creation date (
orderDate_2), not the original sales order date — parent orders may be from weeks earlier; backfill handles that. has_retouris set on all line rows sharing the sameorder_idinplenty_orders.- Re-importing retours for the same
retour_idreplaces existing rows (upsert by retour id). - Plenty property
typeId=4on orders is payment status (fullyPaid); return orders use top-leveltypeId: 4(order type) — do not confuse the two when debugging.
Files touched¶
service-omni
app/services/plenty/plenty_manager.py—search_retours,_parse_retour_entries,fetch_orders_by_idsapp/crud/plenty_retours.py— retour upsert + parent markingapp/crud/plenty_orders.py—has_retour,get_existing_order_ids,mark_has_retourapp/api/v1/endpoints/plenty.py—/retours,/retours/range,_store_retours_for_dateapp/api/v1/endpoints/statistics.py— cron retour stepapp/models/plenty.py,app/schemas/plenty.py—PlentyRetourLine,PlentyRetoursResponse,PlentyRetourLineRecordapp/tests/test_plenty_retours.py
frontend
src/pages/Statistics/Tabs/ProfitTab.jsx— retour import cardsrc/services/api/omni/statistics.js—storeRetoursForDateRange
database / sync
docker/postgres/tables/plenty_retours.sqldocker/postgres/tables/plenty_orders.sql—has_retourcolumndocker/postgres/updates/add_plenty_retours_and_has_retour.sqlscripts/db-sync/tables.json
docs
docs/docs/patchnotes/1.8/1.8.14.md— this filedocs/docs/services/service_omni/endpoints/plenty.mddocs/docs/services/service_omni/endpoints/statistics.mddocs/docs/services/service_omni/services/plenty_orders_retours.mddocs/docs/services/service_omni/services/plenty.md