Comenzi
Creează și gestionează comenzi. Comenzile parcurg statusuri — pending (statusul cu care se creează), processing, assigned, picked, ready_to_ship, shipped, delivered, completed, plus stările terminale cancelled, returned, partially_returned și fully_returned.
Endpoint-uri
| Metodă | Cale | Descriere |
|---|---|---|
| GET | /api/v1/orders | Listă paginată; filtre status, order_number, external_order_id, customer_name, date_from, date_to. |
| GET | /api/v1/orders/{id} | Citește o comandă cu liniile, istoricul de status și operatorul asignat. |
| POST | /api/v1/orders | Creează o comandă. |
| PUT | /api/v1/orders/{id}/status | Actualizează statusul unei comenzi. |
| DELETE | /api/v1/orders/{id} | Șterge definitiv o comandă (doar pending sau cancelled). |
Filtre la listare
| Parametru | Tip | Note |
|---|---|---|
status | string | Filtrează după status. |
order_number | string | Potrivire exactă pe numărul intern al comenzii. |
external_order_id | string | Potrivire exactă pe id-ul din sistemul extern. |
customer_name | string | Potrivire parțială pe numele clientului. |
date_from | YYYY-MM-DD | Comenzi cu order_date ≥ valoarea dată. |
date_to | YYYY-MM-DD | Comenzi cu order_date ≤ valoarea dată. |
per_page | integer | Implicit 50. |
Creare comandă
POST /api/v1/orders. Câmpuri obligatorii: customer_name, shipping_method și cel puțin o linie în items.
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
customer_name | string ≤ 255 | da | Numele destinatarului. |
shipping_method | string | da | Trebuie să fie unul din codurile returnate de GET /api/v1/couriers. |
items | array (min 1) | da | Liniile comenzii. |
items[].product_id | integer | da | Trebuie să existe (products.product_id). |
items[].quantity | integer ≥ 1 | da | Cantitatea comandată. |
items[].unit_price | numeric ≥ 0 | nu | Preț unitar; implicit 0. |
items[].notes | text | nu | Notă pe linie. |
order_number | string ≤ 50 | nu | Generat automat (ORD-000123) dacă lipsește. |
external_order_id | string ≤ 100 | nu | Id-ul comenzii în sistemul tău. |
external_source | string ≤ 50 | nu | Sursa (ex. shopify, woocommerce). |
type | string ≤ 50 | nu | |
warehouse_id | integer | nu | Trebuie să existe; vezi rezolvarea depozitului mai jos. |
customer_email | email ≤ 255 | nu | |
shipping_address | text | nu | |
address_text | text | nu | Adresă liberă, dintr-o singură linie. |
recipient_phone | string ≤ 20 | nu | |
recipient_contact_person | string ≤ 255 | nu | |
recipient_county_name | string ≤ 100 | nu | Județul destinatarului (folosit la AWB). |
recipient_locality_name | string ≤ 100 | nu | Localitatea destinatarului. |
total_value | numeric ≥ 0 | nu | |
total_weight | numeric ≥ 0 | nu | |
notes | text | nu | |
order_date | YYYY-MM-DD | nu | Implicit acum. |
required_date | YYYY-MM-DD | nu | |
priority | enum | nu | low | normal | high | urgent. |
invoice_reference | string ≤ 100 | nu | Numărul facturii care însoțește comanda (stocat ca atare pe comandă). |
client_cui | string ≤ 20 | nu | CUI-ul clientului — folosit doar în numele fișierului de factură. |
invoice_pdf | string | nu | Documentul facturii, ca PDF codat base64. Vezi mai jos. |
Comportamente la creare:
- Curieri obligatorii. Dacă tenantul nu are niciun curier configurat, cererea returnează
422cucode: no_couriers_configuredînainte de validare. Configurează un curier în Setări → Curieri, apoi citește valorile valide dinGET /api/v1/couriers. - Deduplicare linii. Două linii cu același
product_idsunt comasate într-o singură linie (cantitățile se adună), ca să nu generezi sarcini de picking duplicate. - Status inițial. Comanda se creează cu
status = pending. - Rezolvarea depozitului. În ordine:
warehouse_iddin body → depozitul de care e legată cheia API → headerX-Warehouse-Id→ depozitul implicit al tenantului. Dacă trimiți unwarehouse_idcare diferă de depozitul de care e legată cheia, primești403. - Documentul facturii. Dacă trimiți
invoice_pdf, platforma îl decodează din base64, verifică să fie un PDF valid (altfel422cucode: invalid_invoice_pdf, înainte de a crea comanda) și îl salvează caorder_pdf_invoices/factura-{referință}[-cui-RO{cui}].pdf. Calea ajunge îninvoice_file_pathpe comandă, împreună cuinvoice_uploaded_at.invoice_referencepoate fi trimis și singur, fără document.
curl -X POST https://tenant.notsowms.ro/api/v1/orders \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Andrei Popescu",
"customer_email": "andrei@example.com",
"shipping_method": "cargus",
"recipient_phone": "+40712345678",
"recipient_county_name": "Cluj",
"recipient_locality_name": "Cluj-Napoca",
"address_text": "Str. Memorandumului 28",
"priority": "high",
"items": [
{ "product_id": 812, "quantity": 2, "unit_price": 149.90 }
]
}'Răspuns 201 — comanda creată, cu liniile ei:
{
"data": {
"id": 4471,
"order_number": "ORD-000123",
"status": "pending",
"customer_name": "Andrei Popescu",
"shipping_method": "cargus",
"priority": "high",
"order_date": "2026-06-11T08:42:11.000000Z",
"items": [
{ "id": 9912, "product_id": 812, "quantity": 2, "quantity_ordered": 2, "unit_price": "149.90" }
]
}
}Atașarea facturii la creare
Codează PDF-ul în base64 și trimite-l în invoice_pdf, alături de invoice_reference (numărul facturii) și, opțional, client_cui:
INVOICE_PDF=$(base64 -i factura.pdf)
curl -X POST https://tenant.notsowms.ro/api/v1/orders \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
-H "Content-Type: application/json" \
-d "{
\"customer_name\": \"Andrei Popescu\",
\"shipping_method\": \"cargus\",
\"invoice_reference\": \"FAC-2026-0042\",
\"client_cui\": \"RO12345678\",
\"invoice_pdf\": \"${INVOICE_PDF}\",
\"items\": [ { \"product_id\": 812, \"quantity\": 2, \"unit_price\": 149.90 } ]
}"În răspunsul 201, comanda include invoice_reference și invoice_file_path (ex. order_pdf_invoices/factura-FAC-2026-0042-cui-RO12345678.pdf). Documentul se poate descărca ulterior din interfața WMS sau prin GET /api/v1/orders/{id} (câmpul invoice_file_path).
Actualizare status
PUT /api/v1/orders/{id}/status.
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
status | string ≤ 50 | da | Noul status (vezi lista de statusuri de mai sus). |
notes | text | nu | Notă salvată în istoricul de status. |
Folosește doar una din valorile enumerate mai sus — o valoare necunoscută este respinsă de baza de date (eroare de server), nu printr-un 422 de validare.
Schimbarea se înregistrează în istoricul comenzii. Trecerea la shipped sau cancelled declanșează evenimentele de facturare aferente.
curl -X PUT https://tenant.notsowms.ro/api/v1/orders/4471/status \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
-H "Content-Type: application/json" \
-d '{ "status": "cancelled", "notes": "Anulată la cererea clientului" }'Ștergere
DELETE /api/v1/orders/{id} șterge definitiv comanda împreună cu liniile și istoricul ei de status — nu este o anulare „soft”. Pentru a anula o comandă păstrând-o, folosește în schimb PUT .../status cu status: cancelled.
Ștergerea este permisă doar dacă statusul comenzii este pending (neprocesată încă) sau cancelled; o comandă care a intrat în fluxul de depozit nu poate fi ștearsă și primești 422:
{ "error": "Only pending or cancelled orders can be deleted." }curl -X DELETE https://tenant.notsowms.ro/api/v1/orders/4471 \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b"Răspuns:
{ "message": "Order deleted." }