Skip to content

Plenty

service_omni — Endpoints: Plenty

Location: backend/service_omni/app/api/v1/endpoints/plenty.py

Base path: /api/v1/omni/plenty (JWT auth unless noted).

Summary

  • Manage Plenty API credentials
  • Import sales orders into plenty_orders
  • Import return orders (Retouren) into plenty_retours and link to parent sales orders
  • Legacy Shopify export tasks

For the data model and Metabase queries, see Plenty orders & retours.


Credentials

Method Route Description
POST /credentials/ Create credential (PlentyCredentialsCreate)
GET /credentials/ List credentials
PUT /credentials/{credential_id} Update credential
POST /credentials/{credential_id}/toggle-active Toggle active_omni
DELETE /credentials/{credential_id} Delete credential
POST /credentials/test Validate username/password/plenty_id

Example create body:

{
  "username": "plenty_user",
  "password": "secret",
  "plenty_id": 69524,
  "active_omni": true
}

Order and retour imports use the credential with active_omni=true.


Sales orders

Method Route Description
POST /orders?date=YYYY-MM-DD Fetch & store paid sales orders for one day
POST /orders/range?start_date=…&end_date=… Backfill sales orders for each day in range

Plenty filter: sales orders (orderTypeId=1), statusId=7, order date = query date.

Response (PlentyOrdersResponse):

{
  "date": "2026-07-13",
  "total_lines": 42,
  "lines": [{ "order_id": 51657, "asin_sku": "…", "…": "…" }]
}

Unpaid orders (property typeId=4fullyPaid) are queued in plenty_pending_orders for cron retry.

Example:

curl -X POST "http://localhost:8007/api/v1/omni/plenty/orders/range?start_date=2026-07-01&end_date=2026-07-13" \
  -H "Authorization: Bearer $TOKEN"

Retours (returns)

Method Route Description
POST /retours?date=YYYY-MM-DD Fetch & store return orders for one day
POST /retours/range?start_date=…&end_date=… Backfill retours for each day in range

Plenty filter: return orders (orderTypeId=4), orderDate_2 on selected day.

Side effects:

  1. Rows upserted into plenty_retours (one row per returned article line)
  2. Missing parent sales orders fetched from Plenty and inserted into plenty_orders
  3. Parent orders marked has_retour=true in plenty_orders

Response (PlentyRetoursResponse):

{
  "date": "2026-07-13",
  "total_lines": 5,
  "parent_orders_total": 5,
  "parent_orders_fetched": 4,
  "parent_orders_marked": 5,
  "parent_orders_missing": 0,
  "lines": [
    {
      "retour_id": 52484,
      "parent_order_id": 51657,
      "retour_date": "2026-07-13",
      "asin_sku": "RitualsSakuraGeschenkSetS2025",
      "price_gross": 39.9
    }
  ]
}
Field Meaning
parent_orders_total Unique parent sales order IDs from retours
parent_orders_fetched Parents newly imported from Plenty (not in DB before)
parent_orders_marked Parents now flagged has_retour=true
parent_orders_missing Parent IDs Plenty did not return

Example:

curl -X POST "http://localhost:8007/api/v1/omni/plenty/retours/range?start_date=2026-07-13&end_date=2026-07-13" \
  -H "Authorization: Bearer $TOKEN"

Frontend: Statistics → Profit → Manual Plenty Retour Date Range Import.


Shopify export (legacy)

Method Route Description
POST /export/to/shopify Start export task
POST /export/to/shopify/stop Stop export
GET /export/to/shopify/status Export status

Artifacts under shopify_export_data/ (TODO/done/failed JSON files).


Implementation

Component Path
Endpoints plenty.py
Plenty manager plenty_manager.py
Orders CRUD plenty_orders.py
Retours CRUD plenty_retours.py
Models / DB schema schemas/plenty.py

Operational notes

  • Ensure the Plenty account has order read permissions before bulk import.
  • Retour import date = return creation date, not original sale date — parent backfill covers older sales orders.
  • Re-importing the same retour day replaces rows for the same retour_id (idempotent upsert).